Index: Source/platform/fonts/Font.cpp |
diff --git a/Source/platform/fonts/Font.cpp b/Source/platform/fonts/Font.cpp |
index 2aca587e3924ba04b548f1afc031d91c538b9dfa..62b6354dcaf64e55160b115bd26b8b38823397ea 100644 |
--- a/Source/platform/fonts/Font.cpp |
+++ b/Source/platform/fonts/Font.cpp |
@@ -100,7 +100,78 @@ void Font::update(PassRefPtrWillBeRawPtr<FontSelector> fontSelector) const |
m_fontFallbackList->invalidate(fontSelector); |
} |
-float Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo, const FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction) const |
+float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyphBuffer, |
+ ForTextEmphasisOrNot forTextEmphasis) const |
+{ |
+ if (codePath(runInfo) == ComplexPath) { |
+ HarfBuzzShaper shaper(this, runInfo.run, (forTextEmphasis == ForTextEmphasis) |
+ ? HarfBuzzShaper::ForTextEmphasis : HarfBuzzShaper::NotForTextEmphasis); |
+ shaper.setDrawRange(runInfo.from, runInfo.to); |
+ shaper.shape(&glyphBuffer); |
+ |
+ return 0; |
+ } |
+ |
+ SimpleShaper shaper(this, runInfo.run, nullptr /* fallbackFonts */, |
+ nullptr /* GlyphBounds */, forTextEmphasis); |
+ shaper.advance(runInfo.from); |
+ float beforeWidth = shaper.runWidthSoFar(); |
+ shaper.advance(runInfo.to, &glyphBuffer); |
+ |
+ if (runInfo.run.ltr()) |
+ return beforeWidth; |
+ |
+ // RTL |
+ float afterWidth = shaper.runWidthSoFar(); |
+ shaper.advance(runInfo.run.length()); |
+ glyphBuffer.reverse(); |
+ |
+ return shaper.runWidthSoFar() - afterWidth; |
+} |
+ |
+void Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo, |
+ const FloatPoint& point) const |
+{ |
+ // Don't draw anything while we are using custom fonts that are in the process of loading. |
+ if (shouldSkipDrawing()) |
+ return; |
+ |
+ TextDrawingModeFlags textMode = context->textDrawingMode(); |
+ if (!(textMode & TextModeFill) && !((textMode & TextModeStroke) && context->hasStroke())) |
+ return; |
+ |
+ if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
+ ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
+ // we have a pre-cached blob -- happy joy! |
+ drawTextBlob(context, runInfo.cachedTextBlob->get(), point.data()); |
+ return; |
+ } |
+ |
+ GlyphBuffer glyphBuffer; |
+ float initialAdvance = buildGlyphBuffer(runInfo, glyphBuffer); |
+ |
+ if (glyphBuffer.isEmpty()) |
+ return; |
+ |
+ if (RuntimeEnabledFeatures::textBlobEnabled()) { |
+ // Enabling text-blobs forces the blob rendering path even for uncacheable blobs. |
+ TextBlobPtr uncacheableTextBlob; |
+ TextBlobPtr& textBlob = runInfo.cachedTextBlob ? *runInfo.cachedTextBlob : uncacheableTextBlob; |
+ FloatRect blobBounds = runInfo.bounds; |
+ blobBounds.moveBy(-point); |
+ |
+ textBlob = buildTextBlob(glyphBuffer, initialAdvance, blobBounds, context->couldUseLCDRenderedText()); |
+ if (textBlob) { |
+ drawTextBlob(context, textBlob.get(), point.data()); |
+ return; |
+ } |
+ } |
+ |
+ drawGlyphBuffer(context, runInfo, glyphBuffer, FloatPoint(point.x() + initialAdvance, point.y())); |
+} |
+ |
+float Font::drawUncachedText(GraphicsContext* context, const TextRunPaintInfo& runInfo, |
+ const FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction) const |
{ |
// Don't draw anything while we are using custom fonts that are in the process of loading, |
// except if the 'force' argument is set to true (in which case it will use a fallback |
@@ -108,10 +179,17 @@ float Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo, |
if (shouldSkipDrawing() && customFontNotReadyAction == DoNotPaintIfFontNotReady) |
return 0; |
- if (codePath(runInfo) != ComplexPath) |
- return drawSimpleText(context, runInfo, point); |
+ TextDrawingModeFlags textMode = context->textDrawingMode(); |
+ if (!(textMode & TextModeFill) && !((textMode & TextModeStroke) && context->hasStroke())) |
+ return 0; |
+ |
+ GlyphBuffer glyphBuffer; |
+ float initialAdvance = buildGlyphBuffer(runInfo, glyphBuffer); |
+ |
+ if (glyphBuffer.isEmpty()) |
+ return 0; |
- return drawComplexText(context, runInfo, point); |
+ return drawGlyphBuffer(context, runInfo, glyphBuffer, FloatPoint(point.x() + initialAdvance, point.y())); |
} |
void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const |
@@ -119,10 +197,13 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r |
if (shouldSkipDrawing()) |
return; |
- if (codePath(runInfo) != ComplexPath) |
- drawEmphasisMarksForSimpleText(context, runInfo, mark, point); |
- else |
- drawEmphasisMarksForComplexText(context, runInfo, mark, point); |
+ GlyphBuffer glyphBuffer; |
+ float initialAdvance = buildGlyphBuffer(runInfo, glyphBuffer, ForTextEmphasis); |
+ |
+ if (glyphBuffer.isEmpty()) |
+ return; |
+ |
+ drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y())); |
} |
static inline void updateGlyphOverflowFromBounds(const IntRectExtent& glyphBounds, |
@@ -190,43 +271,14 @@ float Font::width(const TextRun& run, int& charsConsumed, Glyph& glyphId) const |
return width(run); |
} |
-PassTextBlobPtr Font::buildTextBlob(const TextRunPaintInfo& runInfo, const FloatPoint& textOrigin, bool couldUseLCDRenderedText, CustomFontNotReadyAction customFontNotReadyAction) const |
-{ |
- ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
- |
- // FIXME: Some logic in common with Font::drawText. Would be nice to |
- // deduplicate. |
- if (shouldSkipDrawing() && customFontNotReadyAction == DoNotPaintIfFontNotReady) |
- return nullptr; |
- |
- if (codePath(runInfo) != ComplexPath) |
- return buildTextBlobForSimpleText(runInfo, textOrigin, couldUseLCDRenderedText); |
- |
- return nullptr; |
-} |
- |
-PassTextBlobPtr Font::buildTextBlobForSimpleText(const TextRunPaintInfo& runInfo, const FloatPoint& textOrigin, bool couldUseLCDRenderedText) const |
-{ |
- GlyphBuffer glyphBuffer; |
- float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffer); |
- |
- if (glyphBuffer.isEmpty()) |
- return nullptr; |
- |
- FloatRect blobBounds = runInfo.bounds; |
- blobBounds.moveBy(-textOrigin); |
- |
- float ignoredWidth; |
- return buildTextBlob(glyphBuffer, initialAdvance, blobBounds, ignoredWidth, couldUseLCDRenderedText); |
-} |
- |
PassTextBlobPtr Font::buildTextBlob(const GlyphBuffer& glyphBuffer, float initialAdvance, |
- const FloatRect& bounds, float& advance, bool couldUseLCD) const |
+ const FloatRect& bounds, bool couldUseLCD) const |
{ |
ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
- // FIXME: Implement the more general full-positioning path. |
- ASSERT(!glyphBuffer.hasOffsets()); |
+ // FIXME: Implement the more general full-positioning path for complex text support. |
+ if (glyphBuffer.hasOffsets()) |
+ return nullptr; |
SkTextBlobBuilder builder; |
SkScalar x = SkFloatToScalar(initialAdvance); |
@@ -271,7 +323,6 @@ PassTextBlobPtr Font::buildTextBlob(const GlyphBuffer& glyphBuffer, float initia |
} |
} |
- advance = x; |
return adoptRef(builder.build()); |
} |
@@ -694,57 +745,6 @@ int Font::emphasisMarkHeight(const AtomicString& mark) const |
return markFontData->fontMetrics().height(); |
} |
-float Font::getGlyphsAndAdvancesForSimpleText(const TextRunPaintInfo& runInfo, |
- GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const |
-{ |
- float initialAdvance; |
- |
- SimpleShaper shaper(this, runInfo.run, 0 /* fallbackFonts */, |
- 0 /* GlyphBounds */, forTextEmphasis); |
- shaper.advance(runInfo.from); |
- float beforeWidth = shaper.runWidthSoFar(); |
- shaper.advance(runInfo.to, &glyphBuffer); |
- |
- if (glyphBuffer.isEmpty()) |
- return 0; |
- |
- float afterWidth = shaper.runWidthSoFar(); |
- |
- if (runInfo.run.rtl()) { |
- shaper.advance(runInfo.run.length()); |
- initialAdvance = shaper.runWidthSoFar() - afterWidth; |
- glyphBuffer.reverse(); |
- } else { |
- initialAdvance = beforeWidth; |
- } |
- |
- return initialAdvance; |
-} |
- |
-float Font::drawSimpleText(GraphicsContext* context, const TextRunPaintInfo& runInfo, const FloatPoint& point) const |
-{ |
- // This glyph buffer holds our glyphs+advances+font data for each glyph. |
- GlyphBuffer glyphBuffer; |
- float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffer); |
- |
- if (glyphBuffer.isEmpty()) |
- return 0; |
- |
- FloatPoint startPoint(point.x() + initialAdvance, point.y()); |
- return drawGlyphBuffer(context, runInfo, glyphBuffer, startPoint); |
-} |
- |
-void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRunPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const |
-{ |
- GlyphBuffer glyphBuffer; |
- float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffer, ForTextEmphasis); |
- |
- if (glyphBuffer.isEmpty()) |
- return; |
- |
- drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y())); |
-} |
- |
static SkPaint textFillPaint(GraphicsContext* gc, const SimpleFontData* font) |
{ |
SkPaint paint = gc->fillPaint(); |
@@ -873,12 +873,10 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, |
} |
ASSERT(glyphBuffer.hasOffsets()); |
- const GlyphBufferWithOffsets& glyphBufferWithOffsets = |
- static_cast<const GlyphBufferWithOffsets&>(glyphBuffer); |
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); |
SkPoint* pos = storage.get(); |
- const FloatSize* offsets = glyphBufferWithOffsets.offsets(from); |
- const float* advances = glyphBufferWithOffsets.advances(from); |
+ const FloatSize* offsets = glyphBuffer.offsets(from); |
+ const float* advances = glyphBuffer.advances(from); |
SkScalar advanceSoFar = SkFloatToScalar(0); |
for (unsigned i = 0; i < numGlyphs; i++) { |
pos[i].set( |
@@ -887,7 +885,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, |
advanceSoFar += SkFloatToScalar(advances[i]); |
} |
- const Glyph* glyphs = glyphBufferWithOffsets.glyphs(from); |
+ const Glyph* glyphs = glyphBuffer.glyphs(from); |
paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect); |
} |
@@ -907,46 +905,6 @@ void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi |
} |
} |
-float Font::drawComplexText(GraphicsContext* gc, const TextRunPaintInfo& runInfo, const FloatPoint& point) const |
-{ |
- if (!runInfo.run.length()) |
- return 0; |
- |
- TextDrawingModeFlags textMode = gc->textDrawingMode(); |
- bool fill = textMode & TextModeFill; |
- bool stroke = (textMode & TextModeStroke) && gc->hasStroke(); |
- |
- if (!fill && !stroke) |
- return 0; |
- |
- GlyphBufferWithOffsets glyphBuffer; |
- HarfBuzzShaper shaper(this, runInfo.run); |
- shaper.setDrawRange(runInfo.from, runInfo.to); |
- if (!shaper.shape(&glyphBuffer) || glyphBuffer.isEmpty()) |
- return 0; |
- return drawGlyphBuffer(gc, runInfo, glyphBuffer, point); |
-} |
- |
-void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRunPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const |
-{ |
- GlyphBuffer glyphBuffer; |
- |
- float initialAdvance = getGlyphsAndAdvancesForComplexText(runInfo, glyphBuffer, ForTextEmphasis); |
- |
- if (glyphBuffer.isEmpty()) |
- return; |
- |
- drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y())); |
-} |
- |
-float Font::getGlyphsAndAdvancesForComplexText(const TextRunPaintInfo& runInfo, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const |
-{ |
- HarfBuzzShaper shaper(this, runInfo.run, HarfBuzzShaper::ForTextEmphasis); |
- shaper.setDrawRange(runInfo.from, runInfo.to); |
- shaper.shape(&glyphBuffer); |
- return 0; |
-} |
- |
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, IntRectExtent* glyphBounds) const |
{ |
HarfBuzzShaper shaper(this, run, HarfBuzzShaper::NotForTextEmphasis, fallbackFonts); |