Skip to content

Commit

Permalink
Stop processing multiline text after maxLines. (flutter#3342)
Browse files Browse the repository at this point in the history
Added a Paragraph.didExceedMaxLines property to query when this occurs.

Needed for flutter/flutter#7271
  • Loading branch information
mpcomplete authored Jan 18, 2017
1 parent e573c6b commit 2efc78c
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 3 deletions.
6 changes: 5 additions & 1 deletion lib/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -693,9 +693,13 @@ abstract class Paragraph extends NativeFieldWrapperClass2 {
double get alphabeticBaseline native "Paragraph_alphabeticBaseline";

/// The distance from the top of the paragraph to the ideographic
/// baseline of the first line, in logical pixels.
/// baseline of the first line, in logical pixels.
double get ideographicBaseline native "Paragraph_ideographicBaseline";

/// True if there is more vertical content, but the text was truncated
/// because we reached [ParagraphStyle.maxLines] lines of text.
bool get didExceedMaxLines native "Paragraph_didExceedMaxLines";

/// Computes the size and position of each glyph in the paragraph.
void layout(ParagraphConstraints constraints) => _layout(constraints.width);
void _layout(double width) native "Paragraph_layout";
Expand Down
9 changes: 9 additions & 0 deletions lib/ui/text/paragraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "flutter/common/threads.h"
#include "flutter/sky/engine/core/rendering/PaintInfo.h"
#include "flutter/sky/engine/core/rendering/RenderText.h"
#include "flutter/sky/engine/core/rendering/RenderParagraph.h"
#include "flutter/sky/engine/core/rendering/style/RenderStyle.h"
#include "flutter/sky/engine/platform/fonts/FontCache.h"
#include "flutter/sky/engine/platform/graphics/GraphicsContext.h"
Expand All @@ -30,6 +31,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
V(Paragraph, maxIntrinsicWidth) \
V(Paragraph, alphabeticBaseline) \
V(Paragraph, ideographicBaseline) \
V(Paragraph, didExceedMaxLines) \
V(Paragraph, layout) \
V(Paragraph, paint) \
V(Paragraph, getWordBoundary) \
Expand Down Expand Up @@ -75,6 +77,13 @@ double Paragraph::ideographicBaseline() {
FontBaselineOrAuto(IdeographicBaseline));
}

bool Paragraph::didExceedMaxLines() {
RenderBox* box = firstChildBox();
ASSERT(box->isRenderParagraph());
RenderParagraph* paragraph = static_cast<RenderParagraph*>(box);
return paragraph->didExceedMaxLines();
}

void Paragraph::layout(double width) {
FontCachePurgePreventer fontCachePurgePreventer;

Expand Down
1 change: 1 addition & 0 deletions lib/ui/text/paragraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Paragraph : public ftl::RefCountedThreadSafe<Paragraph>,
double maxIntrinsicWidth();
double alphabeticBaseline();
double ideographicBaseline();
bool didExceedMaxLines();

void layout(double width);
void paint(Canvas* canvas, double x, double y);
Expand Down
8 changes: 6 additions & 2 deletions sky/engine/core/rendering/RenderParagraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace blink {
using namespace WTF::Unicode;

RenderParagraph::RenderParagraph()
: m_didExceedMaxLines(false)
{
}

Expand Down Expand Up @@ -855,9 +856,10 @@ void RenderParagraph::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,
bool checkForEndLineMatch = layoutState.endLine();
RenderTextInfo renderTextInfo;
VerticalPositionCache verticalPositionCache;

LineBreaker lineBreaker(this);

m_didExceedMaxLines = false;

while (!endOfLine.atEnd()) {
// FIXME: Is this check necessary before the first iteration or can it be moved to the end?
if (checkForEndLineMatch) {
Expand All @@ -880,7 +882,8 @@ void RenderParagraph::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,
endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo,
lastFloatFromPreviousLine, wordMeasurements);
renderTextInfo.m_lineBreakIterator.resetPriorContext();
if (resolver.position().atEnd()) {
m_didExceedMaxLines = layoutState.lineInfo().lineIndex() > styleToUse->maxLines() && !layoutState.lineInfo().isEmpty();
if (resolver.position().atEnd() || m_didExceedMaxLines) {
// FIXME: We shouldn't be creating any runs in nextLineBreak to begin with!
// Once BidiRunList is separated from BidiResolver this will not be needed.
resolver.runs().deleteRuns();
Expand Down Expand Up @@ -934,6 +937,7 @@ void RenderParagraph::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,

// Limit ellipsized text to a single line.
if (lineBreaker.lineWasEllipsized()) {
m_didExceedMaxLines = true;
resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
break;
}
Expand Down
4 changes: 4 additions & 0 deletions sky/engine/core/rendering/RenderParagraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class RenderParagraph final : public RenderBlock {
return obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline();
}

bool didExceedMaxLines() const { return m_didExceedMaxLines; }

// TODO(ojan): Remove the need for these.
using RenderBlock::lineBoxes;
using RenderBlock::firstLineBox;
Expand Down Expand Up @@ -103,6 +105,8 @@ class RenderParagraph final : public RenderBlock {
void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);

bool m_didExceedMaxLines;
};

DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderParagraph, isRenderParagraph());
Expand Down

0 comments on commit 2efc78c

Please sign in to comment.