Bug 1355531: Represent temporary TextOverflow instances using Maybe instead of UniquePtr. r?mats
(This means we'll be storing it on the stack instead of the heap.)
MozReview-Commit-ID: IsIn2BlpHIu
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -316,31 +316,33 @@ TextOverflow::TextOverflow(nsDisplayList
} else {
mIStart.Init(style->mTextOverflow.GetRight(direction));
mIEnd.Init(style->mTextOverflow.GetLeft(direction));
}
// The left/right marker string is setup in ExamineLineFrames when a line
// has overflow on that side.
}
-/* static */ TextOverflow*
+/* static */ Maybe<TextOverflow>
TextOverflow::WillProcessLines(nsDisplayListBuilder* aBuilder,
nsIFrame* aBlockFrame)
{
+ Maybe<TextOverflow> textOverflow;
if (aBuilder->IsForEventDelivery() ||
aBuilder->IsForFrameVisibility() ||
!CanHaveTextOverflow(aBlockFrame)) {
- return nullptr;
+ return textOverflow; // Nothing()
}
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(aBlockFrame);
if (scrollableFrame && scrollableFrame->IsTransformingByAPZ()) {
// If the APZ is actively scrolling this, don't bother with markers.
- return nullptr;
+ return textOverflow; // Nothing()
}
- return new TextOverflow(aBuilder, aBlockFrame);
+ textOverflow.emplace(aBuilder, aBlockFrame);
+ return textOverflow;
}
void
TextOverflow::ExamineFrameSubtree(nsIFrame* aFrame,
const LogicalRect& aContentArea,
const LogicalRect& aInsideMarkersArea,
FrameHashtable* aFramesToHide,
AlignmentEdges* aAlignmentEdges,
--- a/layout/generic/TextOverflow.h
+++ b/layout/generic/TextOverflow.h
@@ -5,39 +5,45 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TextOverflow_h_
#define TextOverflow_h_
#include "nsDisplayList.h"
#include "nsTHashtable.h"
#include "mozilla/Likely.h"
+#include "mozilla/Maybe.h"
#include "mozilla/WritingModes.h"
#include <algorithm>
class nsIScrollableFrame;
class nsLineBox;
namespace mozilla {
namespace css {
/**
* A class for rendering CSS3 text-overflow.
* Usage:
* 1. allocate an object using WillProcessLines
* 2. then call ProcessLine for each line you are building display lists for
*/
-class TextOverflow {
+class MOZ_STACK_CLASS TextOverflow {
public:
+ // Do not instantiate directly; use WillProcessLines() instead.
+ TextOverflow(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aBlockFrame);
+
/**
- * Allocate an object for text-overflow processing.
- * @return nullptr if no processing is necessary. The caller owns the object.
+ * Instantiate an object for text-overflow processing.
+ * @return a TextOverflow object, or Nothing() if no processing is necessary.
*/
- static TextOverflow* WillProcessLines(nsDisplayListBuilder* aBuilder,
- nsIFrame* aBlockFrame);
+ static Maybe<TextOverflow> WillProcessLines(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aBlockFrame);
+
/**
* Analyze the display lists for text overflow and what kind of item is at
* the content edges. Add display items for text-overflow markers as needed
* and remove or clip items that would overlap a marker.
*/
void ProcessLine(const nsDisplayListSet& aLists, nsLineBox* aLine);
/**
@@ -53,19 +59,16 @@ class TextOverflow {
/**
* @return true if aBlockFrame needs analysis for text overflow.
*/
static bool CanHaveTextOverflow(nsIFrame* aBlockFrame);
typedef nsTHashtable<nsPtrHashKey<nsIFrame> > FrameHashtable;
protected:
- TextOverflow(nsDisplayListBuilder* aBuilder,
- nsIFrame* aBlockFrame);
-
typedef mozilla::WritingMode WritingMode;
typedef mozilla::LogicalRect LogicalRect;
struct AlignmentEdges {
AlignmentEdges() : mAssigned(false) {}
void Accumulate(WritingMode aWM, const LogicalRect& aRect)
{
if (MOZ_LIKELY(mAssigned)) {
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6558,17 +6558,17 @@ static void DebugOutputDrawLine(int32_t
}
}
#endif
static void
DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea,
const nsRect& aDirtyRect, nsBlockFrame::LineIterator& aLine,
int32_t aDepth, int32_t& aDrawnLines, const nsDisplayListSet& aLists,
- nsBlockFrame* aFrame, TextOverflow* aTextOverflow) {
+ nsBlockFrame* aFrame, Maybe<TextOverflow>& aTextOverflow) {
// If the line's combined area (which includes child frames that
// stick outside of the line's bounding box or our bounding box)
// intersects the dirty rect then paint the line.
bool intersect = aLineArea.Intersects(aDirtyRect);
#ifdef DEBUG
if (nsBlockFrame::gLamePaintMetrics) {
aDrawnLines++;
}
@@ -6648,18 +6648,18 @@ nsBlockFrame::BuildDisplayList(nsDisplay
if (f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT)
BuildDisplayListForChild(aBuilder, f, aDirtyRect, aLists);
}
}
aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect);
// Prepare for text-overflow processing.
- UniquePtr<TextOverflow> textOverflow(
- TextOverflow::WillProcessLines(aBuilder, this));
+ Maybe<TextOverflow> textOverflow = TextOverflow::WillProcessLines(aBuilder,
+ this);
// We'll collect our lines' display items here, & then append this to aLists.
nsDisplayListCollection linesDisplayListCollection;
// Don't use the line cursor if we might have a descendant placeholder ...
// it might skip lines that contain placeholders but don't themselves
// intersect with the dirty area.
// In particular, we really want to check ShouldDescendIntoFrame()
@@ -6677,30 +6677,30 @@ nsBlockFrame::BuildDisplayList(nsDisplay
nsRect lineArea = line->GetVisualOverflowArea();
if (!lineArea.IsEmpty()) {
// Because we have a cursor, the combinedArea.ys are non-decreasing.
// Once we've passed aDirtyRect.YMost(), we can never see it again.
if (lineArea.y >= aDirtyRect.YMost()) {
break;
}
DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines,
- linesDisplayListCollection, this, textOverflow.get());
+ linesDisplayListCollection, this, textOverflow);
}
}
} else {
bool nonDecreasingYs = true;
int32_t lineCount = 0;
nscoord lastY = INT32_MIN;
nscoord lastYMost = INT32_MIN;
for (LineIterator line = LinesBegin();
line != line_end;
++line) {
nsRect lineArea = line->GetVisualOverflowArea();
DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines,
- linesDisplayListCollection, this, textOverflow.get());
+ linesDisplayListCollection, this, textOverflow);
if (!lineArea.IsEmpty()) {
if (lineArea.y < lastY
|| lineArea.YMost() < lastYMost) {
nonDecreasingYs = false;
}
lastY = lineArea.y;
lastYMost = lineArea.YMost();
}