| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/TextPainter.h" | 6 #include "core/paint/TextPainter.h" |
| 7 | 7 |
| 8 #include "core/CSSPropertyNames.h" | 8 #include "core/CSSPropertyNames.h" |
| 9 #include "core/frame/Settings.h" | 9 #include "core/frame/Settings.h" |
| 10 #include "core/layout/LayoutObject.h" | 10 #include "core/layout/LayoutObject.h" |
| 11 #include "core/layout/LayoutTextCombine.h" | 11 #include "core/layout/LayoutTextCombine.h" |
| 12 #include "core/layout/line/InlineTextBox.h" | 12 #include "core/layout/line/InlineTextBox.h" |
| 13 #include "core/paint/BoxPainter.h" | 13 #include "core/paint/BoxPainter.h" |
| 14 #include "core/paint/PaintInfo.h" | 14 #include "core/paint/PaintInfo.h" |
| 15 #include "core/style/ComputedStyle.h" | 15 #include "core/style/ComputedStyle.h" |
| 16 #include "core/style/ShadowList.h" | 16 #include "core/style/ShadowList.h" |
| 17 #include "platform/fonts/Font.h" | 17 #include "platform/fonts/Font.h" |
| 18 #include "platform/graphics/GraphicsContext.h" | 18 #include "platform/graphics/GraphicsContext.h" |
| 19 #include "platform/graphics/GraphicsContextStateSaver.h" | 19 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 20 #include "platform/text/TextRun.h" | 20 #include "platform/text/TextRun.h" |
| 21 #include "wtf/Assertions.h" | 21 #include "wtf/Assertions.h" |
| 22 #include "wtf/text/CharacterNames.h" | 22 #include "wtf/text/CharacterNames.h" |
| 23 | 23 |
| 24 namespace blink { | 24 namespace blink { |
| 25 | 25 |
| 26 TextPainter::TextPainter(GraphicsContext* context, const Font& font, const TextR
un& run, const LayoutPoint& textOrigin, const LayoutRect& textBounds, bool horiz
ontal) | 26 TextPainter::TextPainter(GraphicsContext& context, const Font& font, const TextR
un& run, const LayoutPoint& textOrigin, const LayoutRect& textBounds, bool horiz
ontal) |
| 27 : m_graphicsContext(context) | 27 : m_graphicsContext(context) |
| 28 , m_font(font) | 28 , m_font(font) |
| 29 , m_run(run) | 29 , m_run(run) |
| 30 , m_textOrigin(textOrigin) | 30 , m_textOrigin(textOrigin) |
| 31 , m_textBounds(textBounds) | 31 , m_textBounds(textBounds) |
| 32 , m_horizontal(horizontal) | 32 , m_horizontal(horizontal) |
| 33 , m_emphasisMarkOffset(0) | 33 , m_emphasisMarkOffset(0) |
| 34 , m_combinedText(0) | 34 , m_combinedText(0) |
| 35 { | 35 { |
| 36 } | 36 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 48 } else if (position == TextEmphasisPositionOver) { | 48 } else if (position == TextEmphasisPositionOver) { |
| 49 m_emphasisMarkOffset = -m_font.fontMetrics().ascent() - m_font.emphasisM
arkDescent(emphasisMark); | 49 m_emphasisMarkOffset = -m_font.fontMetrics().ascent() - m_font.emphasisM
arkDescent(emphasisMark); |
| 50 } else { | 50 } else { |
| 51 ASSERT(position == TextEmphasisPositionUnder); | 51 ASSERT(position == TextEmphasisPositionUnder); |
| 52 m_emphasisMarkOffset = m_font.fontMetrics().descent() + m_font.emphasisM
arkAscent(emphasisMark); | 52 m_emphasisMarkOffset = m_font.fontMetrics().descent() + m_font.emphasisM
arkAscent(emphasisMark); |
| 53 } | 53 } |
| 54 } | 54 } |
| 55 | 55 |
| 56 void TextPainter::paint(int startOffset, int endOffset, int length, const Style&
textStyle, TextBlobPtr* cachedTextBlob) | 56 void TextPainter::paint(int startOffset, int endOffset, int length, const Style&
textStyle, TextBlobPtr* cachedTextBlob) |
| 57 { | 57 { |
| 58 GraphicsContextStateSaver stateSaver(*m_graphicsContext, false); | 58 GraphicsContextStateSaver stateSaver(m_graphicsContext, false); |
| 59 updateGraphicsContext(textStyle, stateSaver); | 59 updateGraphicsContext(textStyle, stateSaver); |
| 60 if (m_combinedText) { | 60 if (m_combinedText) { |
| 61 m_graphicsContext->save(); | 61 m_graphicsContext.save(); |
| 62 m_combinedText->transformToInlineCoordinates(*m_graphicsContext, m_textB
ounds); | 62 m_combinedText->transformToInlineCoordinates(m_graphicsContext, m_textBo
unds); |
| 63 paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob)
; | 63 paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob)
; |
| 64 m_graphicsContext->restore(); | 64 m_graphicsContext.restore(); |
| 65 } else { | 65 } else { |
| 66 paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob)
; | 66 paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob)
; |
| 67 } | 67 } |
| 68 | 68 |
| 69 if (!m_emphasisMark.isEmpty()) { | 69 if (!m_emphasisMark.isEmpty()) { |
| 70 if (textStyle.emphasisMarkColor != textStyle.fillColor) | 70 if (textStyle.emphasisMarkColor != textStyle.fillColor) |
| 71 m_graphicsContext->setFillColor(textStyle.emphasisMarkColor); | 71 m_graphicsContext.setFillColor(textStyle.emphasisMarkColor); |
| 72 | 72 |
| 73 if (m_combinedText) | 73 if (m_combinedText) |
| 74 paintEmphasisMarkForCombinedText(); | 74 paintEmphasisMarkForCombinedText(); |
| 75 else | 75 else |
| 76 paintInternal<PaintEmphasisMark>(startOffset, endOffset, length); | 76 paintInternal<PaintEmphasisMark>(startOffset, endOffset, length); |
| 77 } | 77 } |
| 78 } | 78 } |
| 79 | 79 |
| 80 // static | 80 // static |
| 81 void TextPainter::updateGraphicsContext(GraphicsContext* context, const Style& t
extStyle, bool horizontal, GraphicsContextStateSaver& stateSaver) | 81 void TextPainter::updateGraphicsContext(GraphicsContext& context, const Style& t
extStyle, bool horizontal, GraphicsContextStateSaver& stateSaver) |
| 82 { | 82 { |
| 83 TextDrawingModeFlags mode = context->textDrawingMode(); | 83 TextDrawingModeFlags mode = context.textDrawingMode(); |
| 84 if (textStyle.strokeWidth > 0) { | 84 if (textStyle.strokeWidth > 0) { |
| 85 TextDrawingModeFlags newMode = mode | TextModeStroke; | 85 TextDrawingModeFlags newMode = mode | TextModeStroke; |
| 86 if (mode != newMode) { | 86 if (mode != newMode) { |
| 87 if (!stateSaver.saved()) | 87 if (!stateSaver.saved()) |
| 88 stateSaver.save(); | 88 stateSaver.save(); |
| 89 context->setTextDrawingMode(newMode); | 89 context.setTextDrawingMode(newMode); |
| 90 mode = newMode; | 90 mode = newMode; |
| 91 } | 91 } |
| 92 } | 92 } |
| 93 | 93 |
| 94 if (mode & TextModeFill && textStyle.fillColor != context->fillColor()) | 94 if (mode & TextModeFill && textStyle.fillColor != context.fillColor()) |
| 95 context->setFillColor(textStyle.fillColor); | 95 context.setFillColor(textStyle.fillColor); |
| 96 | 96 |
| 97 if (mode & TextModeStroke) { | 97 if (mode & TextModeStroke) { |
| 98 if (textStyle.strokeColor != context->strokeColor()) | 98 if (textStyle.strokeColor != context.strokeColor()) |
| 99 context->setStrokeColor(textStyle.strokeColor); | 99 context.setStrokeColor(textStyle.strokeColor); |
| 100 if (textStyle.strokeWidth != context->strokeThickness()) | 100 if (textStyle.strokeWidth != context.strokeThickness()) |
| 101 context->setStrokeThickness(textStyle.strokeWidth); | 101 context.setStrokeThickness(textStyle.strokeWidth); |
| 102 } | 102 } |
| 103 | 103 |
| 104 if (textStyle.shadow) { | 104 if (textStyle.shadow) { |
| 105 if (!stateSaver.saved()) | 105 if (!stateSaver.saved()) |
| 106 stateSaver.save(); | 106 stateSaver.save(); |
| 107 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil
der::ShadowIgnoresAlpha, textStyle.currentColor, horizontal)); | 107 context.setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuild
er::ShadowIgnoresAlpha, textStyle.currentColor, horizontal)); |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 static Color textColorForWhiteBackground(Color textColor) | 111 static Color textColorForWhiteBackground(Color textColor) |
| 112 { | 112 { |
| 113 int distanceFromWhite = differenceSquared(textColor, Color::white); | 113 int distanceFromWhite = differenceSquared(textColor, Color::white); |
| 114 // semi-arbitrarily chose 65025 (255^2) value here after a few tests; | 114 // semi-arbitrarily chose 65025 (255^2) value here after a few tests; |
| 115 return distanceFromWhite > 65025 ? textColor : textColor.dark(); | 115 return distanceFromWhite > 65025 ? textColor : textColor.dark(); |
| 116 } | 116 } |
| 117 | 117 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 template <TextPainter::PaintInternalStep step> | 183 template <TextPainter::PaintInternalStep step> |
| 184 void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from,
int to) | 184 void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from,
int to) |
| 185 { | 185 { |
| 186 ASSERT(from <= textRunPaintInfo.run.length()); | 186 ASSERT(from <= textRunPaintInfo.run.length()); |
| 187 ASSERT(to <= textRunPaintInfo.run.length()); | 187 ASSERT(to <= textRunPaintInfo.run.length()); |
| 188 | 188 |
| 189 textRunPaintInfo.from = from; | 189 textRunPaintInfo.from = from; |
| 190 textRunPaintInfo.to = to; | 190 textRunPaintInfo.to = to; |
| 191 | 191 |
| 192 if (step == PaintEmphasisMark) { | 192 if (step == PaintEmphasisMark) { |
| 193 m_graphicsContext->drawEmphasisMarks(m_font, textRunPaintInfo, m_emphasi
sMark, | 193 m_graphicsContext.drawEmphasisMarks(m_font, textRunPaintInfo, m_emphasis
Mark, |
| 194 FloatPoint(m_textOrigin) + IntSize(0, m_emphasisMarkOffset)); | 194 FloatPoint(m_textOrigin) + IntSize(0, m_emphasisMarkOffset)); |
| 195 } else { | 195 } else { |
| 196 ASSERT(step == PaintText); | 196 ASSERT(step == PaintText); |
| 197 m_graphicsContext->drawText(m_font, textRunPaintInfo, FloatPoint(m_textO
rigin)); | 197 m_graphicsContext.drawText(m_font, textRunPaintInfo, FloatPoint(m_textOr
igin)); |
| 198 } | 198 } |
| 199 } | 199 } |
| 200 | 200 |
| 201 template <TextPainter::PaintInternalStep Step> | 201 template <TextPainter::PaintInternalStep Step> |
| 202 void TextPainter::paintInternal(int startOffset, int endOffset, int truncationPo
int, TextBlobPtr* cachedTextBlob) | 202 void TextPainter::paintInternal(int startOffset, int endOffset, int truncationPo
int, TextBlobPtr* cachedTextBlob) |
| 203 { | 203 { |
| 204 TextRunPaintInfo textRunPaintInfo(m_run); | 204 TextRunPaintInfo textRunPaintInfo(m_run); |
| 205 textRunPaintInfo.bounds = FloatRect(m_textBounds); | 205 textRunPaintInfo.bounds = FloatRect(m_textBounds); |
| 206 if (startOffset <= endOffset) { | 206 if (startOffset <= endOffset) { |
| 207 // FIXME: We should be able to use cachedTextBlob in more cases. | 207 // FIXME: We should be able to use cachedTextBlob in more cases. |
| 208 textRunPaintInfo.cachedTextBlob = cachedTextBlob; | 208 textRunPaintInfo.cachedTextBlob = cachedTextBlob; |
| 209 paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset); | 209 paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset); |
| 210 } else { | 210 } else { |
| 211 if (endOffset > 0) | 211 if (endOffset > 0) |
| 212 paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); | 212 paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); |
| 213 if (startOffset < truncationPoint) | 213 if (startOffset < truncationPoint) |
| 214 paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoin
t); | 214 paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoin
t); |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 | 217 |
| 218 void TextPainter::paintEmphasisMarkForCombinedText() | 218 void TextPainter::paintEmphasisMarkForCombinedText() |
| 219 { | 219 { |
| 220 ASSERT(m_combinedText); | 220 ASSERT(m_combinedText); |
| 221 DEFINE_STATIC_LOCAL(TextRun, placeholderTextRun, (&ideographicFullStopCharac
ter, 1)); | 221 DEFINE_STATIC_LOCAL(TextRun, placeholderTextRun, (&ideographicFullStopCharac
ter, 1)); |
| 222 FloatPoint emphasisMarkTextOrigin(m_textBounds.x().toFloat(), m_textBounds.y
().toFloat() + m_font.fontMetrics().ascent() + m_emphasisMarkOffset); | 222 FloatPoint emphasisMarkTextOrigin(m_textBounds.x().toFloat(), m_textBounds.y
().toFloat() + m_font.fontMetrics().ascent() + m_emphasisMarkOffset); |
| 223 TextRunPaintInfo textRunPaintInfo(placeholderTextRun); | 223 TextRunPaintInfo textRunPaintInfo(placeholderTextRun); |
| 224 textRunPaintInfo.bounds = FloatRect(m_textBounds); | 224 textRunPaintInfo.bounds = FloatRect(m_textBounds); |
| 225 m_graphicsContext->concatCTM(rotation(m_textBounds, Clockwise)); | 225 m_graphicsContext.concatCTM(rotation(m_textBounds, Clockwise)); |
| 226 m_graphicsContext->drawEmphasisMarks(m_combinedText->originalFont(), textRun
PaintInfo, m_emphasisMark, emphasisMarkTextOrigin); | 226 m_graphicsContext.drawEmphasisMarks(m_combinedText->originalFont(), textRunP
aintInfo, m_emphasisMark, emphasisMarkTextOrigin); |
| 227 m_graphicsContext->concatCTM(rotation(m_textBounds, Counterclockwise)); | 227 m_graphicsContext.concatCTM(rotation(m_textBounds, Counterclockwise)); |
| 228 } | 228 } |
| 229 | 229 |
| 230 } // namespace blink | 230 } // namespace blink |
| OLD | NEW |