Chromium Code Reviews| 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 |