mirror of
https://github.com/servo/servo.git
synced 2025-07-31 03:00:29 +01:00
Parse interpolation hints (fixes #15166)
This commit is contained in:
parent
8824a68063
commit
ae82cdab34
6 changed files with 152 additions and 57 deletions
|
@ -58,8 +58,8 @@ use style::properties::longhands::border_image_repeat::computed_value::RepeatKey
|
||||||
use style::properties::style_structs;
|
use style::properties::style_structs;
|
||||||
use style::servo::restyle_damage::REPAINT;
|
use style::servo::restyle_damage::REPAINT;
|
||||||
use style::values::{Either, RGBA, computed};
|
use style::values::{Either, RGBA, computed};
|
||||||
use style::values::computed::{AngleOrCorner, Gradient, GradientKind, LengthOrPercentage};
|
use style::values::computed::{AngleOrCorner, Gradient, GradientItem, GradientKind};
|
||||||
use style::values::computed::{LengthOrPercentageOrAuto, NumberOrPercentage};
|
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, NumberOrPercentage};
|
||||||
use style::values::specified::{HorizontalDirection, VerticalDirection};
|
use style::values::specified::{HorizontalDirection, VerticalDirection};
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
use style_traits::cursor::Cursor;
|
use style_traits::cursor::Cursor;
|
||||||
|
@ -948,9 +948,15 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// Determine the position of each stop per CSS-IMAGES § 3.4.
|
// Determine the position of each stop per CSS-IMAGES § 3.4.
|
||||||
//
|
//
|
||||||
// FIXME(#3908, pcwalton): Make sure later stops can't be behind earlier stops.
|
// FIXME(#3908, pcwalton): Make sure later stops can't be behind earlier stops.
|
||||||
let mut stops = Vec::with_capacity(gradient.stops.len());
|
let stop_items = gradient.items.iter().filter_map(|item| {
|
||||||
|
match *item {
|
||||||
|
GradientItem::ColorStop(ref stop) => Some(stop),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
let mut stops = Vec::with_capacity(stop_items.len());
|
||||||
let mut stop_run = None;
|
let mut stop_run = None;
|
||||||
for (i, stop) in gradient.stops.iter().enumerate() {
|
for (i, stop) in stop_items.iter().enumerate() {
|
||||||
let offset = match stop.position {
|
let offset = match stop.position {
|
||||||
None => {
|
None => {
|
||||||
if stop_run.is_none() {
|
if stop_run.is_none() {
|
||||||
|
@ -960,14 +966,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
} else {
|
} else {
|
||||||
// `unwrap()` here should never fail because this is the beginning of
|
// `unwrap()` here should never fail because this is the beginning of
|
||||||
// a stop run, which is always bounded by a length or percentage.
|
// a stop run, which is always bounded by a length or percentage.
|
||||||
position_to_offset(gradient.stops[i - 1].position.unwrap(), length)
|
position_to_offset(stop_items[i - 1].position.unwrap(), length)
|
||||||
};
|
};
|
||||||
let (end_index, end_offset) =
|
let (end_index, end_offset) =
|
||||||
match gradient.stops[i..]
|
match stop_items[i..]
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_, ref stop)| stop.position.is_some()) {
|
.find(|&(_, ref stop)| stop.position.is_some()) {
|
||||||
None => (gradient.stops.len() - 1, 1.0),
|
None => (stop_items.len() - 1, 1.0),
|
||||||
Some((end_index, end_stop)) => {
|
Some((end_index, end_stop)) => {
|
||||||
// `unwrap()` here should never fail because this is the end of
|
// `unwrap()` here should never fail because this is the end of
|
||||||
// a stop run, which is always bounded by a length or
|
// a stop run, which is always bounded by a length or
|
||||||
|
|
|
@ -16,7 +16,8 @@ use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage};
|
||||||
use gecko_bindings::structs::{nsresult, SheetType};
|
use gecko_bindings::structs::{nsresult, SheetType};
|
||||||
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
|
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
|
||||||
use stylesheets::{Origin, RulesMutateError};
|
use stylesheets::{Origin, RulesMutateError};
|
||||||
use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto};
|
use values::computed::{CalcLengthOrPercentage, Gradient, GradientItem, Image};
|
||||||
|
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
|
|
||||||
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
|
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
|
||||||
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
|
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
|
||||||
|
@ -160,7 +161,7 @@ impl nsStyleImage {
|
||||||
use values::computed::LengthOrPercentageOrKeyword;
|
use values::computed::LengthOrPercentageOrKeyword;
|
||||||
use values::specified::{HorizontalDirection, SizeKeyword, VerticalDirection};
|
use values::specified::{HorizontalDirection, SizeKeyword, VerticalDirection};
|
||||||
|
|
||||||
let stop_count = gradient.stops.len();
|
let stop_count = gradient.items.len();
|
||||||
if stop_count >= ::std::u32::MAX as usize {
|
if stop_count >= ::std::u32::MAX as usize {
|
||||||
warn!("stylo: Prevented overflow due to too many gradient stops");
|
warn!("stylo: Prevented overflow due to too many gradient stops");
|
||||||
return;
|
return;
|
||||||
|
@ -280,12 +281,18 @@ impl nsStyleImage {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, stop) in gradient.stops.iter().enumerate() {
|
for (index, item) in gradient.items.iter().enumerate() {
|
||||||
// NB: stops are guaranteed to be none in the gecko side by
|
// NB: stops are guaranteed to be none in the gecko side by
|
||||||
// default.
|
// default.
|
||||||
let mut coord: nsStyleCoord = nsStyleCoord::null();
|
|
||||||
coord.set(stop.position);
|
let mut gecko_stop = unsafe {
|
||||||
let color = match stop.color {
|
&mut (*gecko_gradient).mStops[index]
|
||||||
|
};
|
||||||
|
let mut coord = nsStyleCoord::null();
|
||||||
|
|
||||||
|
match *item {
|
||||||
|
GradientItem::ColorStop(ref stop) => {
|
||||||
|
gecko_stop.mColor = match stop.color {
|
||||||
CSSColor::CurrentColor => {
|
CSSColor::CurrentColor => {
|
||||||
// TODO(emilio): gecko just stores an nscolor,
|
// TODO(emilio): gecko just stores an nscolor,
|
||||||
// and it doesn't seem to support currentColor
|
// and it doesn't seem to support currentColor
|
||||||
|
@ -298,14 +305,16 @@ impl nsStyleImage {
|
||||||
},
|
},
|
||||||
CSSColor::RGBA(ref rgba) => convert_rgba_to_nscolor(rgba),
|
CSSColor::RGBA(ref rgba) => convert_rgba_to_nscolor(rgba),
|
||||||
};
|
};
|
||||||
|
gecko_stop.mIsInterpolationHint = false;
|
||||||
|
coord.set(stop.position);
|
||||||
|
},
|
||||||
|
GradientItem::InterpolationHint(hint) => {
|
||||||
|
gecko_stop.mIsInterpolationHint = true;
|
||||||
|
coord.set(Some(hint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut stop = unsafe {
|
gecko_stop.mLocation.move_from(coord);
|
||||||
&mut (*gecko_gradient).mStops[index]
|
|
||||||
};
|
|
||||||
|
|
||||||
stop.mColor = color;
|
|
||||||
stop.mIsInterpolationHint = false;
|
|
||||||
stop.mLocation.move_from(coord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -120,7 +120,7 @@ impl ToCss for Image {
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct Gradient {
|
pub struct Gradient {
|
||||||
/// The color stops.
|
/// The color stops.
|
||||||
pub stops: Vec<ColorStop>,
|
pub items: Vec<GradientItem>,
|
||||||
/// True if this is a repeating gradient.
|
/// True if this is a repeating gradient.
|
||||||
pub repeating: bool,
|
pub repeating: bool,
|
||||||
/// Gradient kind can be linear or radial.
|
/// Gradient kind can be linear or radial.
|
||||||
|
@ -149,9 +149,9 @@ impl ToCss for Gradient {
|
||||||
try!(position.to_css(dest));
|
try!(position.to_css(dest));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for stop in &self.stops {
|
for item in &self.items {
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(stop.to_css(dest));
|
try!(item.to_css(dest));
|
||||||
}
|
}
|
||||||
try!(dest.write_str(")"));
|
try!(dest.write_str(")"));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -169,8 +169,8 @@ impl fmt::Debug for Gradient {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for stop in &self.stops {
|
for item in &self.items {
|
||||||
let _ = write!(f, ", {:?}", stop);
|
let _ = write!(f, ", {:?}", item);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -182,13 +182,13 @@ impl ToComputedValue for specified::Gradient {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &Context) -> Gradient {
|
fn to_computed_value(&self, context: &Context) -> Gradient {
|
||||||
let specified::Gradient {
|
let specified::Gradient {
|
||||||
ref stops,
|
ref items,
|
||||||
repeating,
|
repeating,
|
||||||
ref gradient_kind,
|
ref gradient_kind,
|
||||||
compat_mode,
|
compat_mode,
|
||||||
} = *self;
|
} = *self;
|
||||||
Gradient {
|
Gradient {
|
||||||
stops: stops.iter().map(|s| s.to_computed_value(context)).collect(),
|
items: items.iter().map(|s| s.to_computed_value(context)).collect(),
|
||||||
repeating: repeating,
|
repeating: repeating,
|
||||||
gradient_kind: gradient_kind.to_computed_value(context),
|
gradient_kind: gradient_kind.to_computed_value(context),
|
||||||
compat_mode: compat_mode,
|
compat_mode: compat_mode,
|
||||||
|
@ -198,13 +198,13 @@ impl ToComputedValue for specified::Gradient {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &Gradient) -> Self {
|
fn from_computed_value(computed: &Gradient) -> Self {
|
||||||
let Gradient {
|
let Gradient {
|
||||||
ref stops,
|
ref items,
|
||||||
repeating,
|
repeating,
|
||||||
ref gradient_kind,
|
ref gradient_kind,
|
||||||
compat_mode,
|
compat_mode,
|
||||||
} = *computed;
|
} = *computed;
|
||||||
specified::Gradient {
|
specified::Gradient {
|
||||||
stops: stops.iter().map(ToComputedValue::from_computed_value).collect(),
|
items: items.iter().map(ToComputedValue::from_computed_value).collect(),
|
||||||
repeating: repeating,
|
repeating: repeating,
|
||||||
gradient_kind: ToComputedValue::from_computed_value(gradient_kind),
|
gradient_kind: ToComputedValue::from_computed_value(gradient_kind),
|
||||||
compat_mode: compat_mode,
|
compat_mode: compat_mode,
|
||||||
|
@ -251,6 +251,53 @@ impl ToComputedValue for specified::GradientKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Specified values for color stops and interpolation hints.
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub enum GradientItem {
|
||||||
|
/// A color stop.
|
||||||
|
ColorStop(ColorStop),
|
||||||
|
/// An interpolation hint.
|
||||||
|
InterpolationHint(LengthOrPercentage),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for GradientItem {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
match *self {
|
||||||
|
GradientItem::ColorStop(stop) => stop.to_css(dest),
|
||||||
|
GradientItem::InterpolationHint(hint) => hint.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for specified::GradientItem {
|
||||||
|
type ComputedValue = GradientItem;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> GradientItem {
|
||||||
|
match *self {
|
||||||
|
specified::GradientItem::ColorStop(ref stop) => {
|
||||||
|
GradientItem::ColorStop(stop.to_computed_value(context))
|
||||||
|
},
|
||||||
|
specified::GradientItem::InterpolationHint(ref hint) => {
|
||||||
|
GradientItem::InterpolationHint(hint.to_computed_value(context))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &GradientItem) -> Self {
|
||||||
|
match *computed {
|
||||||
|
GradientItem::ColorStop(ref stop) => {
|
||||||
|
specified::GradientItem::ColorStop(ToComputedValue::from_computed_value(stop))
|
||||||
|
},
|
||||||
|
GradientItem::InterpolationHint(ref hint) => {
|
||||||
|
specified::GradientItem::InterpolationHint(ToComputedValue::from_computed_value(hint))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Computed values for one color stop in a linear gradient.
|
/// Computed values for one color stop in a linear gradient.
|
||||||
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
||||||
#[derive(Clone, PartialEq, Copy)]
|
#[derive(Clone, PartialEq, Copy)]
|
||||||
|
|
|
@ -17,8 +17,8 @@ use super::specified::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as G
|
||||||
|
|
||||||
pub use app_units::Au;
|
pub use app_units::Au;
|
||||||
pub use cssparser::Color as CSSColor;
|
pub use cssparser::Color as CSSColor;
|
||||||
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image, ImageRect};
|
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientItem};
|
||||||
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use self::image::{GradientKind, Image, ImageRect, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
pub use super::{Auto, Either, None_};
|
pub use super::{Auto, Either, None_};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
|
pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
|
||||||
|
|
|
@ -92,8 +92,8 @@ impl Image {
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct Gradient {
|
pub struct Gradient {
|
||||||
/// The color stops.
|
/// The color stops and interpolation hints.
|
||||||
pub stops: Vec<ColorStop>,
|
pub items: Vec<GradientItem>,
|
||||||
/// True if this is a repeating gradient.
|
/// True if this is a repeating gradient.
|
||||||
pub repeating: bool,
|
pub repeating: bool,
|
||||||
/// Gradients can be linear or radial.
|
/// Gradients can be linear or radial.
|
||||||
|
@ -132,13 +132,13 @@ impl ToCss for Gradient {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for stop in &self.stops {
|
for item in &self.items {
|
||||||
if !skipcomma {
|
if !skipcomma {
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
} else {
|
} else {
|
||||||
skipcomma = false;
|
skipcomma = false;
|
||||||
}
|
}
|
||||||
try!(stop.to_css(dest));
|
try!(item.to_css(dest));
|
||||||
}
|
}
|
||||||
dest.write_str(")")
|
dest.write_str(")")
|
||||||
}
|
}
|
||||||
|
@ -148,18 +148,18 @@ impl Gradient {
|
||||||
/// Parses a gradient from the given arguments.
|
/// Parses a gradient from the given arguments.
|
||||||
pub fn parse_function(context: &ParserContext, input: &mut Parser) -> Result<Gradient, ()> {
|
pub fn parse_function(context: &ParserContext, input: &mut Parser) -> Result<Gradient, ()> {
|
||||||
fn parse<F>(context: &ParserContext, input: &mut Parser, parse_kind: F)
|
fn parse<F>(context: &ParserContext, input: &mut Parser, parse_kind: F)
|
||||||
-> Result<(GradientKind, Vec<ColorStop>), ()>
|
-> Result<(GradientKind, Vec<GradientItem>), ()>
|
||||||
where F: FnOnce(&ParserContext, &mut Parser) -> Result<GradientKind, ()>
|
where F: FnOnce(&ParserContext, &mut Parser) -> Result<GradientKind, ()>
|
||||||
{
|
{
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let kind = try!(parse_kind(context, input));
|
let kind = try!(parse_kind(context, input));
|
||||||
let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i)));
|
let items = try!(Gradient::parse_items(context, input));
|
||||||
Ok((kind, stops))
|
Ok((kind, items))
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let mut repeating = false;
|
let mut repeating = false;
|
||||||
let mut compat_mode = CompatMode::Modern;
|
let mut compat_mode = CompatMode::Modern;
|
||||||
let (gradient_kind, stops) = match_ignore_ascii_case! { &try!(input.expect_function()),
|
let (gradient_kind, items) = match_ignore_ascii_case! { &try!(input.expect_function()),
|
||||||
"linear-gradient" => {
|
"linear-gradient" => {
|
||||||
try!(parse(context, input, GradientKind::parse_modern_linear))
|
try!(parse(context, input, GradientKind::parse_modern_linear))
|
||||||
},
|
},
|
||||||
|
@ -195,18 +195,31 @@ impl Gradient {
|
||||||
_ => { return Err(()); }
|
_ => { return Err(()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
|
||||||
if stops.len() < 2 {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Gradient {
|
Ok(Gradient {
|
||||||
stops: stops,
|
items: items,
|
||||||
repeating: repeating,
|
repeating: repeating,
|
||||||
gradient_kind: gradient_kind,
|
gradient_kind: gradient_kind,
|
||||||
compat_mode: compat_mode,
|
compat_mode: compat_mode,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_items(context: &ParserContext, input: &mut Parser) -> Result<Vec<GradientItem>, ()> {
|
||||||
|
let mut seen_stop = false;
|
||||||
|
let items = try!(input.parse_comma_separated(|input| {
|
||||||
|
if seen_stop {
|
||||||
|
if let Ok(hint) = input.try(|i| LengthOrPercentage::parse(context, i)) {
|
||||||
|
seen_stop = false;
|
||||||
|
return Ok(GradientItem::InterpolationHint(hint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seen_stop = true;
|
||||||
|
ColorStop::parse(context, input).map(GradientItem::ColorStop)
|
||||||
|
}));
|
||||||
|
if !seen_stop || items.len() < 2 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
Ok(items)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specified values for CSS linear or radial gradients.
|
/// Specified values for CSS linear or radial gradients.
|
||||||
|
@ -489,7 +502,27 @@ impl AngleOrCorner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specified values for one color stop in a linear gradient.
|
/// Specified values for color stops and interpolation hints.
|
||||||
|
/// https://drafts.csswg.org/css-images-4/#color-stop-syntax
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub enum GradientItem {
|
||||||
|
/// A color stop.
|
||||||
|
ColorStop(ColorStop),
|
||||||
|
/// An interpolation hint.
|
||||||
|
InterpolationHint(LengthOrPercentage),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for GradientItem {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
match *self {
|
||||||
|
GradientItem::ColorStop(ref stop) => stop.to_css(dest),
|
||||||
|
GradientItem::InterpolationHint(ref hint) => hint.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specified values for one color stop in a gradient.
|
||||||
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
|
|
@ -29,8 +29,8 @@ pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, Justify
|
||||||
pub use self::color::Color;
|
pub use self::color::Color;
|
||||||
pub use self::grid::{GridLine, TrackKeyword};
|
pub use self::grid::{GridLine, TrackKeyword};
|
||||||
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
||||||
pub use self::image::{GradientKind, HorizontalDirection, Image, ImageRect, LengthOrKeyword};
|
pub use self::image::{GradientItem, GradientKind, HorizontalDirection, Image, ImageRect};
|
||||||
pub use self::image::{LengthOrPercentageOrKeyword, SizeKeyword, VerticalDirection};
|
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword, SizeKeyword, VerticalDirection};
|
||||||
pub use self::length::AbsoluteLength;
|
pub use self::length::AbsoluteLength;
|
||||||
pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage};
|
pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage};
|
||||||
pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue