| Index: Source/core/rendering/InlineTextBox.cpp
|
| diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp
|
| index 361a06c7dbc15ab88e05893783c43cd003e48516..b1352fcb62c8278fb0873ae7de8e6ab011309024 100644
|
| --- a/Source/core/rendering/InlineTextBox.cpp
|
| +++ b/Source/core/rendering/InlineTextBox.cpp
|
| @@ -44,6 +44,7 @@
|
| #include "core/rendering/RenderRubyRun.h"
|
| #include "core/rendering/RenderRubyText.h"
|
| #include "core/rendering/RenderTheme.h"
|
| +#include "core/rendering/TextPainter.h"
|
| #include "core/rendering/style/ShadowList.h"
|
| #include "core/rendering/svg/SVGTextRunRenderingContext.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| @@ -375,27 +376,9 @@ bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
|
|
|
| namespace {
|
|
|
| -struct TextPaintingStyle {
|
| - Color fillColor;
|
| - Color strokeColor;
|
| - Color emphasisMarkColor;
|
| - float strokeWidth;
|
| - const ShadowList* shadow;
|
| -
|
| - bool operator==(const TextPaintingStyle& other)
|
| - {
|
| - return fillColor == other.fillColor
|
| - && strokeColor == other.strokeColor
|
| - && emphasisMarkColor == other.emphasisMarkColor
|
| - && strokeWidth == other.strokeWidth
|
| - && shadow == other.shadow;
|
| - }
|
| - bool operator!=(const TextPaintingStyle& other) { return !(*this == other); }
|
| -};
|
| -
|
| -TextPaintingStyle textPaintingStyle(RenderText& renderer, RenderStyle* style, bool forceBlackText, bool isPrinting)
|
| +TextPainter::Style textPaintingStyle(RenderText& renderer, RenderStyle* style, bool forceBlackText, bool isPrinting)
|
| {
|
| - TextPaintingStyle textStyle;
|
| + TextPainter::Style textStyle;
|
|
|
| if (forceBlackText) {
|
| textStyle.fillColor = Color::black;
|
| @@ -432,9 +415,9 @@ TextPaintingStyle textPaintingStyle(RenderText& renderer, RenderStyle* style, bo
|
| return textStyle;
|
| }
|
|
|
| -TextPaintingStyle selectionPaintingStyle(RenderText& renderer, bool haveSelection, bool forceBlackText, bool isPrinting, const TextPaintingStyle& textStyle)
|
| +TextPainter::Style selectionPaintingStyle(RenderText& renderer, bool haveSelection, bool forceBlackText, bool isPrinting, const TextPainter::Style& textStyle)
|
| {
|
| - TextPaintingStyle selectionStyle = textStyle;
|
| + TextPainter::Style selectionStyle = textStyle;
|
|
|
| if (haveSelection) {
|
| if (!forceBlackText) {
|
| @@ -456,107 +439,6 @@ TextPaintingStyle selectionPaintingStyle(RenderText& renderer, bool haveSelectio
|
| return selectionStyle;
|
| }
|
|
|
| -void updateGraphicsContext(GraphicsContext* context, const TextPaintingStyle& textStyle, bool horizontal, GraphicsContextStateSaver& stateSaver)
|
| -{
|
| - TextDrawingModeFlags mode = context->textDrawingMode();
|
| - if (textStyle.strokeWidth > 0) {
|
| - TextDrawingModeFlags newMode = mode | TextModeStroke;
|
| - if (mode != newMode) {
|
| - if (!stateSaver.saved())
|
| - stateSaver.save();
|
| - context->setTextDrawingMode(newMode);
|
| - mode = newMode;
|
| - }
|
| - }
|
| -
|
| - if (mode & TextModeFill && textStyle.fillColor != context->fillColor())
|
| - context->setFillColor(textStyle.fillColor);
|
| -
|
| - if (mode & TextModeStroke) {
|
| - if (textStyle.strokeColor != context->strokeColor())
|
| - context->setStrokeColor(textStyle.strokeColor);
|
| - if (textStyle.strokeWidth != context->strokeThickness())
|
| - context->setStrokeThickness(textStyle.strokeWidth);
|
| - }
|
| -
|
| - // Text shadows are disabled when printing. http://crbug.com/258321
|
| - if (textStyle.shadow && !context->printing()) {
|
| - if (!stateSaver.saved())
|
| - stateSaver.save();
|
| - context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuilder::ShadowIgnoresAlpha, horizontal));
|
| - }
|
| -}
|
| -
|
| -void paintText(GraphicsContext* context,
|
| - const Font& font, const TextRun& textRun,
|
| - const AtomicString& emphasisMark, int emphasisMarkOffset,
|
| - int startOffset, int endOffset, int truncationPoint,
|
| - const FloatPoint& textOrigin, const FloatRect& boxRect)
|
| -{
|
| - TextRunPaintInfo textRunPaintInfo(textRun);
|
| - textRunPaintInfo.bounds = boxRect;
|
| - if (startOffset <= endOffset) {
|
| - textRunPaintInfo.from = startOffset;
|
| - textRunPaintInfo.to = endOffset;
|
| - if (emphasisMark.isEmpty())
|
| - context->drawText(font, textRunPaintInfo, textOrigin);
|
| - else
|
| - context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset));
|
| - } else {
|
| - if (endOffset > 0) {
|
| - textRunPaintInfo.from = 0;
|
| - textRunPaintInfo.to = endOffset;
|
| - if (emphasisMark.isEmpty())
|
| - context->drawText(font, textRunPaintInfo, textOrigin);
|
| - else
|
| - context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset));
|
| - }
|
| - if (startOffset < truncationPoint) {
|
| - textRunPaintInfo.from = startOffset;
|
| - textRunPaintInfo.to = truncationPoint;
|
| - if (emphasisMark.isEmpty())
|
| - context->drawText(font, textRunPaintInfo, textOrigin);
|
| - else
|
| - context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset));
|
| - }
|
| - }
|
| -}
|
| -
|
| -inline void paintEmphasisMark(GraphicsContext* context,
|
| - const AtomicString& emphasisMark, int emphasisMarkOffset,
|
| - int startOffset, int endOffset, int paintRunLength,
|
| - const Font& font, RenderCombineText* combinedText, const TextRun& textRun,
|
| - const FloatPoint& textOrigin, const FloatRect& boxRect)
|
| -{
|
| - ASSERT(!emphasisMark.isEmpty());
|
| -
|
| - if (combinedText) {
|
| - DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectReplacementCharacter, 1));
|
| - FloatPoint emphasisMarkTextOrigin(boxRect.x() + boxRect.width() / 2, boxRect.y() + font.fontMetrics().ascent());
|
| - context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise));
|
| - paintText(context, combinedText->originalFont(), objectReplacementCharacterTextRun, emphasisMark, emphasisMarkOffset, 0, 1, 1, emphasisMarkTextOrigin, boxRect);
|
| - context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Counterclockwise));
|
| - } else {
|
| - paintText(context, font, textRun, emphasisMark, emphasisMarkOffset, startOffset, endOffset, paintRunLength, textOrigin, boxRect);
|
| - }
|
| -}
|
| -
|
| -void paintTextWithEmphasisMark(
|
| - GraphicsContext* context, const Font& font, const TextPaintingStyle& textStyle, const TextRun& textRun,
|
| - const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, int endOffset, int length,
|
| - RenderCombineText* combinedText, const FloatPoint& textOrigin, const FloatRect& boxRect, bool horizontal)
|
| -{
|
| - GraphicsContextStateSaver stateSaver(*context, false);
|
| - updateGraphicsContext(context, textStyle, horizontal, stateSaver);
|
| - paintText(context, font, textRun, nullAtom, 0, startOffset, endOffset, length, textOrigin, boxRect);
|
| -
|
| - if (!emphasisMark.isEmpty()) {
|
| - if (textStyle.emphasisMarkColor != textStyle.fillColor)
|
| - context->setFillColor(textStyle.emphasisMarkColor);
|
| - paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOffset, endOffset, length, font, combinedText, textRun, textOrigin, boxRect);
|
| - }
|
| -}
|
| -
|
| } // namespace
|
|
|
| void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
|
| @@ -631,8 +513,8 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
|
| bool useCustomUnderlines = containsComposition && renderer().frame()->inputMethodController().compositionUsesCustomUnderlines();
|
|
|
| // Determine text colors.
|
| - TextPaintingStyle textStyle = textPaintingStyle(renderer(), styleToUse, paintInfo.forceBlackText(), isPrinting);
|
| - TextPaintingStyle selectionStyle = selectionPaintingStyle(renderer(), haveSelection, paintInfo.forceBlackText(), isPrinting, textStyle);
|
| + TextPainter::Style textStyle = textPaintingStyle(renderer(), styleToUse, paintInfo.forceBlackText(), isPrinting);
|
| + TextPainter::Style selectionStyle = selectionPaintingStyle(renderer(), haveSelection, paintInfo.forceBlackText(), isPrinting, textStyle);
|
| bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection);
|
| bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != selectionStyle;
|
|
|
| @@ -675,49 +557,50 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
|
| if (hasHyphen())
|
| length = textRun.length();
|
|
|
| - int sPos = 0;
|
| - int ePos = 0;
|
| + int selectionStart = 0;
|
| + int selectionEnd = 0;
|
| if (paintSelectedTextOnly || paintSelectedTextSeparately)
|
| - selectionStartEnd(sPos, ePos);
|
| + selectionStartEnd(selectionStart, selectionEnd);
|
|
|
| - bool respectHyphen = ePos == m_len && hasHyphen();
|
| + bool respectHyphen = selectionEnd == m_len && hasHyphen();
|
| if (respectHyphen)
|
| - ePos = textRun.length();
|
| + selectionEnd = textRun.length();
|
|
|
| if (m_truncation != cNoTruncation) {
|
| - sPos = std::min<int>(sPos, m_truncation);
|
| - ePos = std::min<int>(ePos, m_truncation);
|
| + selectionStart = std::min<int>(selectionStart, m_truncation);
|
| + selectionEnd = std::min<int>(selectionEnd, m_truncation);
|
| length = m_truncation;
|
| }
|
|
|
| - int emphasisMarkOffset = 0;
|
| + TextPainter textPainter(context, font, textRun, textOrigin, boxRect, isHorizontal());
|
| TextEmphasisPosition emphasisMarkPosition;
|
| bool hasTextEmphasis = getEmphasisMarkPosition(styleToUse, emphasisMarkPosition);
|
| - const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasisMarkString() : nullAtom;
|
| - if (!emphasisMark.isEmpty())
|
| - emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fontMetrics().descent() + font.emphasisMarkAscent(emphasisMark);
|
| + if (hasTextEmphasis)
|
| + textPainter.setEmphasisMark(styleToUse->textEmphasisMarkString(), emphasisMarkPosition);
|
| + if (combinedText)
|
| + textPainter.setCombinedText(combinedText);
|
|
|
| if (!paintSelectedTextOnly) {
|
| // FIXME: Truncate right-to-left text correctly.
|
| int startOffset = 0;
|
| int endOffset = length;
|
| - if (paintSelectedTextSeparately && ePos > sPos) {
|
| - startOffset = ePos;
|
| - endOffset = sPos;
|
| + if (paintSelectedTextSeparately && selectionStart < selectionEnd) {
|
| + startOffset = selectionEnd;
|
| + endOffset = selectionStart;
|
| }
|
| - paintTextWithEmphasisMark(context, font, textStyle, textRun, emphasisMark, emphasisMarkOffset, startOffset, endOffset, length, combinedText, textOrigin, boxRect, isHorizontal());
|
| + textPainter.paint(startOffset, endOffset, length, textStyle);
|
| }
|
|
|
| - if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) {
|
| + if ((paintSelectedTextOnly || paintSelectedTextSeparately) && selectionStart < selectionEnd) {
|
| // paint only the text that is selected
|
| - paintTextWithEmphasisMark(context, font, selectionStyle, textRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, combinedText, textOrigin, boxRect, isHorizontal());
|
| + textPainter.paint(selectionStart, selectionEnd, length, selectionStyle);
|
| }
|
|
|
| // Paint decorations
|
| TextDecoration textDecorations = styleToUse->textDecorationsInEffect();
|
| if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) {
|
| GraphicsContextStateSaver stateSaver(*context, false);
|
| - updateGraphicsContext(context, textStyle, isHorizontal(), stateSaver);
|
| + TextPainter::updateGraphicsContext(context, textStyle, isHorizontal(), stateSaver);
|
| if (combinedText)
|
| context->concatCTM(rotation(boxRect, Clockwise));
|
| paintDecoration(context, boxOrigin, textDecorations);
|
|
|