Skip to content

Commit

Permalink
Bug 1399310 - (Part 1) Make nsTextFrame::DrawTextRunAndDecorations
Browse files Browse the repository at this point in the history
…draw only in the range of the text. r=jfkthame

We create a clip region with the text length to make the decoration line
would be only drawn in the area. This allows the decoration line would
not be drawn multiple times when the text is being selected.

MozReview-Commit-ID: 4gjawk71eSu

--HG--
extra : rebase_source : 627fa77a2b6e17441d134255017762ebda92eaf6
  • Loading branch information
kuoe0 committed Sep 27, 2017
1 parent 4e6da88 commit 0943404
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions layout/generic/nsTextFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7270,6 +7270,38 @@ nsTextFrame::DrawTextRunAndDecorations(Range aRange,
PaintDecorationLine(params);
};

// We create a clip region in order to draw the decoration lines only in the
// range of the text. Restricting the draw area prevents the decoration lines
// to be drawn multiple times when a part of the text is selected.

// We skip clipping for the following cases:
// - drawing the whole text
// - having different orientation of the text and the writing-mode, such as
// "text-combine-upright" (Bug 1408825)
bool skipClipping = aRange.Length() == mTextRun->GetLength() ||
verticalDec != verticalRun;

gfxRect clipRect;
if (!skipClipping) {
// Get the inline-size according to the specified range.
gfxFloat clipLength = mTextRun->GetAdvanceWidth(aRange, aParams.provider);

clipRect.width = verticalDec ? frameSize.width : clipLength / app;
clipRect.height = verticalDec ? clipLength / app : frameSize.height;

const bool isInlineReversed = mTextRun->IsInlineReversed();
if (verticalDec) {
clipRect.y = (isInlineReversed ? aTextBaselinePt.y - clipLength
: aTextBaselinePt.y) / app;
} else {
clipRect.x = (isInlineReversed ? aTextBaselinePt.x - clipLength
: aTextBaselinePt.x) / app;
}

clipRect.Round();
params.context->Clip(clipRect);
}

// Underlines
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
for (const LineDecoration& dec : Reversed(aDecorations.mUnderlines)) {
Expand All @@ -7283,6 +7315,12 @@ nsTextFrame::DrawTextRunAndDecorations(Range aRange,
paintDecorationLine(dec, &Metrics::underlineSize, &Metrics::maxAscent);
}

// Some glyphs and emphasis marks may extend outside the region, so we reset
// the clip region here. For an example, italic glyphs.
if (!skipClipping) {
params.context->PopClip();
}

{
gfxContextMatrixAutoSaveRestore unscaledRestorer;
if (scaledRestorer.HasMatrix()) {
Expand All @@ -7300,12 +7338,21 @@ nsTextFrame::DrawTextRunAndDecorations(Range aRange,
aTextBaselinePt, aParams.framePt, aRange,
aParams.decorationOverrideColor, aParams.provider);

// Re-apply the clip region when the line-through is being drawn.
if (!skipClipping) {
params.context->Clip(clipRect);
}

// Line-throughs
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
for (const LineDecoration& dec : Reversed(aDecorations.mStrikes)) {
paintDecorationLine(dec, &Metrics::strikeoutSize,
&Metrics::strikeoutOffset);
}

if (!skipClipping) {
params.context->PopClip();
}
}

void
Expand Down

0 comments on commit 0943404

Please sign in to comment.