--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5461,54 +5461,52 @@ nsTextFrame::ComputeSelectionUnderlineHe
return ceil(fontSize / 20);
}
default:
NS_WARNING("Requested underline style is not valid");
return aFontMetrics.underlineSize;
}
}
+enum class DecorationType
+{
+ Normal, Selection
+};
+struct nsTextFrame::PaintDecorationLineParams
+ : nsCSSRendering::DecorationRectParams
+{
+ gfxContext* context = nullptr;
+ LayoutDeviceRect dirtyRect;
+ Point pt;
+ const nscolor* overrideColor = nullptr;
+ nscolor color = NS_RGBA(0, 0, 0, 0);
+ gfxFloat icoordInFrame = 0.0f;
+ DecorationType decorationType = DecorationType::Normal;
+ DrawPathCallbacks* callbacks = nullptr;
+};
+
void
-nsTextFrame::PaintDecorationLine(gfxContext* const aCtx,
- const LayoutDeviceRect& aDirtyRect,
- nscolor aColor,
- const nscolor* aOverrideColor,
- const Point& aPt,
- gfxFloat aICoordInFrame,
- const Size& aLineSize,
- gfxFloat aAscent,
- gfxFloat aOffset,
- uint8_t aDecoration,
- uint8_t aStyle,
- DecorationType aDecorationType,
- DrawPathCallbacks* aCallbacks,
- bool aVertical,
- gfxFloat aDescentLimit /* = -1.0 */)
+nsTextFrame::PaintDecorationLine(const PaintDecorationLineParams& aParams)
{
nsCSSRendering::PaintDecorationLineParams params;
- params.dirtyRect = aDirtyRect.ToUnknownRect();
- params.pt = aPt;
- params.color = aOverrideColor ? *aOverrideColor : aColor;
- params.icoordInFrame = Float(aICoordInFrame);
- params.lineSize = aLineSize;
- params.ascent = aAscent;
- params.offset = aOffset;
- params.decoration = aDecoration;
- params.style = aStyle;
- params.vertical = aVertical;
- params.descentLimit = aDescentLimit;
- if (aCallbacks) {
+ static_cast<nsCSSRendering::DecorationRectParams&>(params) = aParams;
+ params.dirtyRect = aParams.dirtyRect.ToUnknownRect();
+ params.pt = aParams.pt;
+ params.color = aParams.overrideColor ? *aParams.overrideColor : aParams.color;
+ params.icoordInFrame = Float(aParams.icoordInFrame);
+ if (aParams.callbacks) {
Rect path = nsCSSRendering::DecorationLineToPath(params);
- if (aDecorationType == eNormalDecoration) {
- aCallbacks->PaintDecorationLine(path, params.color);
+ if (aParams.decorationType == DecorationType::Normal) {
+ aParams.callbacks->PaintDecorationLine(path, params.color);
} else {
- aCallbacks->PaintSelectionDecorationLine(path, params.color);
+ aParams.callbacks->PaintSelectionDecorationLine(path, params.color);
}
} else {
- nsCSSRendering::PaintDecorationLine(this, *aCtx->GetDrawTarget(), params);
+ nsCSSRendering::PaintDecorationLine(
+ this, *aParams.context->GetDrawTarget(), params);
}
}
/**
* This, plus SelectionTypesWithDecorations, encapsulates all knowledge about
* drawing text decoration for selections.
*/
void
@@ -5522,35 +5520,42 @@ nsTextFrame::DrawSelectionDecorations(gf
gfxFloat aWidth,
gfxFloat aAscent,
const gfxFont::Metrics& aFontMetrics,
DrawPathCallbacks* aCallbacks,
bool aVertical,
gfxFloat aDecorationOffsetDir,
uint8_t aDecoration)
{
- Point pt(aPt);
- Size size(aWidth,
- ComputeSelectionUnderlineHeight(aTextPaintStyle.PresContext(),
- aFontMetrics, aType));
- gfxFloat descentLimit =
+ PaintDecorationLineParams params;
+ params.context = aContext;
+ params.dirtyRect = aDirtyRect;
+ params.pt = aPt;
+ params.lineSize = Size(
+ aWidth, ComputeSelectionUnderlineHeight(aTextPaintStyle.PresContext(),
+ aFontMetrics, aType));
+ params.ascent = aAscent;
+ gfxFloat offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
+ aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
+ params.offset = offset * aDecorationOffsetDir;
+ params.decoration = aDecoration;
+ params.decorationType = DecorationType::Selection;
+ params.callbacks = aCallbacks;
+ params.vertical = aVertical;
+ params.descentLimit =
ComputeDescentLimitForSelectionUnderline(aTextPaintStyle.PresContext(),
aFontMetrics);
float relativeSize;
- uint8_t style;
- nscolor color;
int32_t index =
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aType);
bool weDefineSelectionUnderline =
- aTextPaintStyle.GetSelectionUnderlineForPaint(index, &color,
- &relativeSize, &style);
-
- gfxFloat offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
- aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
+ aTextPaintStyle.GetSelectionUnderlineForPaint(index, ¶ms.color,
+ &relativeSize, ¶ms.style);
+
switch (aType) {
case nsISelectionController::SELECTION_IME_RAWINPUT:
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT: {
// IME decoration lines should not be drawn on the both ends, i.e., we
// need to cut both edges of the decoration lines. Because same style
@@ -5560,50 +5565,50 @@ nsTextFrame::DrawSelectionDecorations(gf
// X: underline
//
// IME selection #1 IME selection #2 IME selection #3
// | | |
// | XXXXXXXXXXXXXXXXXXX | XXXXXXXXXXXXXXXXXXXX | XXXXXXXXXXXXXXXXXXX
// +---------------------+----------------------+--------------------
// ^ ^ ^ ^ ^
// gap gap gap
- pt.x += 1.0;
- size.width -= 2.0;
+ params.pt.x += 1.0;
+ params.lineSize.width -= 2.0;
if (aRangeStyle.IsDefined()) {
// If IME defines the style, that should override our definition.
if (aRangeStyle.IsLineStyleDefined()) {
if (aRangeStyle.mLineStyle == TextRangeStyle::LINESTYLE_NONE) {
return;
}
- style = aRangeStyle.mLineStyle;
+ params.style = aRangeStyle.mLineStyle;
relativeSize = aRangeStyle.mIsBoldLine ? 2.0f : 1.0f;
} else if (!weDefineSelectionUnderline) {
// There is no underline style definition.
return;
}
// If underline color is defined and that doesn't depend on the
// foreground color, we should use the color directly.
if (aRangeStyle.IsUnderlineColorDefined() &&
(!aRangeStyle.IsForegroundColorDefined() ||
aRangeStyle.mUnderlineColor != aRangeStyle.mForegroundColor)) {
- color = aRangeStyle.mUnderlineColor;
+ params.color = aRangeStyle.mUnderlineColor;
}
// If foreground color or background color is defined, the both colors
// are computed by GetSelectionTextColors(). Then, we should use its
// foreground color always. The color should have sufficient contrast
// with the background color.
else if (aRangeStyle.IsForegroundColorDefined() ||
aRangeStyle.IsBackgroundColorDefined()) {
nscolor bg;
GetSelectionTextColors(aType, aTextPaintStyle, aRangeStyle,
- &color, &bg);
+ ¶ms.color, &bg);
}
// Otherwise, use the foreground color of the frame.
else {
- color = aTextPaintStyle.GetTextColor();
+ params.color = aTextPaintStyle.GetTextColor();
}
} else if (!weDefineSelectionUnderline) {
// IME doesn't specify the selection style and we don't define selection
// underline.
return;
}
break;
}
@@ -5623,21 +5628,20 @@ nsTextFrame::DrawSelectionDecorations(gf
offset = metrics.strikeoutOffset + 0.5;
aDecoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
break;
}
default:
NS_WARNING("Requested selection decorations when there aren't any");
return;
}
- size.height *= relativeSize;
- PaintDecorationLine(aContext, aDirtyRect, color, nullptr, pt,
- (aVertical ? (pt.y - aPt.y) : (pt.x - aPt.x)) + aICoordInFrame,
- size, aAscent, offset * aDecorationOffsetDir, aDecoration, style,
- eSelectionDecoration, aCallbacks, aVertical, descentLimit);
+ params.lineSize.height *= relativeSize;
+ params.icoordInFrame = (aVertical ? params.pt.y - aPt.y
+ : params.pt.x - aPt.x) + aICoordInFrame;
+ PaintDecorationLine(params);
}
/* static */
bool
nsTextFrame::GetSelectionTextColors(SelectionType aType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
nscolor* aForeground,
@@ -6641,24 +6645,18 @@ nsTextFrame::DrawTextRunAndDecorations(R
nscoord measure = verticalRun ? frameSize.height : frameSize.width;
if (verticalRun) {
aParams.clipEdges->Intersect(&y, &measure);
} else {
aParams.clipEdges->Intersect(&x, &measure);
}
- // decPt is the physical point where the decoration is to be drawn,
- // relative to the frame; one of its coordinates will be updated below.
- Point decPt(x / app, y / app);
- Float& bCoord = verticalRun ? decPt.x : decPt.y;
-
// decSize is a textrun-relative size, so its 'width' field is actually
// the run-relative measure, and 'height' will be the line thickness
- Size decSize(measure / app, 0);
gfxFloat ascent = gfxFloat(mAscent) / app;
// The starting edge of the frame in block direction
gfxFloat frameBStart = verticalRun ? aParams.framePt.x : aParams.framePt.y;
// In vertical-rl mode, block coordinates are measured from the right,
// so we need to adjust here.
const WritingMode wm = GetWritingMode();
@@ -6669,59 +6667,72 @@ nsTextFrame::DrawTextRunAndDecorations(R
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 = verticalRun ? params.pt.x : params.pt.y;
+ params.lineSize = Size(measure / app, 0);
+ params.ascent = ascent;
+ params.vertical = verticalRun;
+
// Underlines
for (uint32_t i = aDecorations.mUnderlines.Length(); i-- > 0; ) {
const LineDecoration& dec = aDecorations.mUnderlines[i];
if (dec.mStyle == NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
continue;
}
float inflation =
GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
const gfxFont::Metrics metrics =
GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
useVerticalMetrics);
- decSize.height = metrics.underlineSize;
+ params.lineSize.height = metrics.underlineSize;
bCoord = (frameBStart - dec.mBaselineOffset) / app;
- PaintDecorationLine(aParams.context, aParams.dirtyRect, dec.mColor,
- aParams.decorationOverrideColor, decPt, 0.0, decSize, ascent,
- decorationOffsetDir * metrics.underlineOffset,
- NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
- dec.mStyle, eNormalDecoration, aParams.callbacks, verticalRun);
+ params.color = dec.mColor;
+ params.offset = decorationOffsetDir * metrics.underlineOffset;
+ params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
+ params.style = dec.mStyle;
+ PaintDecorationLine(params);
}
// Overlines
for (uint32_t i = aDecorations.mOverlines.Length(); i-- > 0; ) {
const LineDecoration& dec = aDecorations.mOverlines[i];
if (dec.mStyle == NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
continue;
}
float inflation =
GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
const gfxFont::Metrics metrics =
GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
useVerticalMetrics);
- decSize.height = metrics.underlineSize;
+ params.lineSize.height = metrics.underlineSize;
bCoord = (frameBStart - dec.mBaselineOffset) / app;
- PaintDecorationLine(aParams.context, aParams.dirtyRect, dec.mColor,
- aParams.decorationOverrideColor, decPt, 0.0, decSize, ascent,
- decorationOffsetDir * metrics.maxAscent,
- NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle,
- eNormalDecoration, aParams.callbacks, verticalRun);
+ params.color = dec.mColor;
+ params.offset = decorationOffsetDir * metrics.maxAscent;
+ params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
+ params.style = dec.mStyle;
+ PaintDecorationLine(params);
}
// CSS 2.1 mandates that text be painted after over/underlines, and *then*
// line-throughs
DrawTextRun(aRange, aTextBaselinePt, aParams);
// Emphasis marks
DrawEmphasisMarks(aParams.context, wm, aTextBaselinePt, aRange,
@@ -6735,24 +6746,24 @@ nsTextFrame::DrawTextRunAndDecorations(R
}
float inflation =
GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
const gfxFont::Metrics metrics =
GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
useVerticalMetrics);
- decSize.height = metrics.strikeoutSize;
+ params.lineSize.height = metrics.strikeoutSize;
bCoord = (frameBStart - dec.mBaselineOffset) / app;
- PaintDecorationLine(aParams.context, aParams.dirtyRect, dec.mColor,
- aParams.decorationOverrideColor, decPt, 0.0, decSize, ascent,
- decorationOffsetDir * metrics.strikeoutOffset,
- NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
- dec.mStyle, eNormalDecoration, aParams.callbacks, verticalRun);
+ params.color = dec.mColor;
+ params.offset = decorationOffsetDir * metrics.strikeoutOffset;
+ params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
+ params.style = dec.mStyle;
+ PaintDecorationLine(params);
}
}
void
nsTextFrame::DrawText(Range aRange, const gfxPoint& aTextBaselinePt,
const DrawTextParams& aParams)
{
TextDecorations decorations;