17242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 27242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Use of this source code is governed by a BSD-style license that can be 37242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// found in the LICENSE file. 47242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 57242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "config.h" 67242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/TextPainter.h" 77242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 87242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/CSSPropertyNames.h" 97242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/frame/Settings.h" 107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/InlineTextBox.h" 117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderCombineText.h" 127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderObject.h" 137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/style/RenderStyle.h" 147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/style/ShadowList.h" 157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/fonts/Font.h" 167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/graphics/GraphicsContext.h" 177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/graphics/GraphicsContextStateSaver.h" 187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/text/TextRun.h" 197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "wtf/Assertions.h" 207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "wtf/unicode/CharacterNames.h" 217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccinamespace blink { 237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciTextPainter::TextPainter(GraphicsContext* context, const Font& font, const TextRun& run, const FloatPoint& textOrigin, const FloatRect& textBounds, bool horizontal) 257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : m_graphicsContext(context) 267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_font(font) 277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_run(run) 287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_textOrigin(textOrigin) 297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_textBounds(textBounds) 307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_horizontal(horizontal) 317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_emphasisMarkOffset(0) 327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_combinedText(0) 337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciTextPainter::~TextPainter() 377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid TextPainter::setEmphasisMark(const AtomicString& emphasisMark, TextEmphasisPosition position) 417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_emphasisMark = emphasisMark; 437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (emphasisMark.isNull()) { 457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_emphasisMarkOffset = 0; 467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (position == TextEmphasisPositionOver) { 477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_emphasisMarkOffset = -m_font.fontMetrics().ascent() - m_font.emphasisMarkDescent(emphasisMark); 487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(position == TextEmphasisPositionUnder); 507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_emphasisMarkOffset = m_font.fontMetrics().descent() + m_font.emphasisMarkAscent(emphasisMark); 517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid TextPainter::paint(int startOffset, int endOffset, int length, const Style& textStyle, TextBlobPtr* cachedTextBlob) 557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci GraphicsContextStateSaver stateSaver(*m_graphicsContext, false); 577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci updateGraphicsContext(textStyle, stateSaver); 587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob); 597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_emphasisMark.isEmpty()) { 617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (textStyle.emphasisMarkColor != textStyle.fillColor) 627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_graphicsContext->setFillColor(textStyle.emphasisMarkColor); 637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_combinedText) 657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintEmphasisMarkForCombinedText(); 667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci else 677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInternal<PaintEmphasisMark>(startOffset, endOffset, length); 687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// static 727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid TextPainter::updateGraphicsContext(GraphicsContext* context, const Style& textStyle, bool horizontal, GraphicsContextStateSaver& stateSaver) 737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextDrawingModeFlags mode = context->textDrawingMode(); 757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (textStyle.strokeWidth > 0) { 767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextDrawingModeFlags newMode = mode | TextModeStroke; 777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (mode != newMode) { 787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!stateSaver.saved()) 797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci stateSaver.save(); 807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci context->setTextDrawingMode(newMode); 817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci mode = newMode; 827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (mode & TextModeFill && textStyle.fillColor != context->fillColor()) 867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci context->setFillColor(textStyle.fillColor); 877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (mode & TextModeStroke) { 897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (textStyle.strokeColor != context->strokeColor()) 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci context->setStrokeColor(textStyle.strokeColor); 917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (textStyle.strokeWidth != context->strokeThickness()) 927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci context->setStrokeThickness(textStyle.strokeWidth); 937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Text shadows are disabled when printing. http://crbug.com/258321 967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (textStyle.shadow && !context->printing()) { 977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!stateSaver.saved()) 987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci stateSaver.save(); 997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuilder::ShadowIgnoresAlpha, horizontal)); 1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic Color textColorForWhiteBackground(Color textColor) 1047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci int distanceFromWhite = differenceSquared(textColor, Color::white); 1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // semi-arbitrarily chose 65025 (255^2) value here after a few tests; 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return distanceFromWhite > 65025 ? textColor : textColor.dark(); 1087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// static 1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciTextPainter::Style TextPainter::textPaintingStyle(RenderObject& renderer, RenderStyle* style, bool forceBlackText, bool isPrinting) 1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextPainter::Style textStyle; 1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (forceBlackText) { 1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.fillColor = Color::black; 1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.strokeColor = Color::black; 1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.emphasisMarkColor = Color::black; 1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.strokeWidth = style->textStrokeWidth(); 1207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.shadow = 0; 1217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 1227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.fillColor = renderer.resolveColor(style, CSSPropertyWebkitTextFillColor); 1237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.strokeColor = renderer.resolveColor(style, CSSPropertyWebkitTextStrokeColor); 1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.emphasisMarkColor = renderer.resolveColor(style, CSSPropertyWebkitTextEmphasisColor); 1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.strokeWidth = style->textStrokeWidth(); 1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.shadow = style->textShadow(); 1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Adjust text color when printing with a white background. 1297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool forceBackgroundToWhite = false; 1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (isPrinting) { 1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (style->printColorAdjust() == PrintColorAdjustEconomy) 1327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci forceBackgroundToWhite = true; 1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (renderer.document().settings() && renderer.document().settings()->shouldPrintBackgrounds()) 1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci forceBackgroundToWhite = false; 1357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (forceBackgroundToWhite) { 1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.fillColor = textColorForWhiteBackground(textStyle.fillColor); 1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.strokeColor = textColorForWhiteBackground(textStyle.strokeColor); 1397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.emphasisMarkColor = textColorForWhiteBackground(textStyle.emphasisMarkColor); 1407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Text shadows are disabled when printing. http://crbug.com/258321 1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (isPrinting) 1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textStyle.shadow = 0; 1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return textStyle; 1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciTextPainter::Style TextPainter::selectionPaintingStyle(RenderObject& renderer, bool haveSelection, bool forceBlackText, bool isPrinting, const TextPainter::Style& textStyle) 1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextPainter::Style selectionStyle = textStyle; 1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (haveSelection) { 1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!forceBlackText) { 1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci selectionStyle.fillColor = renderer.selectionForegroundColor(); 1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci selectionStyle.emphasisMarkColor = renderer.selectionEmphasisMarkColor(); 1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (RenderStyle* pseudoStyle = renderer.getCachedPseudoStyle(SELECTION)) { 1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci selectionStyle.strokeColor = forceBlackText ? Color::black : renderer.resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor); 1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci selectionStyle.strokeWidth = pseudoStyle->textStrokeWidth(); 1637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci selectionStyle.shadow = forceBlackText ? 0 : pseudoStyle->textShadow(); 1647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Text shadows are disabled when printing. http://crbug.com/258321 1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (isPrinting) 1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci selectionStyle.shadow = 0; 1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return selectionStyle; 1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic bool graphicsContextAllowsTextBlobs(GraphicsContext* context) 1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Text blobs affect the shader coordinate space. 1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: Fix this, most likely in Skia. 1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return !context->strokeGradient() && !context->strokePattern() && !context->fillGradient() && !context->fillPattern(); 1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitemplate <TextPainter::PaintInternalStep step> 1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from, int to, TextBlobPtr* cachedTextBlob) 1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textRunPaintInfo.from = from; 1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textRunPaintInfo.to = to; 1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (step == PaintEmphasisMark) { 1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_graphicsContext->drawEmphasisMarks(m_font, textRunPaintInfo, m_emphasisMark, m_textOrigin + IntSize(0, m_emphasisMarkOffset)); 1897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(step == PaintText); 1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextBlobPtr localTextBlob; 1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextBlobPtr& textBlob = cachedTextBlob ? *cachedTextBlob : localTextBlob; 1967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool canUseTextBlobs = RuntimeEnabledFeatures::textBlobEnabled() && graphicsContextAllowsTextBlobs(m_graphicsContext); 1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (canUseTextBlobs && !textBlob) 1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textBlob = m_font.buildTextBlob(textRunPaintInfo, m_textOrigin, m_graphicsContext->couldUseLCDRenderedText()); 2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (canUseTextBlobs && textBlob) 2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_font.drawTextBlob(m_graphicsContext, textBlob.get(), m_textOrigin.data()); 2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci else 2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_graphicsContext->drawText(m_font, textRunPaintInfo, m_textOrigin); 2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitemplate <TextPainter::PaintInternalStep Step> 2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid TextPainter::paintInternal(int startOffset, int endOffset, int truncationPoint, TextBlobPtr* cachedTextBlob) 2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: We should be able to use cachedTextBlob in more cases. 2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextRunPaintInfo textRunPaintInfo(m_run); 2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textRunPaintInfo.bounds = m_textBounds; 2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (startOffset <= endOffset) { 2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset, cachedTextBlob); 2157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (endOffset > 0) 2177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); 2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (startOffset < truncationPoint) 2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoint); 2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid TextPainter::paintEmphasisMarkForCombinedText() 2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_combinedText); 2267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci DEFINE_STATIC_LOCAL(TextRun, placeholderTextRun, (&ideographicFullStop, 1)); 2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci FloatPoint emphasisMarkTextOrigin(m_textBounds.x(), m_textBounds.y() + m_font.fontMetrics().ascent() + m_emphasisMarkOffset); 2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci TextRunPaintInfo textRunPaintInfo(placeholderTextRun); 2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci textRunPaintInfo.bounds = m_textBounds; 2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_graphicsContext->concatCTM(InlineTextBox::rotation(m_textBounds, InlineTextBox::Clockwise)); 2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_graphicsContext->drawEmphasisMarks(m_combinedText->originalFont(), textRunPaintInfo, m_emphasisMark, emphasisMarkTextOrigin); 2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_graphicsContext->concatCTM(InlineTextBox::rotation(m_textBounds, InlineTextBox::Counterclockwise)); 2337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace blink 236