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/rendering/TextPainter.h" | 6 #include "core/rendering/TextPainter.h" |
7 | 7 |
8 #include "core/rendering/InlineTextBox.h" | 8 #include "core/rendering/InlineTextBox.h" |
9 #include "core/rendering/RenderCombineText.h" | 9 #include "core/rendering/RenderCombineText.h" |
10 #include "core/rendering/style/ShadowList.h" | 10 #include "core/rendering/style/ShadowList.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 if (emphasisMark.isNull()) { | 40 if (emphasisMark.isNull()) { |
41 m_emphasisMarkOffset = 0; | 41 m_emphasisMarkOffset = 0; |
42 } else if (position == TextEmphasisPositionOver) { | 42 } else if (position == TextEmphasisPositionOver) { |
43 m_emphasisMarkOffset = -m_font.fontMetrics().ascent() - m_font.emphasisM arkDescent(emphasisMark); | 43 m_emphasisMarkOffset = -m_font.fontMetrics().ascent() - m_font.emphasisM arkDescent(emphasisMark); |
44 } else { | 44 } else { |
45 ASSERT(position == TextEmphasisPositionUnder); | 45 ASSERT(position == TextEmphasisPositionUnder); |
46 m_emphasisMarkOffset = m_font.fontMetrics().descent() + m_font.emphasisM arkAscent(emphasisMark); | 46 m_emphasisMarkOffset = m_font.fontMetrics().descent() + m_font.emphasisM arkAscent(emphasisMark); |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 void TextPainter::paint(int startOffset, int endOffset, int length, const Style& textStyle) | 50 void TextPainter::paint(int startOffset, int endOffset, int length, const Style& textStyle, TextBlobPtr* textBlobCache) |
51 { | 51 { |
52 GraphicsContextStateSaver stateSaver(*m_graphicsContext, false); | 52 GraphicsContextStateSaver stateSaver(*m_graphicsContext, false); |
53 updateGraphicsContext(textStyle, stateSaver); | 53 updateGraphicsContext(textStyle, stateSaver); |
54 paintInternal<PaintText>(startOffset, endOffset, length); | 54 paintInternal<PaintText>(startOffset, endOffset, length, textBlobCache); |
55 | 55 |
56 if (!m_emphasisMark.isEmpty()) { | 56 if (!m_emphasisMark.isEmpty()) { |
57 if (textStyle.emphasisMarkColor != textStyle.fillColor) | 57 if (textStyle.emphasisMarkColor != textStyle.fillColor) |
58 m_graphicsContext->setFillColor(textStyle.emphasisMarkColor); | 58 m_graphicsContext->setFillColor(textStyle.emphasisMarkColor); |
59 | 59 |
60 if (m_combinedText) | 60 if (m_combinedText) |
61 paintEmphasisMarkForCombinedText(); | 61 paintEmphasisMarkForCombinedText(); |
62 else | 62 else |
63 paintInternal<PaintEmphasisMark>(startOffset, endOffset, length); | 63 paintInternal<PaintEmphasisMark>(startOffset, endOffset, length); |
64 } | 64 } |
(...skipping 24 matching lines...) Expand all Loading... | |
89 } | 89 } |
90 | 90 |
91 // Text shadows are disabled when printing. http://crbug.com/258321 | 91 // Text shadows are disabled when printing. http://crbug.com/258321 |
92 if (textStyle.shadow && !context->printing()) { | 92 if (textStyle.shadow && !context->printing()) { |
93 if (!stateSaver.saved()) | 93 if (!stateSaver.saved()) |
94 stateSaver.save(); | 94 stateSaver.save(); |
95 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil der::ShadowIgnoresAlpha, horizontal)); | 95 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil der::ShadowIgnoresAlpha, horizontal)); |
96 } | 96 } |
97 } | 97 } |
98 | 98 |
99 static bool graphicsContextAllowsTextBlobs(GraphicsContext* context) | |
100 { | |
101 // Text blobs affect the shader coordinate space. | |
102 // FIXME: Fix this, most likely in Skia. | |
103 return !context->strokeGradient() && !context->strokePattern() && !context-> fillGradient() && !context->fillPattern(); | |
104 } | |
105 | |
99 template <TextPainter::PaintInternalStep step> | 106 template <TextPainter::PaintInternalStep step> |
100 void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from, int to) | 107 void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from, int to, TextBlobPtr* textBlobCache) |
101 { | 108 { |
102 textRunPaintInfo.from = from; | 109 textRunPaintInfo.from = from; |
103 textRunPaintInfo.to = to; | 110 textRunPaintInfo.to = to; |
104 if (step == PaintEmphasisMark) | 111 |
112 if (step == PaintEmphasisMark) { | |
105 m_graphicsContext->drawEmphasisMarks(m_font, textRunPaintInfo, m_emphasi sMark, m_textOrigin + IntSize(0, m_emphasisMarkOffset)); | 113 m_graphicsContext->drawEmphasisMarks(m_font, textRunPaintInfo, m_emphasi sMark, m_textOrigin + IntSize(0, m_emphasisMarkOffset)); |
106 else | 114 return; |
115 } | |
116 | |
117 ASSERT(step == PaintText); | |
118 | |
119 // We transfer the original ref back and forth with the cache to avoid | |
120 // thrashing the ref count. Skia will take a ref, so we can't just ref | |
121 // the blob here and then pass that reference to Skia. | |
f(malita)
2014/09/12 13:21:23
We may be able to attain the same using something
jbroman
2014/09/13 00:06:42
Yeah, okay. I'm not sure whether that's clearer or
jbroman
2014/09/17 22:25:37
I've changed to a variation on this theme.
| |
122 TextBlobPtr textBlob = textBlobCache ? textBlobCache->release() : nullptr; | |
123 bool canUseTextBlobs = RuntimeEnabledFeatures::textBlobEnabled() && graphics ContextAllowsTextBlobs(m_graphicsContext); | |
124 | |
125 if (!textBlob && canUseTextBlobs) | |
126 textBlob = m_font.buildTextBlob(textRunPaintInfo, m_textOrigin, m_graphi csContext->couldUseLCDRenderedText()); | |
127 | |
128 if (textBlob && canUseTextBlobs) { | |
129 m_font.drawTextBlob(m_graphicsContext, textBlob.get(), m_textOrigin.data ()); | |
130 if (textBlobCache) | |
131 *textBlobCache = textBlob.release(); | |
132 } else { | |
107 m_graphicsContext->drawText(m_font, textRunPaintInfo, m_textOrigin); | 133 m_graphicsContext->drawText(m_font, textRunPaintInfo, m_textOrigin); |
108 | 134 } |
109 } | 135 } |
110 | 136 |
111 template <TextPainter::PaintInternalStep Step> | 137 template <TextPainter::PaintInternalStep Step> |
112 void TextPainter::paintInternal(int startOffset, int endOffset, int truncationPo int) | 138 void TextPainter::paintInternal(int startOffset, int endOffset, int truncationPo int, TextBlobPtr* textBlobCache) |
113 { | 139 { |
140 // FIXME: We should be able to use textBlobCache in more cases. | |
114 TextRunPaintInfo textRunPaintInfo(m_run); | 141 TextRunPaintInfo textRunPaintInfo(m_run); |
115 textRunPaintInfo.bounds = m_textBounds; | 142 textRunPaintInfo.bounds = m_textBounds; |
116 if (startOffset <= endOffset) { | 143 if (startOffset <= endOffset) { |
117 paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset); | 144 paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset, textBlo bCache); |
118 } else { | 145 } else { |
119 if (endOffset > 0) | 146 if (endOffset > 0) |
120 paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); | 147 paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); |
121 if (startOffset < truncationPoint) | 148 if (startOffset < truncationPoint) |
122 paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoin t); | 149 paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoin t); |
123 } | 150 } |
124 } | 151 } |
125 | 152 |
126 void TextPainter::paintEmphasisMarkForCombinedText() | 153 void TextPainter::paintEmphasisMarkForCombinedText() |
127 { | 154 { |
128 ASSERT(m_combinedText); | 155 ASSERT(m_combinedText); |
129 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectRepl acementCharacter, 1)); | 156 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectRepl acementCharacter, 1)); |
130 FloatPoint emphasisMarkTextOrigin(m_textBounds.x() + m_textBounds.width() / 2, m_textBounds.y() + m_font.fontMetrics().ascent() + m_emphasisMarkOffset); | 157 FloatPoint emphasisMarkTextOrigin(m_textBounds.x() + m_textBounds.width() / 2, m_textBounds.y() + m_font.fontMetrics().ascent() + m_emphasisMarkOffset); |
131 TextRunPaintInfo textRunPaintInfo(objectReplacementCharacterTextRun); | 158 TextRunPaintInfo textRunPaintInfo(objectReplacementCharacterTextRun); |
132 textRunPaintInfo.bounds = m_textBounds; | 159 textRunPaintInfo.bounds = m_textBounds; |
133 m_graphicsContext->concatCTM(InlineTextBox::rotation(m_textBounds, InlineTex tBox::Clockwise)); | 160 m_graphicsContext->concatCTM(InlineTextBox::rotation(m_textBounds, InlineTex tBox::Clockwise)); |
134 m_graphicsContext->drawEmphasisMarks(m_combinedText->originalFont(), textRun PaintInfo, m_emphasisMark, emphasisMarkTextOrigin); | 161 m_graphicsContext->drawEmphasisMarks(m_combinedText->originalFont(), textRun PaintInfo, m_emphasisMark, emphasisMarkTextOrigin); |
135 m_graphicsContext->concatCTM(InlineTextBox::rotation(m_textBounds, InlineTex tBox::Counterclockwise)); | 162 m_graphicsContext->concatCTM(InlineTextBox::rotation(m_textBounds, InlineTex tBox::Counterclockwise)); |
136 } | 163 } |
137 | 164 |
138 } // namespace blink | 165 } // namespace blink |
OLD | NEW |