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 draft
authorMats Palmgren <mats@mozilla.com>
Wed, 12 Apr 2017 15:38:04 +0200
changeset 561349 3d37b26ec21a118a3cbfcbd11a5bdfc4025c4eeb
parent 560729 cc3c4e5a9bc4174ef02730d25935876ffcac08b6
child 561350 f48d62f4144b1d07039115e63f85cefd316e5fd0
push id53707
push usermpalmgren@mozilla.com
push dateWed, 12 Apr 2017 15:19:40 +0000
reviewersdholbert
bugs944200
milestone55.0a1
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: EDz06S3ZyoN
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;