Bug 1079154 patch 4: Logical versions of ReflowChild and FinishReflowChild, r=jfkthame
authorSimon Montagu <smontagu@smontagu.org>
Tue, 06 Jan 2015 23:10:07 -0800
changeset 248194 c16d59bb79d13ff7221511a13b134241dbdc7f44
parent 248193 1fa61a0310e7b7c65ce81d1c4eba7ec3fb47ed31
child 248195 0b2d6f002feea0a8ebb8f4b922c7b17a9fddac20
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1079154
milestone37.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 1079154 patch 4: Logical versions of ReflowChild and FinishReflowChild, r=jfkthame
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -943,16 +943,66 @@ nsContainerFrame::ComputeAutoSize(nsRend
  * requested), and then calls Reflow(). If the reflow succeeds and the child
  * frame is complete, deletes any next-in-flows using DeleteNextInFlowChild()
  */
 void
 nsContainerFrame::ReflowChild(nsIFrame*                aKidFrame,
                               nsPresContext*           aPresContext,
                               nsHTMLReflowMetrics&     aDesiredSize,
                               const nsHTMLReflowState& aReflowState,
+                              const WritingMode&       aWM,
+                              const LogicalPoint&      aPos,
+                              nscoord                  aContainerWidth,
+                              uint32_t                 aFlags,
+                              nsReflowStatus&          aStatus,
+                              nsOverflowContinuationTracker* aTracker)
+{
+  NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state");
+  if (aWM.IsVerticalRL() || (!aWM.IsVertical() && !aWM.IsBidiLTR())) {
+    NS_ASSERTION(aContainerWidth != NS_UNCONSTRAINEDSIZE,
+                 "FinishReflowChild with unconstrained container width!");
+  }
+
+  // Send the WillReflow() notification, and position the child frame
+  // and its view if requested
+  aKidFrame->WillReflow(aPresContext);
+
+  if (NS_FRAME_NO_MOVE_FRAME != (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
+    aKidFrame->SetPosition(aWM, aPos, aContainerWidth);
+  }
+
+  if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) {
+    PositionFrameView(aKidFrame);
+  }
+
+  // Reflow the child frame
+  aKidFrame->Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+
+  // If the child frame is complete, delete any next-in-flows,
+  // but only if the NO_DELETE_NEXT_IN_FLOW flag isn't set.
+  if (NS_FRAME_IS_FULLY_COMPLETE(aStatus) &&
+      !(aFlags & NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD)) {
+    nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow();
+    if (kidNextInFlow) {
+      // Remove all of the childs next-in-flows. Make sure that we ask
+      // the right parent to do the removal (it's possible that the
+      // parent is not this because we are executing pullup code)
+      nsOverflowContinuationTracker::AutoFinish fini(aTracker, aKidFrame);
+      kidNextInFlow->GetParent()->DeleteNextInFlowChild(kidNextInFlow, true);
+    }
+  }
+}
+
+//XXX temporary: hold on to a copy of the old physical version of
+//    ReflowChild so that we can convert callers incrementally.
+void
+nsContainerFrame::ReflowChild(nsIFrame*                aKidFrame,
+                              nsPresContext*           aPresContext,
+                              nsHTMLReflowMetrics&     aDesiredSize,
+                              const nsHTMLReflowState& aReflowState,
                               nscoord                  aX,
                               nscoord                  aY,
                               uint32_t                 aFlags,
                               nsReflowStatus&          aStatus,
                               nsOverflowContinuationTracker* aTracker)
 {
   NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state");
 
@@ -1039,16 +1089,65 @@ nsContainerFrame::PositionChildViews(nsI
  *    don't want to automatically sync the frame and view
  * NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
  */
 void
 nsContainerFrame::FinishReflowChild(nsIFrame*                  aKidFrame,
                                     nsPresContext*             aPresContext,
                                     const nsHTMLReflowMetrics& aDesiredSize,
                                     const nsHTMLReflowState*   aReflowState,
+                                    const WritingMode&         aWM,
+                                    const LogicalPoint&        aPos,
+                                    nscoord                    aContainerWidth,
+                                    uint32_t                   aFlags)
+{
+  if (aWM.IsVerticalRL() || (!aWM.IsVertical() && !aWM.IsBidiLTR())) {
+    NS_ASSERTION(aContainerWidth != NS_UNCONSTRAINEDSIZE,
+                 "FinishReflowChild with unconstrained container width!");
+  }
+
+  nsPoint curOrigin = aKidFrame->GetPosition();
+  WritingMode outerWM = aDesiredSize.GetWritingMode();
+  LogicalSize convertedSize = aDesiredSize.Size(outerWM).ConvertTo(aWM,
+                                                                   outerWM);
+
+  if (NS_FRAME_NO_MOVE_FRAME != (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
+    aKidFrame->SetRect(aWM, LogicalRect(aWM, aPos, convertedSize),
+                       aContainerWidth);
+  } else {
+    aKidFrame->SetSize(aWM, convertedSize);
+  }
+
+  if (aKidFrame->HasView()) {
+    nsView* view = aKidFrame->GetView();
+    // Make sure the frame's view is properly sized and positioned and has
+    // things like opacity correct
+    SyncFrameViewAfterReflow(aPresContext, aKidFrame, view,
+                             aDesiredSize.VisualOverflow(), aFlags);
+  }
+
+  nsPoint newOrigin = aKidFrame->GetPosition();
+  if (!(aFlags & NS_FRAME_NO_MOVE_VIEW) && curOrigin != newOrigin) {
+    if (!aKidFrame->HasView()) {
+      // If the frame has moved, then we need to make sure any child views are
+      // correctly positioned
+      PositionChildViews(aKidFrame);
+    }
+  }
+
+  aKidFrame->DidReflow(aPresContext, aReflowState, nsDidReflowStatus::FINISHED);
+}
+
+//XXX temporary: hold on to a copy of the old physical version of
+//    FinishReflowChild so that we can convert callers incrementally.
+void
+nsContainerFrame::FinishReflowChild(nsIFrame*                  aKidFrame,
+                                    nsPresContext*             aPresContext,
+                                    const nsHTMLReflowMetrics& aDesiredSize,
+                                    const nsHTMLReflowState*   aReflowState,
                                     nscoord                    aX,
                                     nscoord                    aY,
                                     uint32_t                   aFlags)
 {
   nsPoint curOrigin = aKidFrame->GetPosition();
 
   if (NS_FRAME_NO_MOVE_FRAME != (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
     aKidFrame->SetRect(nsRect(aX, aY, aDesiredSize.Width(), aDesiredSize.Height()));
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -240,18 +240,19 @@ public:
    *    don't want to automatically sync the frame and view
    * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
    *    case. Also implies NS_FRAME_NO_MOVE_VIEW
    */
   void ReflowChild(nsIFrame*                      aKidFrame,
                    nsPresContext*                 aPresContext,
                    nsHTMLReflowMetrics&           aDesiredSize,
                    const nsHTMLReflowState&       aReflowState,
-                   nscoord                        aX,
-                   nscoord                        aY,
+                   const mozilla::WritingMode&    aWM,
+                   const mozilla::LogicalPoint&   aPos,
+                   nscoord                        aContainerWidth,
                    uint32_t                       aFlags,
                    nsReflowStatus&                aStatus,
                    nsOverflowContinuationTracker* aTracker = nullptr);
 
   /**
    * The second half of frame reflow. Does the following:
    * - sets the frame's bounds
    * - sizes and positions (if requested) the frame's view. If the frame's final
@@ -263,25 +264,46 @@ public:
    *
    * Flags:
    * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
    *    case. Also implies NS_FRAME_NO_MOVE_VIEW
    * NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
    *    don't want to automatically sync the frame and view
    * NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
    */
+  static void FinishReflowChild(nsIFrame*                    aKidFrame,
+                                nsPresContext*               aPresContext,
+                                const nsHTMLReflowMetrics&   aDesiredSize,
+                                const nsHTMLReflowState*     aReflowState,
+                                const mozilla::WritingMode&  aWM,
+                                const mozilla::LogicalPoint& aPos,
+                                nscoord                      aContainerWidth,
+                                uint32_t                     aFlags);
+
+  //XXX temporary: hold on to a copy of the old physical versions of
+  //    ReflowChild and FinishReflowChild so that we can convert callers
+  //    incrementally.
+  void ReflowChild(nsIFrame*                      aKidFrame,
+                   nsPresContext*                 aPresContext,
+                   nsHTMLReflowMetrics&           aDesiredSize,
+                   const nsHTMLReflowState&       aReflowState,
+                   nscoord                        aX,
+                   nscoord                        aY,
+                   uint32_t                       aFlags,
+                   nsReflowStatus&                aStatus,
+                   nsOverflowContinuationTracker* aTracker = nullptr);
+
   static void FinishReflowChild(nsIFrame*                  aKidFrame,
                                 nsPresContext*             aPresContext,
                                 const nsHTMLReflowMetrics& aDesiredSize,
                                 const nsHTMLReflowState*   aReflowState,
                                 nscoord                    aX,
                                 nscoord                    aY,
                                 uint32_t                   aFlags);
 
-  
   static void PositionChildViews(nsIFrame* aFrame);
 
   // ==========================================================================
   /* Overflow containers are continuation frames that hold overflow. They
    * are created when the frame runs out of computed height, but still has
    * too much content to fit in the availableHeight. The parent creates a
    * continuation as usual, but marks it as NS_FRAME_IS_OVERFLOW_CONTAINER
    * and adds it to its next-in-flow's overflow container list, either by