--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -7216,168 +7216,168 @@ nsTextFrame::DrawTextRun(Range aRange, c
}
void
nsTextFrame::DrawTextRunAndDecorations(Range aRange,
const gfxPoint& aTextBaselinePt,
const DrawTextParams& aParams,
const TextDecorations& aDecorations)
{
- const gfxFloat app =
- aParams.textStyle->PresContext()->AppUnitsPerDevPixel();
- // Writing mode of parent frame is used because the text frame may
- // be orthogonal to its parent when text-combine-upright is used or
- // its parent has "display: contents", and in those cases, we want
- // to draw the decoration lines according to parents' direction
- // rather than ours.
- const WritingMode wm = GetParent()->GetWritingMode();
- bool verticalDec = wm.IsVertical();
- bool verticalRun = mTextRun->IsVertical();
- // If the text run and the decoration is orthogonal, we choose the
- // metrics for decoration so that decoration line won't be broken.
- bool useVerticalMetrics = verticalDec != verticalRun
- ? verticalDec : verticalRun && mTextRun->UseCenterBaseline();
-
- // XXX aFramePt is in AppUnits, shouldn't it be nsFloatPoint?
- nscoord x = NSToCoordRound(aParams.framePt.x);
- nscoord y = NSToCoordRound(aParams.framePt.y);
-
- // 'measure' here is textrun-relative, so for a horizontal run it's the
- // width, while for a vertical run it's the height of the decoration
- const nsSize frameSize = GetSize();
- nscoord measure = verticalDec ? frameSize.height : frameSize.width;
-
- if (verticalDec) {
- aParams.clipEdges->Intersect(&y, &measure);
- } else {
- aParams.clipEdges->Intersect(&x, &measure);
- }
-
- // decSize is a textrun-relative size, so its 'width' field is actually
- // the run-relative measure, and 'height' will be the line thickness
- gfxFloat ascent = gfxFloat(GetLogicalBaseline(wm)) / app;
- // The starting edge of the frame in block direction
- gfxFloat frameBStart = verticalDec ? aParams.framePt.x : aParams.framePt.y;
-
- // In vertical-rl mode, block coordinates are measured from the
- // right, so we need to adjust here.
- if (wm.IsVerticalRL()) {
- frameBStart += frameSize.width;
- ascent = -ascent;
- }
-
- nscoord inflationMinFontSize =
- nsLayoutUtils::InflationMinFontSizeFor(this);
-
- // The decoration-line offsets need to be reversed for sideways-lr mode,
- // so we will multiply the values from metrics by this factor.
- gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0;
-
- PaintDecorationLineParams params;
- params.context = aParams.context;
- params.dirtyRect = aParams.dirtyRect;
- params.overrideColor = aParams.decorationOverrideColor;
- params.callbacks = aParams.callbacks;
- // pt is the physical point where the decoration is to be drawn,
- // relative to the frame; one of its coordinates will be updated below.
- params.pt = Point(x / app, y / app);
- Float& bCoord = verticalDec ? params.pt.x : params.pt.y;
- params.lineSize = Size(measure / app, 0);
- params.ascent = ascent;
- params.vertical = verticalDec;
-
- // The matrix of the context may have been altered for text-combine-
- // upright. However, we want to draw decoration lines unscaled, thus
- // we need to revert the scaling here.
- gfxContextMatrixAutoSaveRestore scaledRestorer;
- if (StyleContext()->IsTextCombined()) {
- float scaleFactor = GetTextCombineScaleFactor(this);
- if (scaleFactor != 1.0f) {
- scaledRestorer.SetContext(aParams.context);
- gfxMatrix unscaled = aParams.context->CurrentMatrix();
- gfxPoint pt(x / app, y / app);
- unscaled.PreTranslate(pt).PreScale(1.0f / scaleFactor, 1.0f).PreTranslate(-pt);
- aParams.context->SetMatrix(unscaled);
- }
- }
-
- typedef gfxFont::Metrics Metrics;
- auto paintDecorationLine = [&](const LineDecoration& dec,
- gfxFloat Metrics::* lineSize,
- gfxFloat Metrics::* lineOffset) {
- if (dec.mStyle == NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
- return;
- }
-
- float inflation =
- GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
- const Metrics metrics =
- GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
- useVerticalMetrics);
-
- params.lineSize.height = metrics.*lineSize;
- bCoord = (frameBStart - dec.mBaselineOffset) / app;
-
- params.color = dec.mColor;
- params.offset = decorationOffsetDir * metrics.*lineOffset;
- params.style = dec.mStyle;
- PaintDecorationLine(params);
- };
-
- auto* textDrawer = aParams.context->GetTextDrawer();
-
- // Underlines
- if (textDrawer && aDecorations.mUnderlines.Length() > 0) {
- textDrawer->StartDrawing(TextDrawTarget::Phase::eUnderline);
- }
- //
- params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
- for (const LineDecoration& dec : Reversed(aDecorations.mUnderlines)) {
- paintDecorationLine(dec, &Metrics::underlineSize,
- &Metrics::underlineOffset);
- }
-
- // Overlines
- if (textDrawer && aDecorations.mOverlines.Length() > 0) {
- textDrawer->StartDrawing(TextDrawTarget::Phase::eOverline);
- }
- params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
- for (const LineDecoration& dec : Reversed(aDecorations.mOverlines)) {
- paintDecorationLine(dec, &Metrics::underlineSize, &Metrics::maxAscent);
- }
-
- {
- gfxContextMatrixAutoSaveRestore unscaledRestorer;
- if (scaledRestorer.HasMatrix()) {
- unscaledRestorer.SetContext(aParams.context);
- aParams.context->SetMatrix(scaledRestorer.Matrix());
- }
-
- // CSS 2.1 mandates that text be painted after over/underlines,
- // and *then* line-throughs
- DrawTextRun(aRange, aTextBaselinePt, aParams);
- }
-
- // Emphasis marks
- if (textDrawer) {
- textDrawer->StartDrawing(TextDrawTarget::Phase::eEmphasisMarks);
- }
- DrawEmphasisMarks(aParams.context, wm,
- aTextBaselinePt, aParams.framePt, aRange,
- aParams.decorationOverrideColor, aParams.provider);
-
- // Line-throughs
- if (textDrawer && aDecorations.mStrikes.Length() > 0) {
- textDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
- }
- params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
- for (const LineDecoration& dec : Reversed(aDecorations.mStrikes)) {
- paintDecorationLine(dec, &Metrics::strikeoutSize,
- &Metrics::strikeoutOffset);
- }
+ const gfxFloat app =
+ aParams.textStyle->PresContext()->AppUnitsPerDevPixel();
+ // Writing mode of parent frame is used because the text frame may
+ // be orthogonal to its parent when text-combine-upright is used or
+ // its parent has "display: contents", and in those cases, we want
+ // to draw the decoration lines according to parents' direction
+ // rather than ours.
+ const WritingMode wm = GetParent()->GetWritingMode();
+ bool verticalDec = wm.IsVertical();
+ bool verticalRun = mTextRun->IsVertical();
+ // If the text run and the decoration is orthogonal, we choose the
+ // metrics for decoration so that decoration line won't be broken.
+ bool useVerticalMetrics =
+ verticalDec != verticalRun ? verticalDec
+ : verticalRun && mTextRun->UseCenterBaseline();
+
+ // XXX aFramePt is in AppUnits, shouldn't it be nsFloatPoint?
+ nscoord x = NSToCoordRound(aParams.framePt.x);
+ nscoord y = NSToCoordRound(aParams.framePt.y);
+
+ // 'measure' here is textrun-relative, so for a horizontal run it's the
+ // width, while for a vertical run it's the height of the decoration
+ const nsSize frameSize = GetSize();
+ nscoord measure = verticalDec ? frameSize.height : frameSize.width;
+
+ if (verticalDec) {
+ aParams.clipEdges->Intersect(&y, &measure);
+ } else {
+ aParams.clipEdges->Intersect(&x, &measure);
+ }
+
+ // decSize is a textrun-relative size, so its 'width' field is actually
+ // the run-relative measure, and 'height' will be the line thickness
+ gfxFloat ascent = gfxFloat(GetLogicalBaseline(wm)) / app;
+ // The starting edge of the frame in block direction
+ gfxFloat frameBStart = verticalDec ? aParams.framePt.x : aParams.framePt.y;
+
+ // In vertical-rl mode, block coordinates are measured from the
+ // right, so we need to adjust here.
+ if (wm.IsVerticalRL()) {
+ frameBStart += frameSize.width;
+ ascent = -ascent;
+ }
+
+ nscoord inflationMinFontSize = nsLayoutUtils::InflationMinFontSizeFor(this);
+
+ // The decoration-line offsets need to be reversed for sideways-lr mode,
+ // so we will multiply the values from metrics by this factor.
+ gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0;
+
+ PaintDecorationLineParams params;
+ params.context = aParams.context;
+ params.dirtyRect = aParams.dirtyRect;
+ params.overrideColor = aParams.decorationOverrideColor;
+ params.callbacks = aParams.callbacks;
+ // pt is the physical point where the decoration is to be drawn,
+ // relative to the frame; one of its coordinates will be updated below.
+ params.pt = Point(x / app, y / app);
+ Float& bCoord = verticalDec ? params.pt.x : params.pt.y;
+ params.lineSize = Size(measure / app, 0);
+ params.ascent = ascent;
+ params.vertical = verticalDec;
+
+ // The matrix of the context may have been altered for text-combine-
+ // upright. However, we want to draw decoration lines unscaled, thus
+ // we need to revert the scaling here.
+ gfxContextMatrixAutoSaveRestore scaledRestorer;
+ if (StyleContext()->IsTextCombined()) {
+ float scaleFactor = GetTextCombineScaleFactor(this);
+ if (scaleFactor != 1.0f) {
+ scaledRestorer.SetContext(aParams.context);
+ gfxMatrix unscaled = aParams.context->CurrentMatrix();
+ gfxPoint pt(x / app, y / app);
+ unscaled.PreTranslate(pt).PreScale(1.0f / scaleFactor, 1.0f).PreTranslate(-pt);
+ aParams.context->SetMatrix(unscaled);
+ }
+ }
+
+ typedef gfxFont::Metrics Metrics;
+ auto paintDecorationLine = [&](const LineDecoration& dec,
+ gfxFloat Metrics::* lineSize,
+ gfxFloat Metrics::* lineOffset) {
+ if (dec.mStyle == NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
+ return;
+ }
+
+ float inflation =
+ GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
+ const Metrics metrics =
+ GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
+ useVerticalMetrics);
+
+ params.lineSize.height = metrics.*lineSize;
+ bCoord = (frameBStart - dec.mBaselineOffset) / app;
+
+ params.color = dec.mColor;
+ params.offset = decorationOffsetDir * metrics.*lineOffset;
+ params.style = dec.mStyle;
+ PaintDecorationLine(params);
+ };
+
+ auto* textDrawer = aParams.context->GetTextDrawer();
+
+ // Underlines
+ if (textDrawer && aDecorations.mUnderlines.Length() > 0) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eUnderline);
+ }
+ //
+ params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
+ for (const LineDecoration& dec : Reversed(aDecorations.mUnderlines)) {
+ paintDecorationLine(dec, &Metrics::underlineSize,
+ &Metrics::underlineOffset);
+ }
+
+ // Overlines
+ if (textDrawer && aDecorations.mOverlines.Length() > 0) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eOverline);
+ }
+ params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
+ for (const LineDecoration& dec : Reversed(aDecorations.mOverlines)) {
+ paintDecorationLine(dec, &Metrics::underlineSize, &Metrics::maxAscent);
+ }
+
+ {
+ gfxContextMatrixAutoSaveRestore unscaledRestorer;
+ if (scaledRestorer.HasMatrix()) {
+ unscaledRestorer.SetContext(aParams.context);
+ aParams.context->SetMatrix(scaledRestorer.Matrix());
+ }
+
+ // CSS 2.1 mandates that text be painted after over/underlines,
+ // and *then* line-throughs
+ DrawTextRun(aRange, aTextBaselinePt, aParams);
+ }
+
+ // Emphasis marks
+ if (textDrawer) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eEmphasisMarks);
+ }
+ DrawEmphasisMarks(aParams.context, wm,
+ aTextBaselinePt, aParams.framePt, aRange,
+ aParams.decorationOverrideColor, aParams.provider);
+
+ // Line-throughs
+ if (textDrawer && aDecorations.mStrikes.Length() > 0) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
+ }
+ params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
+ for (const LineDecoration& dec : Reversed(aDecorations.mStrikes)) {
+ paintDecorationLine(dec, &Metrics::strikeoutSize,
+ &Metrics::strikeoutOffset);
+ }
}
void
nsTextFrame::DrawText(Range aRange, const gfxPoint& aTextBaselinePt,
const DrawTextParams& aParams)
{
TextDecorations decorations;
GetTextDecorations(aParams.textStyle->PresContext(),