Bug 1188061 - Pass the style context to nsStylePosition::CalcDifference so that it can take account of writing-mode where necessary. r=dbaron
authorJonathan Kew <jkew@mozilla.com>
Wed, 09 Sep 2015 12:22:02 +0100
changeset 294161 3ef7c7277bd66903738a7011f78bfe16bb040739
parent 294160 2739625b99bf100ec26ab52f373ebf7fd156f78f
child 294162 373d3fa40d9e81811d5b3106faab0789458e6afb
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1188061
milestone43.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 1188061 - Pass the style context to nsStylePosition::CalcDifference so that it can take account of writing-mode where necessary. r=dbaron
layout/reftests/writing-mode/reftest.list
layout/style/nsStyleContext.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
--- a/layout/reftests/writing-mode/reftest.list
+++ b/layout/reftests/writing-mode/reftest.list
@@ -145,17 +145,17 @@ test-pref(dom.meta-viewport.enabled,true
 == 1172774-percent-margin-3.html 1172774-percent-vertical-ref.html
 == 1172774-percent-margin-4.html 1172774-percent-vertical-ref.html
 == 1172774-percent-padding-1.html 1172774-percent-horizontal-ref.html
 == 1172774-percent-padding-2.html 1172774-percent-horizontal-ref.html
 == 1172774-percent-padding-3.html 1172774-percent-vertical-ref.html
 == 1172774-percent-padding-4.html 1172774-percent-vertical-ref.html
 == 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html
 == 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html
-fails == 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics-ref.html
-fails == 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize-ref.html
+== 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics-ref.html
+== 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize-ref.html
 == 1196887-1-computed-display-inline-block.html 1196887-1-computed-display-inline-block-ref.html
 
 # Suite of tests from GĂ©rard Talbot in bug 1079151
 include abspos/reftest.list
 
 # Tests for tables with vertical writing modes
 include tables/reftest.list
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -872,29 +872,29 @@ nsStyleContext::CalcStyleDifference(nsSt
         /* The very same struct, so we know that there will be no */          \
         /* differences.                                           */          \
         *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                      \
       } else if (compare ||                                                   \
                  (NS_SubtractHint(maxDifference,                              \
                                   differenceAlwaysHandledForDescendants) &    \
                   aParentHintsNotHandledForDescendants)) {                    \
         nsChangeHint difference =                                             \
-            this##struct_->CalcDifference(*other##struct_);                   \
+          this##struct_->CalcDifference(*other##struct_ EXTRA_DIFF_ARGS);     \
         NS_ASSERTION(NS_IsHintSubset(difference, maxDifference),              \
                      "CalcDifference() returned bigger hint than "            \
                      "MaxDifference()");                                      \
         NS_UpdateHint(hint, difference);                                      \
         if (!difference) {                                                    \
           *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                    \
         }                                                                     \
       } else {                                                                \
         /* We still must call CalcDifference to see if there were any */      \
         /* changes so that we can set *aEqualStructs appropriately.   */      \
         nsChangeHint difference =                                             \
-            this##struct_->CalcDifference(*other##struct_);                   \
+          this##struct_->CalcDifference(*other##struct_ EXTRA_DIFF_ARGS);     \
         NS_ASSERTION(NS_IsHintSubset(difference, maxDifference),              \
                      "CalcDifference() returned bigger hint than "            \
                      "MaxDifference()");                                      \
         if (!difference) {                                                    \
           *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                    \
         }                                                                     \
       }                                                                       \
     } else {                                                                  \
@@ -903,39 +903,45 @@ nsStyleContext::CalcStyleDifference(nsSt
     styleStructCount++;                                                       \
   PR_END_MACRO
 
   // In general, we want to examine structs starting with those that can
   // cause the largest style change, down to those that can cause the
   // smallest.  This lets us skip later ones if we already have a hint
   // that subsumes their MaxDifference.  (As the hints get
   // finer-grained, this optimization is becoming less useful, though.)
+#define EXTRA_DIFF_ARGS /* nothing */
   DO_STRUCT_DIFFERENCE(Display);
   DO_STRUCT_DIFFERENCE(XUL);
   DO_STRUCT_DIFFERENCE(Column);
   DO_STRUCT_DIFFERENCE(Content);
   DO_STRUCT_DIFFERENCE(UserInterface);
   DO_STRUCT_DIFFERENCE(Visibility);
   DO_STRUCT_DIFFERENCE(Outline);
   DO_STRUCT_DIFFERENCE(TableBorder);
   DO_STRUCT_DIFFERENCE(Table);
   DO_STRUCT_DIFFERENCE(UIReset);
   DO_STRUCT_DIFFERENCE(Text);
   DO_STRUCT_DIFFERENCE(List);
   DO_STRUCT_DIFFERENCE(Quotes);
   DO_STRUCT_DIFFERENCE(SVGReset);
   DO_STRUCT_DIFFERENCE(SVG);
+#undef EXTRA_DIFF_ARGS
+#define EXTRA_DIFF_ARGS , this
   DO_STRUCT_DIFFERENCE(Position);
+#undef EXTRA_DIFF_ARGS
+#define EXTRA_DIFF_ARGS /* nothing */
   DO_STRUCT_DIFFERENCE(Font);
   DO_STRUCT_DIFFERENCE(Margin);
   DO_STRUCT_DIFFERENCE(Padding);
   DO_STRUCT_DIFFERENCE(Border);
   DO_STRUCT_DIFFERENCE(TextReset);
   DO_STRUCT_DIFFERENCE(Background);
   DO_STRUCT_DIFFERENCE(Color);
+#undef EXTRA_DIFF_ARGS
 
 #undef DO_STRUCT_DIFFERENCE
 
   MOZ_ASSERT(styleStructCount == nsStyleStructID_Length,
              "missing a call to DO_STRUCT_DIFFERENCE");
 
   // We check for struct pointer equality here rather than as part of the
   // DO_STRUCT_DIFFERENCE calls, since those calls can result in structs
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1492,17 +1492,19 @@ IsAutonessEqual(const nsStyleSides& aSid
     if ((aSides1.GetUnit(side) == eStyleUnit_Auto) !=
         (aSides2.GetUnit(side) == eStyleUnit_Auto)) {
       return false;
     }
   }
   return true;
 }
 
-nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) const
+nsChangeHint
+nsStylePosition::CalcDifference(const nsStylePosition& aOther,
+                                nsStyleContext* aContext) const
 {
   nsChangeHint hint = nsChangeHint(0);
 
   // Changes to "z-index" require a repaint.
   if (mZIndex != aOther.mZIndex) {
     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
   }
 
@@ -1590,32 +1592,35 @@ nsChangeHint nsStylePosition::CalcDiffer
   // NOTE: If we get here, we know that mFlexWrap == aOther.mFlexWrap
   // (otherwise, we would've returned earlier). So it doesn't matter which one
   // of those we check to see if we're multi-line.
   if (mFlexWrap != NS_STYLE_FLEX_WRAP_NOWRAP &&
       mAlignContent != aOther.mAlignContent) {
     NS_UpdateHint(hint, nsChangeHint_NeedReflow);
   }
 
-  if (mHeight != aOther.mHeight ||
-      mMinHeight != aOther.mMinHeight ||
-      mMaxHeight != aOther.mMaxHeight) {
-    // Height changes can affect descendant intrinsic sizes due to replaced
-    // elements with percentage heights in descendants which also have
-    // percentage heights. This is handled via nsChangeHint_UpdateComputedBSize
+  bool widthChanged = mWidth != aOther.mWidth ||
+                      mMinWidth != aOther.mMinWidth ||
+                      mMaxWidth != aOther.mMaxWidth;
+  bool heightChanged = mHeight != aOther.mHeight ||
+                       mMinHeight != aOther.mMinHeight ||
+                       mMaxHeight != aOther.mMaxHeight;
+  bool isVertical = WritingMode(aContext).IsVertical();
+  if (isVertical ? widthChanged : heightChanged) {
+    // Block-size changes can affect descendant intrinsic sizes due to replaced
+    // elements with percentage bsizes in descendants which also have
+    // percentage bsizes. This is handled via nsChangeHint_UpdateComputedBSize
     // which clears intrinsic sizes for frames that have such replaced elements.
     NS_UpdateHint(hint, nsChangeHint_NeedReflow |
         nsChangeHint_UpdateComputedBSize |
         nsChangeHint_ReflowChangesSizeOrPosition);
   }
 
-  if (mWidth != aOther.mWidth ||
-      mMinWidth != aOther.mMinWidth ||
-      mMaxWidth != aOther.mMaxWidth) {
-    // None of our width differences can affect descendant intrinsic
+  if (isVertical ? heightChanged : widthChanged) {
+    // None of our inline-size differences can affect descendant intrinsic
     // sizes and none of them need to force children to reflow.
     NS_UpdateHint(hint, NS_SubtractHint(nsChangeHint_AllReflowHints,
                                         NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
                                                        nsChangeHint_NeedDirtyReflow)));
   }
 
   // If any of the offsets have changed, then return the respective hints
   // so that we would hopefully be able to avoid reflowing.
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1360,17 +1360,18 @@ struct nsStylePosition {
       AllocateByObjectID(nsPresArena::nsStylePosition_id, sz);
   }
   void Destroy(nsPresContext* aContext) {
     this->~nsStylePosition();
     aContext->PresShell()->
       FreeByObjectID(nsPresArena::nsStylePosition_id, this);
   }
 
-  nsChangeHint CalcDifference(const nsStylePosition& aOther) const;
+  nsChangeHint CalcDifference(const nsStylePosition& aOther,
+                              nsStyleContext* aContext) const;
   static nsChangeHint MaxDifference() {
     return NS_CombineHint(NS_STYLE_HINT_REFLOW,
                           nsChangeHint(nsChangeHint_RecomputePosition |
                                        nsChangeHint_UpdateParentOverflow |
                                        nsChangeHint_UpdateComputedBSize));
   }
   static nsChangeHint DifferenceAlwaysHandledForDescendants() {
     // CalcDifference can return all of the reflow hints that are