Bug 1541913 - Use Servo lengths for column-width. r=boris
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 04 Apr 2019 18:29:57 +0000
changeset 468051 ddcd214baefac1efcec62fa50d163677de01869b
parent 468050 9c7e806cf361adbea6ca2d9d82641c1bca0ed5e1
child 468052 a0bf0da499b1fba9ce5ef32161e66b1de8441547
push id82354
push userealvarez@mozilla.com
push dateThu, 04 Apr 2019 18:38:43 +0000
treeherderautoland@a0bf0da499b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersboris
bugs1541913
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1541913 - Use Servo lengths for column-width. r=boris Depends on D26154 Differential Revision: https://phabricator.services.mozilla.com/D26155
Cargo.lock
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsColumnSetFrame.h
layout/style/ServoCSSPropList.mako.py
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsStyleCoord.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
servo/components/style/properties/gecko.mako.rs
servo/ports/geckolib/cbindgen.toml
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,8 +1,10 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
 [[package]]
 name = "Inflector"
 version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -279,23 +279,19 @@ static nscoord GetColumnGap(nsColumnSetF
   const auto& columnGap = aFrame->StylePosition()->mColumnGap;
   if (columnGap.GetUnit() == eStyleUnit_Normal) {
     return aFrame->StyleFont()->mFont.size;
   }
   return nsLayoutUtils::ResolveGapToLength(columnGap, aPercentageBasis);
 }
 
 /* static */
-nscoord nsColumnSetFrame::ClampUsedColumnWidth(
-    const nsStyleCoord& aColumnWidth) {
-  MOZ_ASSERT(aColumnWidth.GetUnit() == eStyleUnit_Coord,
-             "This should only be called when column-width is a <length>!");
-
+nscoord nsColumnSetFrame::ClampUsedColumnWidth(const Length& aColumnWidth) {
   // Per spec, used values will be clamped to a minimum of 1px.
-  return std::max(CSSPixel::ToAppUnits(1), aColumnWidth.GetCoordValue());
+  return std::max(CSSPixel::ToAppUnits(1), aColumnWidth.ToAppUnits());
 }
 
 nsColumnSetFrame::ReflowConfig nsColumnSetFrame::ChooseColumnStrategy(
     const ReflowInput& aReflowInput, bool aForceAuto = false) {
   WritingMode wm = aReflowInput.GetWritingMode();
 
   const nsStyleColumn* colStyle = StyleColumn();
   nscoord availContentISize = GetAvailableContentISize(aReflowInput);
@@ -336,18 +332,18 @@ nsColumnSetFrame::ReflowConfig nsColumnS
     if (cnt == MAX_NESTED_COLUMN_BALANCING) {
       numColumns = 1;
     }
   }
 
   nscoord colISize;
   // In vertical writing-mode, "column-width" (inline size) will actually be
   // physical height, but its CSS name is still column-width.
-  if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
-    colISize = ClampUsedColumnWidth(colStyle->mColumnWidth);
+  if (colStyle->mColumnWidth.IsLength()) {
+    colISize = ClampUsedColumnWidth(colStyle->mColumnWidth.AsLength());
     NS_ASSERTION(colISize >= 0, "negative column width");
     // Reduce column count if necessary to make columns fit in the
     // available width. Compute max number of columns that fit in
     // availContentISize, satisfying colGap*(maxColumns - 1) +
     // colISize*maxColumns <= availContentISize
     if (availContentISize != NS_INTRINSICSIZE && colGap + colISize > 0 &&
         numColumns > 0) {
       // This expression uses truncated rounding, which is what we
@@ -486,18 +482,18 @@ nscoord nsColumnSetFrame::GetMinISize(gf
   if (mFrames.FirstChild() && !StyleDisplay()->IsContainSize()) {
     // We want to ignore this in the case that we're size contained
     // because our children should not contribute to our
     // intrinsic size.
     iSize = mFrames.FirstChild()->GetMinISize(aRenderingContext);
   }
   const nsStyleColumn* colStyle = StyleColumn();
   nscoord colISize;
-  if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
-    colISize = ClampUsedColumnWidth(colStyle->mColumnWidth);
+  if (colStyle->mColumnWidth.IsLength()) {
+    colISize = ClampUsedColumnWidth(colStyle->mColumnWidth.AsLength());
     // As available width reduces to zero, we reduce our number of columns
     // to one, and don't enforce the column width, so just return the min
     // of the child's min-width with any specified column width.
     iSize = std::min(iSize, colISize);
   } else {
     NS_ASSERTION(colStyle->mColumnCount > 0,
                  "column-count and column-width can't both be auto");
     // As available width reduces to zero, we still have mColumnCount columns,
@@ -522,18 +518,18 @@ nscoord nsColumnSetFrame::GetPrefISize(g
   // of any required column gaps
   // XXX what about forced column breaks here?
   nscoord result = 0;
   DISPLAY_PREF_INLINE_SIZE(this, result);
   const nsStyleColumn* colStyle = StyleColumn();
   nscoord colGap = GetColumnGap(this, NS_UNCONSTRAINEDSIZE);
 
   nscoord colISize;
-  if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
-    colISize = ClampUsedColumnWidth(colStyle->mColumnWidth);
+  if (colStyle->mColumnWidth.IsLength()) {
+    colISize = ClampUsedColumnWidth(colStyle->mColumnWidth.AsLength());
   } else if (mFrames.FirstChild() && !StyleDisplay()->IsContainSize()) {
     // We want to ignore this in the case that we're size contained
     // because our children should not contribute to our
     // intrinsic size.
     colISize = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
   } else {
     colISize = 0;
   }
--- a/layout/generic/nsColumnSetFrame.h
+++ b/layout/generic/nsColumnSetFrame.h
@@ -213,12 +213,12 @@ class nsColumnSetFrame final : public ns
                       const ReflowInput& aReflowInput, nsReflowStatus& aStatus,
                       const ReflowConfig& aConfig, bool aLastColumnUnbounded,
                       ColumnBalanceData& aColData);
 
   void ForEachColumnRule(
       const std::function<void(const nsRect& lineRect)>& aSetLineRect,
       const nsPoint& aPt);
 
-  static nscoord ClampUsedColumnWidth(const nsStyleCoord& aColumnWidth);
+  static nscoord ClampUsedColumnWidth(const mozilla::Length& aColumnWidth);
 };
 
 #endif  // nsColumnSetFrame_h___
--- a/layout/style/ServoCSSPropList.mako.py
+++ b/layout/style/ServoCSSPropList.mako.py
@@ -71,17 +71,16 @@ LONGHANDS_NOT_SERIALIZED_WITH_SERVO = [
     "border-image-width",
     "border-spacing",
     "box-shadow",
     "caret-color",
     "color",
     "column-count",
     "column-gap",
     "column-rule-width",
-    "column-width",
     "display",
     "fill",
     "filter",
     "flex-basis",
     "flex-grow",
     "flex-shrink",
     "grid-auto-columns",
     "grid-auto-flow",
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1060,25 +1060,16 @@ already_AddRefed<CSSValue> nsComputedDOM
     val->SetIdent(eCSSKeyword_auto);
   } else {
     val->SetNumber(column->mColumnCount);
   }
 
   return val.forget();
 }
 
-already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnWidth() {
-  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-
-  // XXX fix the auto case. When we actually have a column frame, I think
-  // we should return the computed column width.
-  SetValueToCoord(val, StyleColumn()->mColumnWidth, true);
-  return val.forget();
-}
-
 already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnRuleWidth() {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
   val->SetAppUnits(StyleColumn()->GetComputedColumnRuleWidth());
   return val.forget();
 }
 
 static Position MaybeResolvePositionForTransform(const LengthPercentage& aX,
                                                  const LengthPercentage& aY,
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -326,17 +326,16 @@ class nsComputedDOMStyle final : public 
   already_AddRefed<CSSValue> DoGetScrollbarColor();
 
   /* User interface properties */
   already_AddRefed<CSSValue> DoGetCaretColor();
   already_AddRefed<CSSValue> DoGetForceBrokenImageIcon();
 
   /* Column properties */
   already_AddRefed<CSSValue> DoGetColumnCount();
-  already_AddRefed<CSSValue> DoGetColumnWidth();
   already_AddRefed<CSSValue> DoGetColumnRuleWidth();
 
   /* CSS Transitions */
   already_AddRefed<CSSValue> DoGetTransitionProperty();
   already_AddRefed<CSSValue> DoGetTransitionDuration();
   already_AddRefed<CSSValue> DoGetTransitionDelay();
 
   /* CSS Animations */
--- a/layout/style/nsStyleCoord.h
+++ b/layout/style/nsStyleCoord.h
@@ -39,16 +39,20 @@ enum LogicalCorner {
   eLogicalCornerBEndIStart = 3
 };
 
 using LengthPercentage = StyleLengthPercentage;
 using LengthPercentageOrAuto = StyleLengthPercentageOrAuto;
 using NonNegativeLengthPercentage = StyleNonNegativeLengthPercentage;
 using NonNegativeLengthPercentageOrAuto =
     StyleNonNegativeLengthPercentageOrAuto;
+using Length = StyleLength;
+using LengthOrAuto = StyleLengthOrAuto;
+using NonNegativeLength = StyleNonNegativeLength;
+using NonNegativeLengthOrAuto = StyleNonNegativeLengthOrAuto;
 using BorderRadius = StyleBorderRadius;
 
 bool StyleCSSPixelLength::IsZero() const { return _0 == 0.0f; }
 
 nscoord StyleCSSPixelLength::ToAppUnits() const {
   // We want to resolve the length part of the calc() expression rounding 0.5
   // away from zero, instead of the default behavior of
   // NSToCoordRound{,WithClamp} which do floor(x + 0.5).
@@ -189,16 +193,26 @@ nscoord LengthPercentage::Resolve(nscoor
     return AsLengthPercentage().ToPercentage();                             \
   }
 
 IMPL_LENGTHPERCENTAGE_FORWARDS(LengthPercentageOrAuto)
 IMPL_LENGTHPERCENTAGE_FORWARDS(StyleSize)
 IMPL_LENGTHPERCENTAGE_FORWARDS(StyleMaxSize)
 
 template <>
+inline bool LengthOrAuto::IsLength() const {
+  return IsLengthPercentage();
+}
+
+template <>
+inline const Length& LengthOrAuto::AsLength() const {
+  return AsLengthPercentage();
+}
+
+template <>
 inline bool StyleFlexBasis::IsAuto() const {
   return IsSize() && AsSize().IsAuto();
 }
 
 template <>
 inline bool StyleSize::BehavesLikeInitialValueOnBlockAxis() const {
   return IsAuto() || IsExtremumLength();
 }
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -583,17 +583,17 @@ nsChangeHint nsStyleXUL::CalcDifference(
 
 // --------------------
 // nsStyleColumn
 //
 /* static */ const uint32_t nsStyleColumn::kMaxColumnCount;
 /* static */ const uint32_t nsStyleColumn::kColumnCountAuto;
 
 nsStyleColumn::nsStyleColumn(const Document& aDocument)
-    : mColumnWidth(eStyleUnit_Auto),
+    : mColumnWidth(LengthOrAuto::Auto()),
       mColumnRuleColor(StyleColor::CurrentColor()),
       mColumnRuleStyle(StyleBorderStyle::None),
       mColumnRuleWidth(kMediumBorderWidth),
       mTwipsPerPixel(TwipsPerPixel(aDocument)) {
   MOZ_COUNT_CTOR(nsStyleColumn);
 }
 
 nsStyleColumn::~nsStyleColumn() { MOZ_COUNT_DTOR(nsStyleColumn); }
@@ -607,18 +607,17 @@ nsStyleColumn::nsStyleColumn(const nsSty
       mColumnSpan(aSource.mColumnSpan),
       mColumnRuleWidth(aSource.mColumnRuleWidth),
       mTwipsPerPixel(aSource.mTwipsPerPixel) {
   MOZ_COUNT_CTOR(nsStyleColumn);
 }
 
 nsChangeHint nsStyleColumn::CalcDifference(
     const nsStyleColumn& aNewData) const {
-  if ((mColumnWidth.GetUnit() == eStyleUnit_Auto) !=
-          (aNewData.mColumnWidth.GetUnit() == eStyleUnit_Auto) ||
+  if (mColumnWidth.IsAuto() != aNewData.mColumnWidth.IsAuto() ||
       mColumnCount != aNewData.mColumnCount ||
       mColumnSpan != aNewData.mColumnSpan) {
     // We force column count changes to do a reframe, because it's tricky to
     // handle some edge cases where the column count gets smaller and content
     // overflows.
     // XXX not ideal
     return nsChangeHint_ReconstructFrame;
   }
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2603,30 +2603,29 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   // This is the maximum number of columns we can process. It's used in
   // nsColumnSetFrame.
   static const uint32_t kMaxColumnCount = 1000;
 
   // This represents the value of column-count: auto.
   static const uint32_t kColumnCountAuto = 0;
 
   uint32_t mColumnCount = kColumnCountAuto;
-  nsStyleCoord mColumnWidth;  // coord, auto
+  mozilla::NonNegativeLengthOrAuto mColumnWidth;
 
   mozilla::StyleColor mColumnRuleColor;
   mozilla::StyleBorderStyle mColumnRuleStyle;  // StyleborderStyle::*
   mozilla::StyleColumnFill mColumnFill = mozilla::StyleColumnFill::Balance;
   mozilla::StyleColumnSpan mColumnSpan = mozilla::StyleColumnSpan::None;
 
   nscoord GetComputedColumnRuleWidth() const {
     return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
   }
 
   bool IsColumnContainerStyle() const {
-    return (mColumnCount != kColumnCountAuto ||
-            mColumnWidth.GetUnit() != eStyleUnit_Auto);
+    return mColumnCount != kColumnCountAuto || !mColumnWidth.IsAuto();
   }
 
   bool IsColumnSpanStyle() const {
     return mColumnSpan == mozilla::StyleColumnSpan::All;
   }
 
  protected:
   nscoord mColumnRuleWidth;  // coord
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -1199,17 +1199,16 @@ impl Clone for ${style_struct.gecko_stru
 <%def name="impl_trait(style_struct_name, skip_longhands='')">
 <%
     style_struct = next(x for x in data.style_structs if x.name == style_struct_name)
     longhands = [x for x in style_struct.longhands
                 if not (skip_longhands == "*" or x.name in skip_longhands.split())]
 
     # Types used with predefined_type()-defined properties that we can auto-generate.
     predefined_types = {
-        "length::NonNegativeLengthOrAuto": impl_style_coord,
         "length::NonNegativeLengthPercentageOrNormal": impl_style_coord,
         "Length": impl_absolute_length,
         "MozScriptMinSize": impl_absolute_length,
         "RGBAColor": impl_rgba_color,
         "SVGLength": impl_svg_length,
         "SVGOpacity": impl_svg_opacity,
         "SVGPaint": impl_svg_paint,
         "SVGWidth": impl_svg_length,
--- a/servo/ports/geckolib/cbindgen.toml
+++ b/servo/ports/geckolib/cbindgen.toml
@@ -77,16 +77,18 @@ include = [
   "Resize",
   "Overflow",
   "LengthPercentage",
   "LetterSpacing",
   "NonNegativeLengthPercentage",
   "LengthPercentageOrAuto",
   "LineHeight",
   "NonNegativeLengthPercentageOrAuto",
+  "LengthOrAuto",
+  "NonNegativeLengthOrAuto",
   "Rect",
   "IntersectionObserverRootMargin",
   "Size",
   "MaxSize",
   "FlexBasis",
   "Position",
   "BackgroundSize",
   "BorderImageSlice",
@@ -194,16 +196,20 @@ renaming_overrides_prefixing = true
 
 "GenericLengthPercentageOrAuto" = """
   inline bool ConvertsToLength() const;
   inline nscoord ToLength() const;
   inline bool ConvertsToPercentage() const;
   inline float ToPercentage() const;
   inline bool HasPercent() const;
   inline bool HasLengthAndPercentage() const;
+
+  // Just some convenient aliases for LengthOrAuto, to avoid confusing naming.
+  inline bool IsLength() const;
+  inline const StyleLength& AsLength() const;
 """
 
 "GenericSize" = """
   inline bool ConvertsToLength() const;
   inline nscoord ToLength() const;
   inline bool ConvertsToPercentage() const;
   inline float ToPercentage() const;
   inline bool HasPercent() const;