Bug 944200 part 3 - [css-ui] Refactor the code to prepare for narrowing the content area by the float edges in the next part (idempotent patch). r=dholbert
authorMats Palmgren <mats@mozilla.com>
Sat, 15 Apr 2017 00:31:44 +0200
changeset 353231 a21b1caf9bf70ac5eb685b2f917d94fb4ce8361a
parent 353230 32faa7c639ff6b976f3e3ef4761f5983860f2b26
child 353232 ba55d6a84f0c33387b0faf7dbe40d0524040c5ef
push id89219
push usermpalmgren@mozilla.com
push dateFri, 14 Apr 2017 22:31:54 +0000
treeherdermozilla-inbound@d5b9f05ea3ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs944200
milestone55.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 944200 part 3 - [css-ui] Refactor the code to prepare for narrowing the content area by the float edges in the next part (idempotent patch). r=dholbert MozReview-Commit-ID: 8s0ynJSmBbD
layout/generic/TextOverflow.cpp
layout/generic/TextOverflow.h
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -460,17 +460,17 @@ TextOverflow::AnalyzeMarkerEdges(nsIFram
     }
   } else {
     // frame is inside
     aAlignmentEdges->Accumulate(mBlockWM, borderRect);
     *aFoundVisibleTextOrAtomic = true;
   }
 }
 
-void
+LogicalRect
 TextOverflow::ExamineLineFrames(nsLineBox*      aLine,
                                 FrameHashtable* aFramesToHide,
                                 AlignmentEdges* aAlignmentEdges)
 {
   // No ellipsing for 'clip' style.
   bool suppressIStart = mIStart.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
   bool suppressIEnd = mIEnd.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
   if (mCanHaveInlineAxisScrollbar) {
@@ -484,29 +484,39 @@ TextOverflow::ExamineLineFrames(nsLineBo
       suppressIStart = true;
     }
     if (pos.I(mBlockWM) >= scrollRange.IEnd(mBlockWM)) {
       suppressIEnd = true;
     }
   }
 
   LogicalRect contentArea = mContentArea;
-  const nscoord scrollAdjust = mAdjustForPixelSnapping ?
-    mBlock->PresContext()->AppUnitsPerDevPixel() : 0;
-  InflateIStart(mBlockWM, &contentArea, scrollAdjust);
-  InflateIEnd(mBlockWM, &contentArea, scrollAdjust);
+  bool snapStart = true, snapEnd = true;
+  // Save the non-snapped area since that's what we want to use when placing
+  // the markers (our return value).  The snapped area is only for analysis.
+  LogicalRect nonSnappedContentArea = contentArea;
+  if (mAdjustForPixelSnapping) {
+    const nscoord scrollAdjust = mBlock->PresContext()->AppUnitsPerDevPixel();
+    if (snapStart) {
+      InflateIStart(mBlockWM, &contentArea, scrollAdjust);
+    }
+    if (snapEnd) {
+      InflateIEnd(mBlockWM, &contentArea, scrollAdjust);
+    }
+  }
+
   LogicalRect lineRect(mBlockWM, aLine->GetScrollableOverflowArea(),
                        mBlockSize);
   const bool istartOverflow =
     !suppressIStart && lineRect.IStart(mBlockWM) < contentArea.IStart(mBlockWM);
   const bool iendOverflow =
     !suppressIEnd && lineRect.IEnd(mBlockWM) > contentArea.IEnd(mBlockWM);
   if (!istartOverflow && !iendOverflow) {
     // The line does not overflow on a side we should ellipsize.
-    return;
+    return nonSnappedContentArea;
   }
 
   int pass = 0;
   bool retryEmptyLine = true;
   bool guessIStart = istartOverflow;
   bool guessIEnd = iendOverflow;
   mIStart.mActive = istartOverflow;
   mIEnd.mActive = iendOverflow;
@@ -527,17 +537,17 @@ TextOverflow::ExamineLineFrames(nsLineBo
     nscoord iendMarkerISize = mIEnd.mActive ? mIEnd.mISize : 0;
     if (istartMarkerISize && iendMarkerISize &&
         istartMarkerISize + iendMarkerISize > contentArea.ISize(mBlockWM)) {
       istartMarkerISize = 0;
     }
 
     // Calculate the area between the potential markers aligned at the
     // block's edge.
-    LogicalRect insideMarkersArea = mContentArea;
+    LogicalRect insideMarkersArea = nonSnappedContentArea;
     if (guessIStart) {
       InflateIStart(mBlockWM, &insideMarkersArea, -istartMarkerISize);
     }
     if (guessIEnd) {
       InflateIEnd(mBlockWM, &insideMarkersArea, -iendMarkerISize);
     }
 
     // Analyze the frames on aLine for the overflow situation at the content
@@ -553,31 +563,32 @@ TextOverflow::ExamineLineFrames(nsLineBo
                           &clippedMarkerEdges);
     }
     if (!foundVisibleTextOrAtomic && retryEmptyLine) {
       aAlignmentEdges->mAssigned = false;
       aFramesToHide->Clear();
       pass = -1;
       if (mIStart.IsNeeded() && mIStart.mActive && !clippedIStartMarker) {
         if (clippedMarkerEdges.mAssignedIStart &&
-            clippedMarkerEdges.mIStart > mContentArea.IStart(mBlockWM)) {
-          mIStart.mISize =
-            clippedMarkerEdges.mIStart - mContentArea.IStart(mBlockWM);
+            clippedMarkerEdges.mIStart > nonSnappedContentArea.IStart(mBlockWM)) {
+          mIStart.mISize = clippedMarkerEdges.mIStart -
+                           nonSnappedContentArea.IStart(mBlockWM);
           NS_ASSERTION(mIStart.mISize < mIStart.mIntrinsicISize,
                       "clipping a marker should make it strictly smaller");
           clippedIStartMarker = true;
         } else {
           mIStart.mActive = guessIStart = false;
         }
         continue;
       }
       if (mIEnd.IsNeeded() && mIEnd.mActive && !clippedIEndMarker) {
         if (clippedMarkerEdges.mAssignedIEnd &&
-            mContentArea.IEnd(mBlockWM) > clippedMarkerEdges.mIEnd) {
-          mIEnd.mISize = mContentArea.IEnd(mBlockWM) - clippedMarkerEdges.mIEnd;
+            nonSnappedContentArea.IEnd(mBlockWM) > clippedMarkerEdges.mIEnd) {
+          mIEnd.mISize = nonSnappedContentArea.IEnd(mBlockWM) -
+                         clippedMarkerEdges.mIEnd;
           NS_ASSERTION(mIEnd.mISize < mIEnd.mIntrinsicISize,
                       "clipping a marker should make it strictly smaller");
           clippedIEndMarker = true;
         } else {
           mIEnd.mActive = guessIEnd = false;
         }
         continue;
       }
@@ -603,50 +614,52 @@ TextOverflow::ExamineLineFrames(nsLineBo
     NS_ASSERTION(pass == 0, "2nd pass should never guess wrong");
   } while (++pass != 2);
   if (!istartOverflow || !mIStart.mActive) {
     mIStart.Reset();
   }
   if (!iendOverflow || !mIEnd.mActive) {
     mIEnd.Reset();
   }
+  return nonSnappedContentArea;
 }
 
 void
 TextOverflow::ProcessLine(const nsDisplayListSet& aLists,
                           nsLineBox*              aLine)
 {
   NS_ASSERTION(mIStart.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
                mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP,
                "TextOverflow with 'clip' for both sides");
   mIStart.Reset();
   mIStart.mActive = mIStart.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP;
   mIEnd.Reset();
   mIEnd.mActive = mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP;
 
   FrameHashtable framesToHide(64);
   AlignmentEdges alignmentEdges;
-  ExamineLineFrames(aLine, &framesToHide, &alignmentEdges);
+  const LogicalRect contentArea =
+    ExamineLineFrames(aLine, &framesToHide, &alignmentEdges);
   bool needIStart = mIStart.IsNeeded();
   bool needIEnd = mIEnd.IsNeeded();
   if (!needIStart && !needIEnd) {
     return;
   }
   NS_ASSERTION(mIStart.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
                !needIStart, "left marker for 'clip'");
   NS_ASSERTION(mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
                !needIEnd, "right marker for 'clip'");
 
   // If there is insufficient space for both markers then keep the one on the
   // end side per the block's 'direction'.
   if (needIStart && needIEnd &&
-      mIStart.mISize + mIEnd.mISize > mContentArea.ISize(mBlockWM)) {
+      mIStart.mISize + mIEnd.mISize > contentArea.ISize(mBlockWM)) {
     needIStart = false;
   }
-  LogicalRect insideMarkersArea = mContentArea;
+  LogicalRect insideMarkersArea = contentArea;
   if (needIStart) {
     InflateIStart(mBlockWM, &insideMarkersArea, -mIStart.mISize);
   }
   if (needIEnd) {
     InflateIEnd(mBlockWM, &insideMarkersArea, -mIEnd.mISize);
   }
   if (!mCanHaveInlineAxisScrollbar && alignmentEdges.mAssigned) {
     LogicalRect alignmentRect(mBlockWM, alignmentEdges.mIStart,
@@ -655,17 +668,17 @@ TextOverflow::ProcessLine(const nsDispla
     insideMarkersArea.IntersectRect(insideMarkersArea, alignmentRect);
   }
 
   // Clip and remove display items as needed at the final marker edges.
   nsDisplayList* lists[] = { aLists.Content(), aLists.PositionedDescendants() };
   for (uint32_t i = 0; i < ArrayLength(lists); ++i) {
     PruneDisplayListContents(lists[i], framesToHide, insideMarkersArea);
   }
-  CreateMarkers(aLine, needIStart, needIEnd, insideMarkersArea);
+  CreateMarkers(aLine, needIStart, needIEnd, insideMarkersArea, contentArea);
 }
 
 void
 TextOverflow::PruneDisplayListContents(nsDisplayList* aList,
                                        const FrameHashtable& aFramesToHide,
                                        const LogicalRect& aInsideMarkersArea)
 {
   nsDisplayList saved;
@@ -749,45 +762,46 @@ TextOverflow::CanHaveTextOverflow(nsIFra
     }
   }
   return true;
 }
 
 void
 TextOverflow::CreateMarkers(const nsLineBox* aLine,
                             bool aCreateIStart, bool aCreateIEnd,
-                            const mozilla::LogicalRect& aInsideMarkersArea)
+                            const LogicalRect& aInsideMarkersArea,
+                            const LogicalRect& aContentArea)
 {
   if (aCreateIStart) {
     DisplayListClipState::AutoSaveRestore clipState(mBuilder);
 
     LogicalRect markerLogicalRect(
       mBlockWM, aInsideMarkersArea.IStart(mBlockWM) - mIStart.mIntrinsicISize,
       aLine->BStart(), mIStart.mIntrinsicISize, aLine->BSize());
     nsPoint offset = mBuilder->ToReferenceFrame(mBlock);
     nsRect markerRect =
       markerLogicalRect.GetPhysicalRect(mBlockWM, mBlockSize) + offset;
-    ClipMarker(mContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
+    ClipMarker(aContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
                markerRect, clipState);
     nsDisplayItem* marker = new (mBuilder)
       nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
                                   aLine->GetLogicalAscent(), mIStart.mStyle, 0);
     mMarkerList.AppendNewToTop(marker);
   }
 
   if (aCreateIEnd) {
     DisplayListClipState::AutoSaveRestore clipState(mBuilder);
 
     LogicalRect markerLogicalRect(
       mBlockWM, aInsideMarkersArea.IEnd(mBlockWM), aLine->BStart(),
       mIEnd.mIntrinsicISize, aLine->BSize());
     nsPoint offset = mBuilder->ToReferenceFrame(mBlock);
     nsRect markerRect =
       markerLogicalRect.GetPhysicalRect(mBlockWM, mBlockSize) + offset;
-    ClipMarker(mContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
+    ClipMarker(aContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
                markerRect, clipState);
     nsDisplayItem* marker = new (mBuilder)
       nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
                                   aLine->GetLogicalAscent(), mIEnd.mStyle, 1);
     mMarkerList.AppendNewToTop(marker);
   }
 }
 
--- a/layout/generic/TextOverflow.h
+++ b/layout/generic/TextOverflow.h
@@ -121,20 +121,22 @@ class TextOverflow {
   /**
    * Examines frames on the line to determine whether we should draw a left
    * and/or right marker, and if so, which frames should be completely hidden
    * and the bounds of what will be displayed between the markers.
    * @param aLine the line we're processing
    * @param aFramesToHide frames that should have their display items removed
    * @param aAlignmentEdges the outermost edges of all text and atomic
    *   inline-level frames that are inside the area between the markers
+   * @return the area inside which we should add any markers;
+   *   this is the block's content area.
    */
-  void ExamineLineFrames(nsLineBox*      aLine,
-                         FrameHashtable* aFramesToHide,
-                         AlignmentEdges* aAlignmentEdges);
+  LogicalRect ExamineLineFrames(nsLineBox*      aLine,
+                                FrameHashtable* aFramesToHide,
+                                AlignmentEdges* aAlignmentEdges);
 
   /**
    * LineHasOverflowingText calls this to analyze edges, both the block's
    * content edges and the hypothetical marker edges aligned at the block edges.
    * @param aFrame the descendant frame of mBlock that we're analyzing
    * @param aContentArea the block's content area
    * @param aInsideMarkersArea the rectangle between the markers
    * @param aFramesToHide frames that should have their display items removed
@@ -193,20 +195,23 @@ class TextOverflow {
 
   /**
    * ProcessLine calls this to create display items for the markers and insert
    * them into mMarkerList.
    * @param aLine the line we're processing
    * @param aCreateIStart if true, create a marker on the inline start side
    * @param aCreateIEnd if true, create a marker on the inline end side
    * @param aInsideMarkersArea is the area inside the markers
+   * @param aContentArea is the area inside which we should add the markers;
+   *   this is the block's content area.
    */
   void CreateMarkers(const nsLineBox* aLine,
                      bool aCreateIStart, bool aCreateIEnd,
-                     const LogicalRect& aInsideMarkersArea);
+                     const LogicalRect& aInsideMarkersArea,
+                     const LogicalRect& aContentArea);
 
   LogicalRect            mContentArea;
   nsDisplayListBuilder*  mBuilder;
   nsIFrame*              mBlock;
   nsIScrollableFrame*    mScrollableFrame;
   nsDisplayList          mMarkerList;
   nsSize                 mBlockSize;
   WritingMode            mBlockWM;