summaryrefslogtreecommitdiffstats
path: root/servo/components/style/values/computed
diff options
context:
space:
mode:
Diffstat (limited to 'servo/components/style/values/computed')
-rw-r--r--servo/components/style/values/computed/basic_shape.rs188
-rw-r--r--servo/components/style/values/computed/box.rs11
-rw-r--r--servo/components/style/values/computed/font.rs14
-rw-r--r--servo/components/style/values/computed/length.rs23
-rw-r--r--servo/components/style/values/computed/length_percentage.rs20
-rw-r--r--servo/components/style/values/computed/ratio.rs2
6 files changed, 250 insertions, 8 deletions
diff --git a/servo/components/style/values/computed/basic_shape.rs b/servo/components/style/values/computed/basic_shape.rs
index d39110ec1c..21df7baf93 100644
--- a/servo/components/style/values/computed/basic_shape.rs
+++ b/servo/components/style/values/computed/basic_shape.rs
@@ -7,9 +7,12 @@
//!
//! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape
+use crate::values::animated::{Animate, Procedure};
+use crate::values::computed::angle::Angle;
use crate::values::computed::url::ComputedUrl;
use crate::values::computed::{Image, LengthPercentage, NonNegativeLengthPercentage, Position};
use crate::values::generics::basic_shape as generic;
+use crate::values::specified::svg_path::{CoordPair, PathCommand};
/// A computed alias for FillRule.
pub use crate::values::generics::basic_shape::FillRule;
@@ -21,8 +24,13 @@ pub type ClipPath = generic::GenericClipPath<BasicShape, ComputedUrl>;
pub type ShapeOutside = generic::GenericShapeOutside<BasicShape, Image>;
/// A computed basic shape.
-pub type BasicShape =
- generic::GenericBasicShape<Position, LengthPercentage, NonNegativeLengthPercentage, InsetRect>;
+pub type BasicShape = generic::GenericBasicShape<
+ Angle,
+ Position,
+ LengthPercentage,
+ NonNegativeLengthPercentage,
+ InsetRect,
+>;
/// The computed value of `inset()`.
pub type InsetRect = generic::GenericInsetRect<LengthPercentage, NonNegativeLengthPercentage>;
@@ -35,3 +43,179 @@ pub type Ellipse = generic::Ellipse<Position, NonNegativeLengthPercentage>;
/// The computed value of `ShapeRadius`.
pub type ShapeRadius = generic::GenericShapeRadius<NonNegativeLengthPercentage>;
+
+/// The computed value of `shape()`.
+pub type Shape = generic::Shape<Angle, LengthPercentage>;
+
+/// The computed value of `ShapeCommand`.
+pub type ShapeCommand = generic::GenericShapeCommand<Angle, LengthPercentage>;
+
+/// The computed value of `PathOrShapeFunction`.
+pub type PathOrShapeFunction = generic::GenericPathOrShapeFunction<Angle, LengthPercentage>;
+
+/// The computed value of `CoordinatePair`.
+pub type CoordinatePair = generic::CoordinatePair<LengthPercentage>;
+
+/// Animate from `Shape` to `Path`, and vice versa.
+macro_rules! animate_shape {
+ (
+ $from:ident,
+ $to:ident,
+ $procedure:ident,
+ $from_as_shape:tt,
+ $to_as_shape:tt
+ ) => {{
+ // Check fill-rule.
+ if $from.fill != $to.fill {
+ return Err(());
+ }
+
+ // Check the list of commands. (This is a specialized lists::by_computed_value::animate().)
+ let from_cmds = $from.commands();
+ let to_cmds = $to.commands();
+ if from_cmds.len() != to_cmds.len() {
+ return Err(());
+ }
+ let commands = from_cmds
+ .iter()
+ .zip(to_cmds.iter())
+ .map(|(from_cmd, to_cmd)| {
+ $from_as_shape(from_cmd).animate(&$to_as_shape(to_cmd), $procedure)
+ })
+ .collect::<Result<Vec<ShapeCommand>, ()>>()?;
+
+ Ok(Shape {
+ fill: $from.fill,
+ commands: commands.into(),
+ })
+ }};
+}
+
+impl Animate for PathOrShapeFunction {
+ #[inline]
+ fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
+ // Per spec, commands are "the same" if they use the same command keyword, and use the same
+ // <by-to> keyword. For curve and smooth, they also must have the same number of control
+ // points. Therefore, we don't have to do normalization here. (Note that we do
+ // normalization if we animate from path() to path(). See svg_path.rs for more details.)
+ //
+ // https://drafts.csswg.org/css-shapes-2/#interpolating-shape
+ match (self, other) {
+ (Self::Path(ref from), Self::Path(ref to)) => {
+ from.animate(to, procedure).map(Self::Path)
+ },
+ (Self::Shape(ref from), Self::Shape(ref to)) => {
+ from.animate(to, procedure).map(Self::Shape)
+ },
+ (Self::Shape(ref from), Self::Path(ref to)) => {
+ // Animate from shape() to path(). We convert each PathCommand into ShapeCommand,
+ // and return shape().
+ animate_shape!(
+ from,
+ to,
+ procedure,
+ (|shape_cmd| shape_cmd),
+ (|path_cmd| ShapeCommand::from(path_cmd))
+ )
+ .map(Self::Shape)
+ },
+ (Self::Path(ref from), Self::Shape(ref to)) => {
+ // Animate from path() to shape(). We convert each PathCommand into ShapeCommand,
+ // and return shape().
+ animate_shape!(
+ from,
+ to,
+ procedure,
+ (|path_cmd| ShapeCommand::from(path_cmd)),
+ (|shape_cmd| shape_cmd)
+ )
+ .map(Self::Shape)
+ },
+ }
+ }
+}
+
+impl From<&PathCommand> for ShapeCommand {
+ #[inline]
+ fn from(path: &PathCommand) -> Self {
+ use crate::values::computed::CSSPixelLength;
+ match path {
+ &PathCommand::Close => Self::Close,
+ &PathCommand::Move { by_to, ref point } => Self::Move {
+ by_to,
+ point: point.into(),
+ },
+ &PathCommand::Line { by_to, ref point } => Self::Move {
+ by_to,
+ point: point.into(),
+ },
+ &PathCommand::HLine { by_to, x } => Self::HLine {
+ by_to,
+ x: LengthPercentage::new_length(CSSPixelLength::new(x)),
+ },
+ &PathCommand::VLine { by_to, y } => Self::VLine {
+ by_to,
+ y: LengthPercentage::new_length(CSSPixelLength::new(y)),
+ },
+ &PathCommand::CubicCurve {
+ by_to,
+ ref point,
+ ref control1,
+ ref control2,
+ } => Self::CubicCurve {
+ by_to,
+ point: point.into(),
+ control1: control1.into(),
+ control2: control2.into(),
+ },
+ &PathCommand::QuadCurve {
+ by_to,
+ ref point,
+ ref control1,
+ } => Self::QuadCurve {
+ by_to,
+ point: point.into(),
+ control1: control1.into(),
+ },
+ &PathCommand::SmoothCubic {
+ by_to,
+ ref point,
+ ref control2,
+ } => Self::SmoothCubic {
+ by_to,
+ point: point.into(),
+ control2: control2.into(),
+ },
+ &PathCommand::SmoothQuad { by_to, ref point } => Self::SmoothQuad {
+ by_to,
+ point: point.into(),
+ },
+ &PathCommand::Arc {
+ by_to,
+ ref point,
+ ref radii,
+ arc_sweep,
+ arc_size,
+ rotate,
+ } => Self::Arc {
+ by_to,
+ point: point.into(),
+ radii: radii.into(),
+ arc_sweep,
+ arc_size,
+ rotate: Angle::from_degrees(rotate),
+ },
+ }
+ }
+}
+
+impl From<&CoordPair> for CoordinatePair {
+ #[inline]
+ fn from(p: &CoordPair) -> Self {
+ use crate::values::computed::CSSPixelLength;
+ Self::new(
+ LengthPercentage::new_length(CSSPixelLength::new(p.x)),
+ LengthPercentage::new_length(CSSPixelLength::new(p.y)),
+ )
+ }
+}
diff --git a/servo/components/style/values/computed/box.rs b/servo/components/style/values/computed/box.rs
index 62811d9851..0dea1c7ab9 100644
--- a/servo/components/style/values/computed/box.rs
+++ b/servo/components/style/values/computed/box.rs
@@ -383,6 +383,15 @@ impl Zoom {
if self == Self::ONE {
return value;
}
- self.value() * value
+ value * self.value()
+ }
+
+ /// Returns the un-zoomed value.
+ #[inline]
+ pub fn unzoom(self, value: f32) -> f32 {
+ if self == Self::ONE {
+ return value;
+ }
+ value / self.value()
}
}
diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs
index de0a5e372b..e492584f75 100644
--- a/servo/components/style/values/computed/font.rs
+++ b/servo/components/style/values/computed/font.rs
@@ -8,7 +8,7 @@ use crate::parser::{Parse, ParserContext};
use crate::values::animated::ToAnimatedValue;
use crate::values::computed::{
Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, Number, Percentage,
- ToComputedValue,
+ ToComputedValue, Zoom,
};
use crate::values::generics::font::{
FeatureTagValue, FontSettings, TaggedFontValue, VariationValue,
@@ -278,6 +278,16 @@ impl FontSize {
self.used_size.0
}
+ /// Apply zoom to the font-size. This is usually done by ToComputedValue.
+ #[inline]
+ pub fn zoom(&self, zoom: Zoom) -> Self {
+ Self {
+ computed_size: NonNegative(Length::new(zoom.zoom(self.computed_size.0.px()))),
+ used_size: NonNegative(Length::new(zoom.zoom(self.used_size.0.px()))),
+ keyword_info: self.keyword_info,
+ }
+ }
+
#[inline]
/// Get default value of font size.
pub fn medium() -> Self {
@@ -1359,7 +1369,7 @@ impl ToResolvedValue for LineHeight {
context.style.get_font(),
wm,
Some(context.element_info.element),
- ))
+ ).to_resolved_value(context))
}
#[inline]
diff --git a/servo/components/style/values/computed/length.rs b/servo/components/style/values/computed/length.rs
index e75676a76d..881efed126 100644
--- a/servo/components/style/values/computed/length.rs
+++ b/servo/components/style/values/computed/length.rs
@@ -6,12 +6,13 @@
use super::{Context, Number, ToComputedValue};
use crate::values::animated::ToAnimatedValue;
-use crate::values::computed::NonNegativeNumber;
+use crate::values::computed::{NonNegativeNumber, Zoom};
use crate::values::generics::length as generics;
use crate::values::generics::length::{
GenericLengthOrNumber, GenericLengthPercentageOrNormal, GenericMaxSize, GenericSize,
};
use crate::values::generics::NonNegative;
+use crate::values::resolved::{Context as ResolvedContext, ToResolvedValue};
use crate::values::specified::length::{AbsoluteLength, FontBaseSize, LineHeightBase};
use crate::values::{specified, CSSFloat};
use crate::Zero;
@@ -227,12 +228,24 @@ impl Size {
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
- ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct CSSPixelLength(CSSFloat);
+impl ToResolvedValue for CSSPixelLength {
+ type ResolvedValue = Self;
+
+ fn to_resolved_value(self, context: &ResolvedContext) -> Self::ResolvedValue {
+ Self(context.style.effective_zoom.unzoom(self.0))
+ }
+
+ #[inline]
+ fn from_resolved_value(value: Self::ResolvedValue) -> Self {
+ value
+ }
+}
+
impl fmt::Debug for CSSPixelLength {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)?;
@@ -271,6 +284,12 @@ impl CSSPixelLength {
self.0
}
+ /// Zooms a particular length.
+ #[inline]
+ pub fn zoom(self, zoom: Zoom) -> Self {
+ Self::new(zoom.zoom(self.px()))
+ }
+
/// Return the length with app_unit i32 type.
#[inline]
pub fn to_i32_au(self) -> i32 {
diff --git a/servo/components/style/values/computed/length_percentage.rs b/servo/components/style/values/computed/length_percentage.rs
index 0dbd2de76d..c448025dd1 100644
--- a/servo/components/style/values/computed/length_percentage.rs
+++ b/servo/components/style/values/computed/length_percentage.rs
@@ -30,6 +30,7 @@ use crate::values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZer
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
use crate::values::generics::calc::{CalcUnits, PositivePercentageBasis};
use crate::values::generics::{calc, NonNegative};
+use crate::values::resolved::{Context as ResolvedContext, ToResolvedValue};
use crate::values::specified::length::{FontBaseSize, LineHeightBase};
use crate::values::{specified, CSSFloat};
use crate::{Zero, ZeroNoPercent};
@@ -164,6 +165,25 @@ impl MallocSizeOf for LengthPercentage {
}
}
+impl ToResolvedValue for LengthPercentage {
+ type ResolvedValue = Self;
+
+ fn to_resolved_value(self, context: &ResolvedContext) -> Self::ResolvedValue {
+ if context.style.effective_zoom.is_one() {
+ return self;
+ }
+ match self.unpack() {
+ Unpacked::Length(l) => Self::new_length(l.to_resolved_value(context)),
+ Unpacked::Percentage(..) | Unpacked::Calc(..) => self,
+ }
+ }
+
+ #[inline]
+ fn from_resolved_value(value: Self::ResolvedValue) -> Self {
+ value
+ }
+}
+
/// An unpacked `<length-percentage>` that borrows the `calc()` variant.
#[derive(Clone, Debug, PartialEq, ToCss)]
enum Unpacked<'a> {
diff --git a/servo/components/style/values/computed/ratio.rs b/servo/components/style/values/computed/ratio.rs
index ae8997cfc0..6964eec3e4 100644
--- a/servo/components/style/values/computed/ratio.rs
+++ b/servo/components/style/values/computed/ratio.rs
@@ -9,7 +9,7 @@ use crate::values::computed::NonNegativeNumber;
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
use crate::values::generics::ratio::Ratio as GenericRatio;
use crate::{One, Zero};
-use std::cmp::{Ordering, PartialOrd};
+use std::cmp::Ordering;
/// A computed <ratio> value.
pub type Ratio = GenericRatio<NonNegativeNumber>;