Index: Source/core/rendering/TextPainter.cpp |
diff --git a/Source/core/rendering/TextPainter.cpp b/Source/core/rendering/TextPainter.cpp |
index 724bfd40e08cfb73a176ae714b49bde12b390877..43f4a1360668e3a927db20832eabc82b43737e01 100644 |
--- a/Source/core/rendering/TextPainter.cpp |
+++ b/Source/core/rendering/TextPainter.cpp |
@@ -47,11 +47,11 @@ void TextPainter::setEmphasisMark(const AtomicString& emphasisMark, TextEmphasis |
} |
} |
-void TextPainter::paint(int startOffset, int endOffset, int length, const Style& textStyle) |
+void TextPainter::paint(int startOffset, int endOffset, int length, const Style& textStyle, TextBlobPtr* textBlobCache) |
{ |
GraphicsContextStateSaver stateSaver(*m_graphicsContext, false); |
updateGraphicsContext(textStyle, stateSaver); |
- paintInternal<PaintText>(startOffset, endOffset, length); |
+ paintInternal<PaintText>(startOffset, endOffset, length, textBlobCache); |
if (!m_emphasisMark.isEmpty()) { |
if (textStyle.emphasisMarkColor != textStyle.fillColor) |
@@ -96,25 +96,52 @@ void TextPainter::updateGraphicsContext(GraphicsContext* context, const Style& t |
} |
} |
+static bool graphicsContextAllowsTextBlobs(GraphicsContext* context) |
+{ |
+ // Text blobs affect the shader coordinate space. |
+ // FIXME: Fix this, most likely in Skia. |
+ return !context->strokeGradient() && !context->strokePattern() && !context->fillGradient() && !context->fillPattern(); |
+} |
+ |
template <TextPainter::PaintInternalStep step> |
-void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from, int to) |
+void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo, int from, int to, TextBlobPtr* textBlobCache) |
{ |
textRunPaintInfo.from = from; |
textRunPaintInfo.to = to; |
- if (step == PaintEmphasisMark) |
+ |
+ if (step == PaintEmphasisMark) { |
m_graphicsContext->drawEmphasisMarks(m_font, textRunPaintInfo, m_emphasisMark, m_textOrigin + IntSize(0, m_emphasisMarkOffset)); |
- else |
- m_graphicsContext->drawText(m_font, textRunPaintInfo, m_textOrigin); |
+ return; |
+ } |
+ ASSERT(step == PaintText); |
+ |
+ // We transfer the original ref back and forth with the cache to avoid |
+ // thrashing the ref count. Skia will take a ref, so we can't just ref |
+ // 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.
|
+ TextBlobPtr textBlob = textBlobCache ? textBlobCache->release() : nullptr; |
+ bool canUseTextBlobs = RuntimeEnabledFeatures::textBlobEnabled() && graphicsContextAllowsTextBlobs(m_graphicsContext); |
+ |
+ if (!textBlob && canUseTextBlobs) |
+ textBlob = m_font.buildTextBlob(textRunPaintInfo, m_textOrigin, m_graphicsContext->couldUseLCDRenderedText()); |
+ |
+ if (textBlob && canUseTextBlobs) { |
+ m_font.drawTextBlob(m_graphicsContext, textBlob.get(), m_textOrigin.data()); |
+ if (textBlobCache) |
+ *textBlobCache = textBlob.release(); |
+ } else { |
+ m_graphicsContext->drawText(m_font, textRunPaintInfo, m_textOrigin); |
+ } |
} |
template <TextPainter::PaintInternalStep Step> |
-void TextPainter::paintInternal(int startOffset, int endOffset, int truncationPoint) |
+void TextPainter::paintInternal(int startOffset, int endOffset, int truncationPoint, TextBlobPtr* textBlobCache) |
{ |
+ // FIXME: We should be able to use textBlobCache in more cases. |
TextRunPaintInfo textRunPaintInfo(m_run); |
textRunPaintInfo.bounds = m_textBounds; |
if (startOffset <= endOffset) { |
- paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset); |
+ paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset, textBlobCache); |
} else { |
if (endOffset > 0) |
paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); |