Bug 1527542 - Use rust types for background-size. r=jwatt

Hopefully straight-forward.

Differential Revision: https://phabricator.services.mozilla.com/D19625
This commit is contained in:
Emilio Cobos Álvarez 2019-02-13 03:59:09 +01:00
Родитель 95454d416b
Коммит 9db2ce6d9b
12 изменённых файлов: 73 добавлений и 258 удалений

Просмотреть файл

@ -2821,29 +2821,30 @@ nsRect nsCSSRendering::ComputeImageLayerPositioningArea(
// It can be found by calling nsImageRenderer::ComputeIntrinsicSize. // It can be found by calling nsImageRenderer::ComputeIntrinsicSize.
static nsSize ComputeDrawnSizeForBackground( static nsSize ComputeDrawnSizeForBackground(
const CSSSizeOrRatio& aIntrinsicSize, const nsSize& aBgPositioningArea, const CSSSizeOrRatio& aIntrinsicSize, const nsSize& aBgPositioningArea,
const nsStyleImageLayers::Size& aLayerSize, StyleImageLayerRepeat aXRepeat, const StyleBackgroundSize& aLayerSize, StyleImageLayerRepeat aXRepeat,
StyleImageLayerRepeat aYRepeat) { StyleImageLayerRepeat aYRepeat) {
nsSize imageSize; nsSize imageSize;
// Size is dictated by cover or contain rules. // Size is dictated by cover or contain rules.
if (aLayerSize.mWidthType == nsStyleImageLayers::Size::eContain || if (aLayerSize.IsContain() || aLayerSize.IsCover()) {
aLayerSize.mWidthType == nsStyleImageLayers::Size::eCover) { nsImageRenderer::FitType fitType = aLayerSize.IsCover()
nsImageRenderer::FitType fitType = ? nsImageRenderer::COVER
aLayerSize.mWidthType == nsStyleImageLayers::Size::eCover : nsImageRenderer::CONTAIN;
? nsImageRenderer::COVER
: nsImageRenderer::CONTAIN;
imageSize = nsImageRenderer::ComputeConstrainedSize( imageSize = nsImageRenderer::ComputeConstrainedSize(
aBgPositioningArea, aIntrinsicSize.mRatio, fitType); aBgPositioningArea, aIntrinsicSize.mRatio, fitType);
} else { } else {
MOZ_ASSERT(aLayerSize.IsExplicitSize());
const auto& width = aLayerSize.explicit_size.width;
const auto& height = aLayerSize.explicit_size.height;
// No cover/contain constraint, use default algorithm. // No cover/contain constraint, use default algorithm.
CSSSizeOrRatio specifiedSize; CSSSizeOrRatio specifiedSize;
if (aLayerSize.mWidthType == nsStyleImageLayers::Size::eLengthPercentage) { if (width.IsLengthPercentage()) {
specifiedSize.SetWidth( specifiedSize.SetWidth(
aLayerSize.ResolveWidthLengthPercentage(aBgPositioningArea)); width.AsLengthPercentage().Resolve(aBgPositioningArea.width));
} }
if (aLayerSize.mHeightType == nsStyleImageLayers::Size::eLengthPercentage) { if (height.IsLengthPercentage()) {
specifiedSize.SetHeight( specifiedSize.SetHeight(
aLayerSize.ResolveHeightLengthPercentage(aBgPositioningArea)); height.AsLengthPercentage().Resolve(aBgPositioningArea.height));
} }
imageSize = nsImageRenderer::ComputeConcreteSize( imageSize = nsImageRenderer::ComputeConcreteSize(
@ -2869,9 +2870,8 @@ static nsSize ComputeDrawnSizeForBackground(
if (imageSize.width && aXRepeat == StyleImageLayerRepeat::Round) { if (imageSize.width && aXRepeat == StyleImageLayerRepeat::Round) {
imageSize.width = nsCSSRendering::ComputeRoundedSize( imageSize.width = nsCSSRendering::ComputeRoundedSize(
imageSize.width, aBgPositioningArea.width); imageSize.width, aBgPositioningArea.width);
if (!isRepeatRoundInBothDimensions && if (!isRepeatRoundInBothDimensions && aLayerSize.IsExplicitSize() &&
aLayerSize.mHeightType == aLayerSize.explicit_size.height.IsAuto()) {
nsStyleImageLayers::Size::DimensionType::eAuto) {
// Restore intrinsic rato // Restore intrinsic rato
if (aIntrinsicSize.mRatio.width) { if (aIntrinsicSize.mRatio.width) {
float scale = float scale =
@ -2887,9 +2887,8 @@ static nsSize ComputeDrawnSizeForBackground(
if (imageSize.height && aYRepeat == StyleImageLayerRepeat::Round) { if (imageSize.height && aYRepeat == StyleImageLayerRepeat::Round) {
imageSize.height = nsCSSRendering::ComputeRoundedSize( imageSize.height = nsCSSRendering::ComputeRoundedSize(
imageSize.height, aBgPositioningArea.height); imageSize.height, aBgPositioningArea.height);
if (!isRepeatRoundInBothDimensions && if (!isRepeatRoundInBothDimensions && aLayerSize.IsExplicitSize() &&
aLayerSize.mWidthType == aLayerSize.explicit_size.width.IsAuto()) {
nsStyleImageLayers::Size::DimensionType::eAuto) {
// Restore intrinsic rato // Restore intrinsic rato
if (aIntrinsicSize.mRatio.height) { if (aIntrinsicSize.mRatio.height) {
float scale = float scale =

Просмотреть файл

@ -3835,9 +3835,7 @@ bool nsDisplayBackgroundImage::CanOptimizeToImageLayer(
// because there isn't going to be any spriting/atlasing going on. // because there isn't going to be any spriting/atlasing going on.
const nsStyleImageLayers::Layer& layer = const nsStyleImageLayers::Layer& layer =
mBackgroundStyle->StyleBackground()->mImage.mLayers[mLayer]; mBackgroundStyle->StyleBackground()->mImage.mLayers[mLayer];
bool allowPartialImages = bool allowPartialImages = layer.mSize.IsContain() || layer.mSize.IsCover();
(layer.mSize.mWidthType == nsStyleImageLayers::Size::eContain ||
layer.mSize.mWidthType == nsStyleImageLayers::Size::eCover);
if (!allowPartialImages && !mFillRect.Contains(mDestRect)) { if (!allowPartialImages && !mFillRect.Contains(mDestRect)) {
return false; return false;
} }

Просмотреть файл

@ -424,6 +424,8 @@ cbindgen-types = [
{ gecko = "StyleMaxSize", servo = "values::computed::MaxSize" }, { gecko = "StyleMaxSize", servo = "values::computed::MaxSize" },
{ gecko = "StyleFlexBasis", servo = "values::computed::FlexBasis" }, { gecko = "StyleFlexBasis", servo = "values::computed::FlexBasis" },
{ gecko = "StylePosition", servo = "values::computed::Position" }, { gecko = "StylePosition", servo = "values::computed::Position" },
{ gecko = "StyleBackgroundSize", servo = "values::computed::BackgroundSize" },
{ gecko = "StyleGenericBackgroundSize", servo = "values::generics::background::BackgroundSize" },
] ]
mapped-generic-types = [ mapped-generic-types = [

Просмотреть файл

@ -224,6 +224,12 @@ inline StyleExtremumLength StyleMaxSize::AsExtremumLength() const {
return extremum_length._0; return extremum_length._0;
} }
template <>
inline bool StyleBackgroundSize::IsInitialValue() const {
return IsExplicitSize() && explicit_size.width.IsAuto() &&
explicit_size.height.IsAuto();
}
template <typename T> template <typename T>
const T& StyleRect<T>::Get(mozilla::Side aSide) const { const T& StyleRect<T>::Get(mozilla::Side aSide) const {
static_assert(sizeof(StyleRect<T>) == sizeof(T) * 4, ""); static_assert(sizeof(StyleRect<T>) == sizeof(T) * 4, "");

Просмотреть файл

@ -2603,33 +2603,30 @@ bool nsStyleImageLayers::IsInitialPositionForLayerType(Position aPosition,
return aPosition == Position::FromPercentage(0.); return aPosition == Position::FromPercentage(0.);
} }
bool nsStyleImageLayers::Size::DependsOnPositioningAreaSize( static bool SizeDependsOnPositioningAreaSize(const StyleBackgroundSize& aSize,
const nsStyleImage& aImage) const { const nsStyleImage& aImage) {
MOZ_ASSERT(aImage.GetType() != eStyleImageType_Null, MOZ_ASSERT(aImage.GetType() != eStyleImageType_Null,
"caller should have handled this"); "caller should have handled this");
// If either dimension contains a non-zero percentage, rendering for that // Contain and cover straightforwardly depend on frame size.
// dimension straightforwardly depends on frame size. if (aSize.IsCover() || aSize.IsContain()) {
if ((mWidthType == eLengthPercentage && mWidth.mPercent != 0.0f) ||
(mHeightType == eLengthPercentage && mHeight.mPercent != 0.0f)) {
return true; return true;
} }
// So too for contain and cover. MOZ_ASSERT(aSize.IsExplicitSize());
if (mWidthType == eContain || mWidthType == eCover) { auto& size = aSize.explicit_size;
// If either dimension contains a non-zero percentage, rendering for that
// dimension straightforwardly depends on frame size.
if (size.width.HasPercent() || size.height.HasPercent()) {
return true; return true;
} }
// If both dimensions are fixed lengths, there's no dependency. // If both dimensions are fixed lengths, there's no dependency.
if (mWidthType == eLengthPercentage && mHeightType == eLengthPercentage) { if (!size.width.IsAuto() && !size.height.IsAuto()) {
return false; return false;
} }
MOZ_ASSERT((mWidthType == eLengthPercentage && mHeightType == eAuto) ||
(mWidthType == eAuto && mHeightType == eLengthPercentage) ||
(mWidthType == eAuto && mHeightType == eAuto),
"logic error");
nsStyleImageType type = aImage.GetType(); nsStyleImageType type = aImage.GetType();
// Gradient rendering depends on frame size when auto is involved because // Gradient rendering depends on frame size when auto is involved because
@ -2667,13 +2664,13 @@ bool nsStyleImageLayers::Size::DependsOnPositioningAreaSize(
// If the image has an intrinsic ratio, rendering will depend on frame // If the image has an intrinsic ratio, rendering will depend on frame
// size when background-size is all auto. // size when background-size is all auto.
if (imageRatio != nsSize(0, 0)) { if (imageRatio != nsSize(0, 0)) {
return mWidthType == mHeightType; return size.width.IsAuto() == size.height.IsAuto();
} }
// Otherwise, rendering depends on frame size when the image dimensions // Otherwise, rendering depends on frame size when the image dimensions
// and background-size don't complement each other. // and background-size don't complement each other.
return !(hasWidth && mHeightType == eLengthPercentage) && return !(hasWidth && size.width.IsLengthPercentage()) &&
!(hasHeight && mWidthType == eLengthPercentage); !(hasHeight && size.height.IsLengthPercentage());
} }
} else { } else {
MOZ_ASSERT_UNREACHABLE("missed an enum value"); MOZ_ASSERT_UNREACHABLE("missed an enum value");
@ -2683,31 +2680,15 @@ bool nsStyleImageLayers::Size::DependsOnPositioningAreaSize(
return false; return false;
} }
void nsStyleImageLayers::Size::SetInitialValues() {
mWidthType = mHeightType = eAuto;
}
bool nsStyleImageLayers::Size::operator==(const Size& aOther) const {
MOZ_ASSERT(mWidthType < eDimensionType_COUNT, "bad mWidthType for this");
MOZ_ASSERT(mHeightType < eDimensionType_COUNT, "bad mHeightType for this");
MOZ_ASSERT(aOther.mWidthType < eDimensionType_COUNT,
"bad mWidthType for aOther");
MOZ_ASSERT(aOther.mHeightType < eDimensionType_COUNT,
"bad mHeightType for aOther");
return mWidthType == aOther.mWidthType && mHeightType == aOther.mHeightType &&
(mWidthType != eLengthPercentage || mWidth == aOther.mWidth) &&
(mHeightType != eLengthPercentage || mHeight == aOther.mHeight);
}
nsStyleImageLayers::Layer::Layer() nsStyleImageLayers::Layer::Layer()
: mClip(StyleGeometryBox::BorderBox), : mSize(StyleBackgroundSize::ExplicitSize(LengthPercentageOrAuto::Auto(),
LengthPercentageOrAuto::Auto())),
mClip(StyleGeometryBox::BorderBox),
mAttachment(StyleImageLayerAttachment::Scroll), mAttachment(StyleImageLayerAttachment::Scroll),
mBlendMode(NS_STYLE_BLEND_NORMAL), mBlendMode(NS_STYLE_BLEND_NORMAL),
mComposite(NS_STYLE_MASK_COMPOSITE_ADD), mComposite(NS_STYLE_MASK_COMPOSITE_ADD),
mMaskMode(NS_STYLE_MASK_MODE_MATCH_SOURCE) { mMaskMode(NS_STYLE_MASK_MODE_MATCH_SOURCE) {
mImage.SetNull(); mImage.SetNull();
mSize.SetInitialValues();
} }
nsStyleImageLayers::Layer::~Layer() {} nsStyleImageLayers::Layer::~Layer() {}
@ -2734,7 +2715,7 @@ bool nsStyleImageLayers::Layer::
} }
return mPosition.DependsOnPositioningAreaSize() || return mPosition.DependsOnPositioningAreaSize() ||
mSize.DependsOnPositioningAreaSize(mImage) || SizeDependsOnPositioningAreaSize(mSize, mImage) ||
mRepeat.DependsOnPositioningAreaSize(); mRepeat.DependsOnPositioningAreaSize();
} }

Просмотреть файл

@ -496,68 +496,6 @@ struct nsStyleImageLayers {
static bool IsInitialPositionForLayerType(mozilla::Position aPosition, static bool IsInitialPositionForLayerType(mozilla::Position aPosition,
LayerType aType); LayerType aType);
struct Size {
struct Dimension : public nsStyleCoord::CalcValue {
nscoord ResolveLengthPercentage(nscoord aAvailable) const {
double d = double(mPercent) * double(aAvailable) + double(mLength);
if (d < 0.0) {
return 0;
}
return NSToCoordRoundWithClamp(float(d));
}
};
Dimension mWidth, mHeight;
bool IsInitialValue() const {
return mWidthType == eAuto && mHeightType == eAuto;
}
nscoord ResolveWidthLengthPercentage(
const nsSize& aBgPositioningArea) const {
MOZ_ASSERT(mWidthType == eLengthPercentage,
"resolving non-length/percent dimension!");
return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
}
nscoord ResolveHeightLengthPercentage(
const nsSize& aBgPositioningArea) const {
MOZ_ASSERT(mHeightType == eLengthPercentage,
"resolving non-length/percent dimension!");
return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
}
// Except for eLengthPercentage, Dimension types which might change
// how a layer is painted when the corresponding frame's dimensions
// change *must* precede all dimension types which are agnostic to
// frame size; see DependsOnDependsOnPositioningAreaSizeSize.
enum DimensionType {
// If one of mWidth and mHeight is eContain or eCover, then both are.
// NOTE: eContain and eCover *must* be equal to NS_STYLE_BG_SIZE_CONTAIN
// and NS_STYLE_BG_SIZE_COVER (in kBackgroundSizeKTable).
eContain,
eCover,
eAuto,
eLengthPercentage,
eDimensionType_COUNT
};
uint8_t mWidthType, mHeightType;
// True if the effective image size described by this depends on the size of
// the corresponding frame, when aImage (which must not have null type) is
// the background image.
bool DependsOnPositioningAreaSize(const nsStyleImage& aImage) const;
// Initialize nothing
Size() {}
// Initialize to initial values
void SetInitialValues();
bool operator==(const Size& aOther) const;
bool operator!=(const Size& aOther) const { return !(*this == aOther); }
};
struct Repeat { struct Repeat {
mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat; mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
@ -589,10 +527,11 @@ struct nsStyleImageLayers {
struct Layer { struct Layer {
typedef mozilla::StyleGeometryBox StyleGeometryBox; typedef mozilla::StyleGeometryBox StyleGeometryBox;
typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment; typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment;
typedef mozilla::StyleBackgroundSize StyleBackgroundSize;
nsStyleImage mImage; nsStyleImage mImage;
mozilla::Position mPosition; mozilla::Position mPosition;
Size mSize; StyleBackgroundSize mSize;
StyleGeometryBox mClip; StyleGeometryBox mClip;
MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin; MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin;
@ -1290,7 +1229,7 @@ struct nsStyleGridTemplate {
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition { struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto; using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
using Position = mozilla::Position; using Position = mozilla::Position;
template<typename T> template <typename T>
using StyleRect = mozilla::StyleRect<T>; using StyleRect = mozilla::StyleRect<T>;
using StyleSize = mozilla::StyleSize; using StyleSize = mozilla::StyleSize;
using StyleMaxSize = mozilla::StyleMaxSize; using StyleMaxSize = mozilla::StyleMaxSize;

Просмотреть файл

@ -83,6 +83,7 @@ include = [
"MaxSize", "MaxSize",
"FlexBasis", "FlexBasis",
"Position", "Position",
"BackgroundSize",
] ]
item_types = ["enums", "structs", "typedefs"] item_types = ["enums", "structs", "typedefs"]
@ -157,6 +158,10 @@ item_types = ["enums", "structs", "typedefs"]
static inline StyleGenericPosition FromPercentage(float); static inline StyleGenericPosition FromPercentage(float);
""" """
"GenericBackgroundSize" = """
bool IsInitialValue() const;
"""
"Rect" = """ "Rect" = """
// Defined in nsStyleCoord.h // Defined in nsStyleCoord.h
template<typename Predicate> inline bool All(Predicate) const; template<typename Predicate> inline bool All(Predicate) const;

Просмотреть файл

@ -23,13 +23,10 @@ use crate::values::computed::url::ComputedImageUrl;
use crate::values::computed::{Angle, Gradient, Image}; use crate::values::computed::{Angle, Gradient, Image};
use crate::values::computed::{Integer, LengthPercentage}; use crate::values::computed::{Integer, LengthPercentage};
use crate::values::computed::{Length, Percentage, TextAlign}; use crate::values::computed::{Length, Percentage, TextAlign};
use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentageOrAuto};
use crate::values::generics::box_::VerticalAlign; use crate::values::generics::box_::VerticalAlign;
use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::grid::{TrackListValue, TrackSize};
use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
use crate::values::generics::length::LengthPercentageOrAuto as GenericLengthPercentageOrAuto;
use crate::values::generics::rect::Rect; use crate::values::generics::rect::Rect;
use crate::values::generics::NonNegative;
use app_units::Au; use app_units::Au;
use std::f32::consts::PI; use std::f32::consts::PI;
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
@ -62,42 +59,6 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage {
) )
} }
} }
impl NonNegativeLengthPercentageOrAuto {
/// Convert this value in an appropriate `nsStyleCoord::CalcValue`.
pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> {
match *self {
GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)),
GenericLengthPercentageOrAuto::Auto => None,
}
}
}
impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto {
GenericLengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other))
}
}
// FIXME(emilio): A lot of these impl From should probably become explicit or
// disappear as we move more stuff to cbindgen.
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> Self {
GenericLengthPercentageOrAuto::LengthPercentage(NonNegative(
LengthPercentage::with_clamping_mode(
Au(other.mLength).into(),
if other.mHasPercent {
Some(Percentage(other.mPercent))
} else {
None
},
AllowedNumericType::NonNegative,
/* was_calc = */ true,
),
))
}
}
impl From<Angle> for CoordDataValue { impl From<Angle> for CoordDataValue {
fn from(reference: Angle) -> Self { fn from(reference: Angle) -> Self {
CoordDataValue::Degree(reference.degrees()) CoordDataValue::Degree(reference.degrees())

Просмотреть файл

@ -3797,80 +3797,12 @@ fn static_assert() {
% endfor % endfor
<%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize"> <%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize">
use crate::gecko_bindings::structs::nsStyleImageLayers_Size_Dimension; servo
use crate::gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType;
use crate::gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImageLayers_Size};
use crate::values::generics::background::BackgroundSize;
let mut width = nsStyleCoord_CalcValue::new();
let mut height = nsStyleCoord_CalcValue::new();
let (w_type, h_type) = match servo {
BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => {
let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto;
let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto;
if let Some(w) = explicit_width.to_calc_value() {
width = w;
w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
}
if let Some(h) = explicit_height.to_calc_value() {
height = h;
h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
}
(w_type, h_type)
}
BackgroundSize::Cover => {
(
nsStyleImageLayers_Size_DimensionType::eCover,
nsStyleImageLayers_Size_DimensionType::eCover,
)
},
BackgroundSize::Contain => {
(
nsStyleImageLayers_Size_DimensionType::eContain,
nsStyleImageLayers_Size_DimensionType::eContain,
)
},
};
nsStyleImageLayers_Size {
mWidth: nsStyleImageLayers_Size_Dimension { _base: width },
mHeight: nsStyleImageLayers_Size_Dimension { _base: height },
mWidthType: w_type as u8,
mHeightType: h_type as u8,
}
</%self:simple_image_array_property> </%self:simple_image_array_property>
pub fn clone_${shorthand}_size(&self) -> longhands::${shorthand}_size::computed_value::T { pub fn clone_${shorthand}_size(&self) -> longhands::${shorthand}_size::computed_value::T {
use crate::gecko_bindings::structs::nsStyleCoord_CalcValue as CalcValue;
use crate::gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType as DimensionType;
use crate::values::computed::NonNegativeLengthPercentageOrAuto;
use crate::values::generics::background::BackgroundSize;
fn to_servo(value: CalcValue, ty: u8) -> NonNegativeLengthPercentageOrAuto {
if ty == DimensionType::eAuto as u8 {
NonNegativeLengthPercentageOrAuto::auto()
} else {
debug_assert_eq!(ty, DimensionType::eLengthPercentage as u8);
value.into()
}
}
longhands::${shorthand}_size::computed_value::List( longhands::${shorthand}_size::computed_value::List(
self.gecko.${image_layers_field}.mLayers.iter().map(|ref layer| { self.gecko.${image_layers_field}.mLayers.iter().map(|layer| layer.mSize).collect()
if DimensionType::eCover as u8 == layer.mSize.mWidthType {
debug_assert_eq!(layer.mSize.mHeightType, DimensionType::eCover as u8);
return BackgroundSize::Cover
}
if DimensionType::eContain as u8 == layer.mSize.mWidthType {
debug_assert_eq!(layer.mSize.mHeightType, DimensionType::eContain as u8);
return BackgroundSize::Contain
}
BackgroundSize::Explicit {
width: to_servo(layer.mSize.mWidth._base, layer.mSize.mWidthType),
height: to_servo(layer.mSize.mHeight._base, layer.mSize.mHeightType),
}
}).collect()
) )
} }

Просмотреть файл

@ -6,19 +6,8 @@
use crate::values::computed::length::NonNegativeLengthPercentage; use crate::values::computed::length::NonNegativeLengthPercentage;
use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
use crate::values::generics::length::LengthPercentageOrAuto;
pub use crate::values::specified::background::BackgroundRepeat; pub use crate::values::specified::background::BackgroundRepeat;
/// A computed value for the `background-size` property. /// A computed value for the `background-size` property.
pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>; pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
impl BackgroundSize {
/// Returns `auto auto`.
pub fn auto() -> Self {
GenericBackgroundSize::Explicit {
width: LengthPercentageOrAuto::auto(),
height: LengthPercentageOrAuto::auto(),
}
}
}

Просмотреть файл

@ -4,7 +4,7 @@
//! Generic types for CSS values related to backgrounds. //! Generic types for CSS values related to backgrounds.
use crate::values::generics::length::LengthPercentageOrAuto; use crate::values::generics::length::{LengthPercentageOrAuto, GenericLengthPercentageOrAuto};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss}; use style_traits::{CssWriter, ToCss};
@ -22,13 +22,14 @@ use style_traits::{CssWriter, ToCss};
ToAnimatedZero, ToAnimatedZero,
ToComputedValue, ToComputedValue,
)] )]
pub enum BackgroundSize<LengthPercentage> { #[repr(C, u8)]
pub enum GenericBackgroundSize<LengthPercent> {
/// `<width> <height>` /// `<width> <height>`
Explicit { ExplicitSize {
/// Explicit width. /// Explicit width.
width: LengthPercentageOrAuto<LengthPercentage>, width: GenericLengthPercentageOrAuto<LengthPercent>,
/// Explicit height. /// Explicit height.
height: LengthPercentageOrAuto<LengthPercentage>, height: GenericLengthPercentageOrAuto<LengthPercent>,
}, },
/// `cover` /// `cover`
#[animation(error)] #[animation(error)]
@ -38,6 +39,8 @@ pub enum BackgroundSize<LengthPercentage> {
Contain, Contain,
} }
pub use self::GenericBackgroundSize as BackgroundSize;
impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage> impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage>
where where
LengthPercentage: ToCss, LengthPercentage: ToCss,
@ -47,7 +50,7 @@ where
W: Write, W: Write,
{ {
match self { match self {
BackgroundSize::Explicit { width, height } => { BackgroundSize::ExplicitSize { width, height } => {
width.to_css(dest)?; width.to_css(dest)?;
// NOTE(emilio): We should probably simplify all these in case // NOTE(emilio): We should probably simplify all these in case
// `width == `height`, but all other browsers agree on only // `width == `height`, but all other browsers agree on only
@ -63,3 +66,13 @@ where
} }
} }
} }
impl<LengthPercentage> BackgroundSize<LengthPercentage> {
/// Returns `auto auto`.
pub fn auto() -> Self {
GenericBackgroundSize::ExplicitSize {
width: LengthPercentageOrAuto::Auto,
height: LengthPercentageOrAuto::Auto,
}
}
}

Просмотреть файл

@ -26,7 +26,7 @@ impl Parse for BackgroundSize {
let height = input let height = input
.try(|i| NonNegativeLengthPercentageOrAuto::parse(context, i)) .try(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
.unwrap_or(NonNegativeLengthPercentageOrAuto::auto()); .unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
return Ok(GenericBackgroundSize::Explicit { width, height }); return Ok(GenericBackgroundSize::ExplicitSize { width, height });
} }
Ok(try_match_ident_ignore_ascii_case! { input, Ok(try_match_ident_ignore_ascii_case! { input,
"cover" => GenericBackgroundSize::Cover, "cover" => GenericBackgroundSize::Cover,
@ -35,16 +35,6 @@ impl Parse for BackgroundSize {
} }
} }
impl BackgroundSize {
/// Returns `auto auto`.
pub fn auto() -> Self {
GenericBackgroundSize::Explicit {
width: NonNegativeLengthPercentageOrAuto::auto(),
height: NonNegativeLengthPercentageOrAuto::auto(),
}
}
}
/// One of the keywords for `background-repeat`. /// One of the keywords for `background-repeat`.
#[derive( #[derive(
Clone, Clone,