mirror of
https://github.com/servo/servo.git
synced 2025-08-09 23:45:35 +01:00
Auto merge of #17071 - servo:derive-all-the-things, r=emilio
Reuse Rect<T> some more <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17071) <!-- Reviewable:end -->
This commit is contained in:
commit
433d68955b
24 changed files with 324 additions and 355 deletions
|
@ -5,11 +5,10 @@
|
|||
//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape)
|
||||
//! types that are generic over their `ToCss` implementations.
|
||||
|
||||
use euclid::size::Size2D;
|
||||
use std::fmt;
|
||||
use style_traits::{HasViewportPercentage, ToCss};
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
use values::generics::BorderRadiusSize;
|
||||
use values::generics::border::BorderRadius;
|
||||
use values::generics::position::Position;
|
||||
use values::generics::rect::Rect;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
@ -71,22 +70,6 @@ pub struct InsetRect<LengthOrPercentage> {
|
|||
pub round: Option<BorderRadius<LengthOrPercentage>>,
|
||||
}
|
||||
|
||||
/// A generic type used for `border-radius`, `outline-radius` and `inset()` values.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-backgrounds-3/#border-radius
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, PartialEq, ToComputedValue)]
|
||||
pub struct BorderRadius<LengthOrPercentage> {
|
||||
/// The top left radius.
|
||||
pub top_left: BorderRadiusSize<LengthOrPercentage>,
|
||||
/// The top right radius.
|
||||
pub top_right: BorderRadiusSize<LengthOrPercentage>,
|
||||
/// The bottom right radius.
|
||||
pub bottom_right: BorderRadiusSize<LengthOrPercentage>,
|
||||
/// The bottom left radius.
|
||||
pub bottom_left: BorderRadiusSize<LengthOrPercentage>,
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-shapes/#funcdef-circle
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -201,33 +184,6 @@ impl<L> ToCss for InsetRect<L>
|
|||
}
|
||||
}
|
||||
|
||||
impl<L: ToCss + PartialEq> ToCss for BorderRadius<L> {
|
||||
#[inline]
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
serialize_radius_values(dest, &self.top_left.0, &self.top_right.0,
|
||||
&self.bottom_right.0, &self.bottom_left.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization helper for types of longhands like `border-radius` and `outline-radius`
|
||||
pub fn serialize_radius_values<L, W>(dest: &mut W, top_left: &Size2D<L>,
|
||||
top_right: &Size2D<L>, bottom_right: &Size2D<L>,
|
||||
bottom_left: &Size2D<L>) -> fmt::Result
|
||||
where L: ToCss + PartialEq, W: fmt::Write
|
||||
{
|
||||
Rect::new(&top_left.width, &top_right.width, &bottom_right.width, &bottom_left.width).to_css(dest)?;
|
||||
if
|
||||
top_left.width != top_left.height ||
|
||||
top_right.width != top_right.height ||
|
||||
bottom_right.width != bottom_right.height ||
|
||||
bottom_left.width != bottom_left.height
|
||||
{
|
||||
dest.write_str(" / ")?;
|
||||
Rect::new(&top_left.height, &top_right.height, &bottom_right.height, &bottom_left.height).to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<L> Default for ShapeRadius<L> {
|
||||
#[inline]
|
||||
fn default() -> Self { ShapeRadius::ClosestSide }
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
//! Generic types for CSS values related to borders.
|
||||
|
||||
use euclid::Size2D;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::generics::rect::Rect;
|
||||
|
@ -30,6 +31,27 @@ pub struct BorderImageSlice<NumberOrPercentage> {
|
|||
pub fill: bool,
|
||||
}
|
||||
|
||||
/// A generic value for `border-radius`, `outline-radius` and `inset()`.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-backgrounds-3/#border-radius
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
pub struct BorderRadius<LengthOrPercentage> {
|
||||
/// The top left radius.
|
||||
pub top_left: BorderCornerRadius<LengthOrPercentage>,
|
||||
/// The top right radius.
|
||||
pub top_right: BorderCornerRadius<LengthOrPercentage>,
|
||||
/// The bottom right radius.
|
||||
pub bottom_right: BorderCornerRadius<LengthOrPercentage>,
|
||||
/// The bottom left radius.
|
||||
pub bottom_left: BorderCornerRadius<LengthOrPercentage>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
/// A generic value for `border-*-radius` longhand properties.
|
||||
pub struct BorderCornerRadius<L>(pub Size2D<L>);
|
||||
|
||||
impl<L, N> ToCss for BorderImageWidthSide<L, N>
|
||||
where L: ToCss, N: ToCss,
|
||||
{
|
||||
|
@ -69,3 +91,81 @@ impl<N> ToCss for BorderImageSlice<N>
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> BorderRadius<L> {
|
||||
/// Returns a new `BorderRadius<L>`.
|
||||
#[inline]
|
||||
pub fn new(tl: BorderCornerRadius<L>,
|
||||
tr: BorderCornerRadius<L>,
|
||||
br: BorderCornerRadius<L>,
|
||||
bl: BorderCornerRadius<L>)
|
||||
-> Self {
|
||||
BorderRadius {
|
||||
top_left: tl,
|
||||
top_right: tr,
|
||||
bottom_right: br,
|
||||
bottom_left: bl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> BorderRadius<L>
|
||||
where L: PartialEq + ToCss
|
||||
{
|
||||
/// Serialises two given rects following the syntax of the `border-radius``
|
||||
/// property.
|
||||
pub fn serialize_rects<W>(widths: Rect<&L>, heights: Rect<&L>, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
widths.to_css(dest)?;
|
||||
if widths.0 != heights.0 || widths.1 != heights.1 || widths.2 != heights.2 || widths.3 != heights.3 {
|
||||
dest.write_str(" / ")?;
|
||||
heights.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> ToCss for BorderRadius<L>
|
||||
where L: PartialEq + ToCss
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
let BorderRadius {
|
||||
top_left: ref tl,
|
||||
top_right: ref tr,
|
||||
bottom_right: ref br,
|
||||
bottom_left: ref bl,
|
||||
} = *self;
|
||||
|
||||
let widths = Rect::new(&tl.0.width, &tr.0.width, &br.0.width, &bl.0.width);
|
||||
let heights = Rect::new(&tl.0.height, &tr.0.height, &br.0.height, &bl.0.height);
|
||||
|
||||
Self::serialize_rects(widths, heights, dest)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> BorderCornerRadius<L> {
|
||||
#[inline]
|
||||
/// Create a new `BorderCornerRadius` for an area of given width and height.
|
||||
pub fn new(width: L, height: L) -> BorderCornerRadius<L> {
|
||||
BorderCornerRadius(Size2D::new(width, height))
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Clone> From<L> for BorderCornerRadius<L> {
|
||||
fn from(radius: L) -> Self {
|
||||
Self::new(radius.clone(), radius)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> ToCss for BorderCornerRadius<L>
|
||||
where L: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write
|
||||
{
|
||||
self.0.width.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
self.0.height.to_css(dest)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,11 @@
|
|||
|
||||
use counter_style::{Symbols, parse_counter_style_name};
|
||||
use cssparser::Parser;
|
||||
use euclid::size::Size2D;
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::fmt;
|
||||
use style_traits::{HasViewportPercentage, OneOrMoreCommaSeparated, ToCss};
|
||||
use style_traits::{OneOrMoreCommaSeparated, ToCss};
|
||||
use super::CustomIdent;
|
||||
|
||||
pub use self::basic_shape::serialize_radius_values;
|
||||
|
||||
pub mod background;
|
||||
pub mod basic_shape;
|
||||
pub mod border;
|
||||
|
@ -23,47 +20,6 @@ pub mod image;
|
|||
pub mod position;
|
||||
pub mod rect;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, ToComputedValue)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
/// A type for representing CSS `width` and `height` values.
|
||||
pub struct BorderRadiusSize<L>(pub Size2D<L>);
|
||||
|
||||
impl<L> HasViewportPercentage for BorderRadiusSize<L> {
|
||||
#[inline]
|
||||
fn has_viewport_percentage(&self) -> bool { false }
|
||||
}
|
||||
|
||||
impl<L: Clone> From<L> for BorderRadiusSize<L> {
|
||||
fn from(other: L) -> Self {
|
||||
Self::new(other.clone(), other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> BorderRadiusSize<L> {
|
||||
#[inline]
|
||||
/// Create a new `BorderRadiusSize` for an area of given width and height.
|
||||
pub fn new(width: L, height: L) -> BorderRadiusSize<L> {
|
||||
BorderRadiusSize(Size2D::new(width, height))
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Clone> BorderRadiusSize<L> {
|
||||
#[inline]
|
||||
/// Create a new `BorderRadiusSize` for a circle of given radius.
|
||||
pub fn circle(radius: L) -> BorderRadiusSize<L> {
|
||||
BorderRadiusSize(Size2D::new(radius.clone(), radius))
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: ToCss> ToCss for BorderRadiusSize<L> {
|
||||
#[inline]
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
self.0.width.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
self.0.height.to_css(dest)
|
||||
}
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
||||
define_css_keyword_enum! { SymbolsType:
|
||||
"cyclic" => Cyclic,
|
||||
|
|
|
@ -9,29 +9,16 @@ use parser::{Parse, ParserContext};
|
|||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
/// A CSS value made of four sides: top, right, bottom, and left.
|
||||
/// A CSS value made of four components, where its `ToCss` impl will try to
|
||||
/// serialize as few components as possible, like for example in `border-width`.
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct Rect<T> {
|
||||
/// Top
|
||||
pub top: T,
|
||||
/// Right.
|
||||
pub right: T,
|
||||
/// Bottom.
|
||||
pub bottom: T,
|
||||
/// Left.
|
||||
pub left: T,
|
||||
}
|
||||
pub struct Rect<T>(pub T, pub T, pub T, pub T);
|
||||
|
||||
impl<T> Rect<T> {
|
||||
/// Returns a new `Rect<T>` value.
|
||||
pub fn new(top: T, right: T, bottom: T, left: T) -> Self {
|
||||
Rect {
|
||||
top: top,
|
||||
right: right,
|
||||
bottom: bottom,
|
||||
left: left,
|
||||
}
|
||||
pub fn new(first: T, second: T, third: T, fourth: T) -> Self {
|
||||
Rect(first, second, third, fourth)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,21 +33,21 @@ impl<T> Rect<T>
|
|||
-> Result<Self, ()>
|
||||
where Parse: Fn(&ParserContext, &mut Parser) -> Result<T, ()>
|
||||
{
|
||||
let top = parse(context, input)?;
|
||||
let right = if let Ok(right) = input.try(|i| parse(context, i)) { right } else {
|
||||
// <top>
|
||||
return Ok(Self::new(top.clone(), top.clone(), top.clone(), top));
|
||||
let first = parse(context, input)?;
|
||||
let second = if let Ok(second) = input.try(|i| parse(context, i)) { second } else {
|
||||
// <first>
|
||||
return Ok(Self::new(first.clone(), first.clone(), first.clone(), first));
|
||||
};
|
||||
let bottom = if let Ok(bottom) = input.try(|i| parse(context, i)) { bottom } else {
|
||||
// <top> <right>
|
||||
return Ok(Self::new(top.clone(), right.clone(), top, right));
|
||||
let third = if let Ok(third) = input.try(|i| parse(context, i)) { third } else {
|
||||
// <first> <second>
|
||||
return Ok(Self::new(first.clone(), second.clone(), first, second));
|
||||
};
|
||||
let left = if let Ok(left) = input.try(|i| parse(context, i)) { left } else {
|
||||
// <top> <right> <bottom>
|
||||
return Ok(Self::new(top, right.clone(), bottom, right));
|
||||
let fourth = if let Ok(fourth) = input.try(|i| parse(context, i)) { fourth } else {
|
||||
// <first> <second> <third>
|
||||
return Ok(Self::new(first, second.clone(), third, second));
|
||||
};
|
||||
// <top> <right> <bottom> <left>
|
||||
Ok(Self::new(top, right, bottom, left))
|
||||
// <first> <second> <third> <fourth>
|
||||
Ok(Self::new(first, second, third, fourth))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,23 +75,23 @@ impl<T> ToCss for Rect<T>
|
|||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
self.top.to_css(dest)?;
|
||||
let same_vertical = self.top == self.bottom;
|
||||
let same_horizontal = self.right == self.left;
|
||||
if same_vertical && same_horizontal && self.top == self.right {
|
||||
self.0.to_css(dest)?;
|
||||
let same_vertical = self.0 == self.2;
|
||||
let same_horizontal = self.1 == self.3;
|
||||
if same_vertical && same_horizontal && self.0 == self.1 {
|
||||
return Ok(());
|
||||
}
|
||||
dest.write_str(" ")?;
|
||||
self.right.to_css(dest)?;
|
||||
self.1.to_css(dest)?;
|
||||
if same_vertical && same_horizontal {
|
||||
return Ok(());
|
||||
}
|
||||
dest.write_str(" ")?;
|
||||
self.bottom.to_css(dest)?;
|
||||
self.2.to_css(dest)?;
|
||||
if same_horizontal {
|
||||
return Ok(());
|
||||
}
|
||||
dest.write_str(" ")?;
|
||||
self.left.to_css(dest)
|
||||
self.3.to_css(dest)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue