Bug 1028716 part 2 - Handle the new orient values in <progress> and <meter> layout. r=smontagu
authorJonathan Kew <jkew@mozilla.com>
Fri, 27 Jun 2014 11:25:11 +0100
changeset 240508 7a39e04e9ab173781b721f5a7818df73683dde35
parent 240507 2204929c7540a20914518e5a0530afbbfc8002c0
child 240509 f9810c65cd6979f6624b39b6c0afbbef6b3eaf7a
push id58842
push userjkew@mozilla.com
push dateWed, 22 Apr 2015 15:19:43 +0000
treeherdermozilla-inbound@03da3b6d21b9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmontagu
bugs1028716
milestone40.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 1028716 part 2 - Handle the new orient values in <progress> and <meter> layout. r=smontagu
layout/forms/nsMeterFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -130,17 +130,17 @@ nsMeterFrame::Reflow(nsPresContext*     
 }
 
 void
 nsMeterFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
                              nsPresContext*           aPresContext,
                              const nsHTMLReflowState& aReflowState,
                              nsReflowStatus&          aStatus)
 {
-  bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
+  bool vertical = ResolvedOrientationIsVertical();
   WritingMode wm = aBarFrame->GetWritingMode();
   LogicalSize availSize = aReflowState.ComputedSize(wm);
   availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState reflowState(aPresContext, aReflowState,
                                 aBarFrame, availSize);
   nscoord size = vertical ? aReflowState.ComputedHeight()
                           : aReflowState.ComputedWidth();
   nscoord xoffset = aReflowState.ComputedPhysicalBorderPadding().left;
@@ -153,17 +153,17 @@ nsMeterFrame::ReflowBarFrame(nsIFrame*  
   double min = meterElement->Min();
   double value = meterElement->Value();
 
   double position = max - min;
   position = position != 0 ? (value - min) / position : 1;
 
   size = NSToCoordRound(size * position);
 
-  if (!vertical && StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
+  if (!vertical && (wm.IsVertical() ? wm.IsVerticalRL() : !wm.IsBidiLTR())) {
     xoffset += aReflowState.ComputedWidth() - size;
   }
 
   // The bar position is *always* constrained.
   if (vertical) {
     // We want the bar to begin at the bottom.
     yoffset += aReflowState.ComputedHeight() - size;
 
@@ -225,40 +225,40 @@ nsMeterFrame::ComputeAutoSize(nsRenderin
   NS_ENSURE_SUCCESS(nsLayoutUtils::GetFontMetricsForFrame(this,
                                                           getter_AddRefs(fontMet)),
                     LogicalSize(aWM));
 
   const WritingMode wm = GetWritingMode();
   LogicalSize autoSize(wm);
   autoSize.BSize(wm) = autoSize.ISize(wm) = fontMet->Font().size; // 1em
 
-  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL) {
+  if (ResolvedOrientationIsVertical()) {
     autoSize.Height(wm) *= 5; // 5em
   } else {
     autoSize.Width(wm) *= 5; // 5em
   }
 
   return autoSize.ConvertTo(aWM, wm);
 }
 
 nscoord
 nsMeterFrame::GetMinISize(nsRenderingContext *aRenderingContext)
 {
   nsRefPtr<nsFontMetrics> fontMet;
   NS_ENSURE_SUCCESS(
       nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)), 0);
 
-  nscoord minWidth = fontMet->Font().size; // 1em
+  nscoord minISize = fontMet->Font().size; // 1em
 
-  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
-    // The orientation is horizontal
-    minWidth *= 5; // 5em
+  if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) {
+    // The orientation is inline
+    minISize *= 5; // 5em
   }
 
-  return minWidth;
+  return minISize;
 }
 
 nscoord
 nsMeterFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
 {
   return GetMinISize(aRenderingContext);
 }
 
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -134,17 +134,17 @@ nsProgressFrame::Reflow(nsPresContext*  
 }
 
 void
 nsProgressFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
                                 nsPresContext*           aPresContext,
                                 const nsHTMLReflowState& aReflowState,
                                 nsReflowStatus&          aStatus)
 {
-  bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
+  bool vertical = ResolvedOrientationIsVertical();
   WritingMode wm = aBarFrame->GetWritingMode();
   LogicalSize availSize = aReflowState.ComputedSize(wm);
   availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState reflowState(aPresContext, aReflowState,
                                 aBarFrame, availSize);
   nscoord size = vertical ? aReflowState.ComputedHeight()
                           : aReflowState.ComputedWidth();
   nscoord xoffset = aReflowState.ComputedPhysicalBorderPadding().left;
@@ -153,17 +153,17 @@ nsProgressFrame::ReflowBarFrame(nsIFrame
   double position = static_cast<HTMLProgressElement*>(mContent)->Position();
 
   // Force the bar's size to match the current progress.
   // When indeterminate, the progress' size will be 100%.
   if (position >= 0.0) {
     size *= position;
   }
 
-  if (!vertical && StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
+  if (!vertical && (wm.IsVertical() ? wm.IsVerticalRL() : !wm.IsBidiLTR())) {
     xoffset += aReflowState.ComputedWidth() - size;
   }
 
   // The bar size is fixed in these cases:
   // - the progress position is determined: the bar size is fixed according
   //   to it's value.
   // - the progress position is indeterminate and the bar appearance should be
   //   shown as native: the bar size is forced to 100%.
@@ -231,40 +231,40 @@ nsProgressFrame::ComputeAutoSize(nsRende
                                  bool aShrinkWrap)
 {
   const WritingMode wm = GetWritingMode();
   LogicalSize autoSize(wm);
   autoSize.BSize(wm) = autoSize.ISize(wm) =
     NSToCoordRound(StyleFont()->mFont.size *
                    nsLayoutUtils::FontSizeInflationFor(this)); // 1em
 
-  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL) {
+  if (ResolvedOrientationIsVertical()) {
     autoSize.Height(wm) *= 10; // 10em
   } else {
     autoSize.Width(wm) *= 10; // 10em
   }
 
   return autoSize.ConvertTo(aWM, wm);
 }
 
 nscoord
 nsProgressFrame::GetMinISize(nsRenderingContext *aRenderingContext)
 {
   nsRefPtr<nsFontMetrics> fontMet;
   NS_ENSURE_SUCCESS(
       nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)), 0);
 
-  nscoord minWidth = fontMet->Font().size; // 1em
+  nscoord minISize = fontMet->Font().size; // 1em
 
-  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
-    // The orientation is horizontal
-    minWidth *= 10; // 10em
+  if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) {
+    // The orientation is inline
+    minISize *= 10; // 10em
   }
 
-  return minWidth;
+  return minISize;
 }
 
 nscoord
 nsProgressFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
 {
   return GetMinISize(aRenderingContext);
 }
 
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1674,16 +1674,34 @@ nsContainerFrame::PullNextInFlowChild(Co
     mFrames.AppendFrame(this, frame);
     // AppendFrame has reparented the frame, we need
     // to reparent the frame view then.
     nsContainerFrame::ReparentFrameView(frame, nextInFlow, this);
   }
   return frame;
 }
 
+bool
+nsContainerFrame::ResolvedOrientationIsVertical()
+{
+  uint8_t orient = StyleDisplay()->mOrient;
+  switch (orient) {
+    case NS_STYLE_ORIENT_HORIZONTAL:
+      return false;
+    case NS_STYLE_ORIENT_VERTICAL:
+      return true;
+    case NS_STYLE_ORIENT_INLINE:
+      return GetWritingMode().IsVertical();
+    case NS_STYLE_ORIENT_BLOCK:
+      return !GetWritingMode().IsVertical();
+  }
+  NS_NOTREACHED("unexpected -moz-orient value");
+  return false;
+}
+
 nsOverflowContinuationTracker::nsOverflowContinuationTracker(nsContainerFrame* aFrame,
                                                              bool              aWalkOOFFrames,
                                                              bool              aSkipOverflowContainerChildren)
   : mOverflowContList(nullptr),
     mPrevOverflowCont(nullptr),
     mSentry(nullptr),
     mParent(aFrame),
     mSkipOverflowContainerChildren(aSkipOverflowContainerChildren),
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -608,16 +608,22 @@ protected:
    */
   void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
                                   nsIPresShell* aPresShell,
                                   mozilla::FramePropertyTable* aPropTable,
                                   const FramePropertyDescriptor* aProp);
 
   // ==========================================================================
 
+  // Helper used by Progress and Meter frames. Returns true if the bar should
+  // be rendered vertically, based on writing-mode and -moz-orient properties.
+  bool ResolvedOrientationIsVertical();
+
+  // ==========================================================================
+
   nsFrameList mFrames;
 };
 
 // ==========================================================================
 /* The out-of-flow-related code below is for a hacky way of splitting
  * absolutely-positioned frames. Basically what we do is split the frame
  * in nsAbsoluteContainingBlock and pretend the continuation is an overflow
  * container. This isn't an ideal solution, but it lets us print the content