diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 3c5ec347c7..c1f81188ce 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2432,7 +2432,7 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca fScratchGlyphRunBuilder->drawText( looper.paint(), text, byteLength, SkPoint::Make(x, y)); auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList(); - iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList); + iter.fDevice->drawGlyphRunList(glyphRunList); } LOOPER_END @@ -2446,7 +2446,7 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint while (iter.next()) { fScratchGlyphRunBuilder->drawPosText(looper.paint(), text, byteLength, pos); auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList(); - iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList); + iter.fDevice->drawGlyphRunList(glyphRunList); } LOOPER_END @@ -2461,7 +2461,7 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala fScratchGlyphRunBuilder->drawPosTextH( looper.paint(), text, byteLength, xpos, constY); auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList(); - iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList); + iter.fDevice->drawGlyphRunList(glyphRunList); } LOOPER_END @@ -2511,7 +2511,8 @@ void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, LOOPER_BEGIN(paint, bounds) while (iter.next()) { - iter.fDevice->drawTextBlob(blob, x, y, looper.paint()); + fScratchGlyphRunBuilder->drawTextBlob(looper.paint(), *blob, SkPoint::Make(x, y)); + iter.fDevice->drawGlyphRunList(fScratchGlyphRunBuilder->useGlyphRunList()); } LOOPER_END diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index a4482a19ec..2296d359da 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -158,7 +158,7 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, SkGlyphRunBuilder builder; builder.drawText(runPaint, (const char*) it.glyphs(), textLen, origin); auto glyphRunList = builder.useGlyphRunList(); - glyphRunList->temporaryShuntToDrawPosText(this); + glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0)); } break; case SkTextBlob::kHorizontal_Positioning: @@ -239,8 +239,16 @@ void SkBaseDevice::drawImageLattice(const SkImage* image, } } -void SkBaseDevice::drawGlyphRunList(const SkPaint& paint, SkGlyphRunList* glyphRunList) { - glyphRunList->temporaryShuntToDrawPosText(this); +void SkBaseDevice::drawGlyphRunList(SkGlyphRunList* glyphRunList) { + auto blob = glyphRunList->blob(); + + if (blob == nullptr) { + glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0)); + } else { + auto origin = glyphRunList->origin(); + auto paint = glyphRunList->paint(); + this->drawTextBlob(blob, origin.x(), origin.y(), paint); + } } void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap, diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index 2a33822b1e..345b90548b 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -218,17 +218,12 @@ protected: virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&, const SkRect& dst, const SkPaint&); - /** - * Does not handle text decoration. - * Decorations (underline and stike-thru) will be handled by SkCanvas. - */ - virtual void drawGlyphRunList(const SkPaint& paint, SkGlyphRunList* glyphRunList); + virtual void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode, const SkPaint&) = 0; virtual void drawShadow(const SkPath&, const SkDrawShadowRec&); - // default implementation unrolls the blob runs. - virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint& paint); + virtual void drawGlyphRunList(SkGlyphRunList* glyphRunList); // default implementation calls drawVertices virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint); @@ -346,10 +341,16 @@ private: // Temporarily friend the SkGlyphRunBuilder until drawPosText is gone. friend class SkGlyphRun; + friend class SkGlyphRunList; virtual void drawPosText(const void* text, size_t len, const SkScalar pos[], int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) = 0; + // Does not handle text decoration. + // Decorations (underline and stike-thru) will be handled by SkCanvas. + // default implementation unrolls the blob runs. + virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint& paint); + // used to change the backend's pixels (and possibly config/rowbytes) // but cannot change the width/height, so there should be no change to // any clip information. diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index 6cb458544f..549dce8ee8 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -51,10 +51,9 @@ SkGlyphRun::SkGlyphRun(SkPaint&& runPaint, , fClusters{clusters} , fRunPaint{std::move(runPaint)} {} -void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device) { +void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin) { auto pos = (const SkScalar*) this->positions().data(); - auto origin = SkPoint::Make(0, 0); if (!fTemporaryShuntGlyphIDs.empty()) { device->drawPosText( @@ -442,7 +441,7 @@ size_t SkGlyphRunBuilder::simplifyDrawPosText( uniqueGlyphIDs, text, clusters); - return 0; + return uniqueGlyphIDs.size(); } diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 4b392fda0f..c220a26424 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -56,7 +56,7 @@ public: // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs // are developed. - void temporaryShuntToDrawPosText(SkBaseDevice* device); + void temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin); using TemporaryShuntCallback = std::function; void temporaryShuntToCallback(TemporaryShuntCallback callback); @@ -114,15 +114,16 @@ public: SkPoint origin() const { return fOrigin; } const SkPaint& paint() const { return *fOriginalPaint; } + const SkTextBlob* blob() const { return fOriginalTextBlob; } auto begin() -> decltype(fGlyphRuns.begin()) { return fGlyphRuns.begin(); } auto end() -> decltype(fGlyphRuns.end()) { return fGlyphRuns.end(); } auto size() -> decltype(fGlyphRuns.size()) { return fGlyphRuns.size(); } auto empty() -> decltype(fGlyphRuns.empty()) { return fGlyphRuns.empty(); } auto operator [] (size_t i) -> decltype(fGlyphRuns[i]) { return fGlyphRuns[i]; } - void temporaryShuntToDrawPosText(SkBaseDevice* device) { + void temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin) { for (auto& run : fGlyphRuns) { - run.temporaryShuntToDrawPosText(device); + run.temporaryShuntToDrawPosText(device, origin); } } diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp index d2c0cf8ced..4ed9cf287a 100644 --- a/src/core/SkRemoteGlyphCache.cpp +++ b/src/core/SkRemoteGlyphCache.cpp @@ -256,6 +256,19 @@ protected: } } + void drawGlyphRunList(SkGlyphRunList* glyphRunList) override { + auto blob = glyphRunList->blob(); + + SkASSERT(blob != nullptr); + + if (blob != nullptr) { + auto origin = glyphRunList->origin(); + auto paint = glyphRunList->paint(); + this->drawTextBlob(blob, origin.x(), origin.y(), paint); + } + } + + private: void processGlyphRun(const SkPoint& position, const SkTextBlobRunIterator& it, diff --git a/src/core/SkTypeface_remote.h b/src/core/SkTypeface_remote.h index c751745b0f..74dbb4d124 100644 --- a/src/core/SkTypeface_remote.h +++ b/src/core/SkTypeface_remote.h @@ -129,8 +129,7 @@ protected: return 0; } int onCountGlyphs() const override { - SK_ABORT("Should never be called."); - return 0; + return this->glyphCount(); } void* onGetCTFontRef() const override { diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index cc21397e12..fc5638f6a7 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1647,6 +1647,22 @@ void SkGpuDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, this->devClipBounds()); } +void SkGpuDevice::drawGlyphRunList(SkGlyphRunList* glyphRunList) { + ASSERT_SINGLE_OWNER + GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawGlyphRunList", fContext.get()); + SkDEBUGCODE(this->validate();) + + auto blob = glyphRunList->blob(); + + if (blob == nullptr) { + glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0)); + } else { + auto origin = glyphRunList->origin(); + auto paint = glyphRunList->paint(); + this->drawTextBlob(blob, origin.x(), origin.y(), paint); + } +} + /////////////////////////////////////////////////////////////////////////////// void SkGpuDevice::flush() { diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 8d360c2813..fce3ea58d2 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -90,6 +90,7 @@ public: void drawPosText(const void* text, size_t len, const SkScalar pos[], int scalarsPerPos, const SkPoint& offset, const SkPaint&) override; void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint& paint) override; + void drawGlyphRunList(SkGlyphRunList* glyphRunList) override; void drawVertices(const SkVertices*, const SkMatrix bones[], int boneCount, SkBlendMode, const SkPaint&) override; void drawShadow(const SkPath&, const SkDrawShadowRec&) override; diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index a933972009..46dff0722a 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -1457,6 +1457,18 @@ void SkPDFDevice::drawPosText(const void* text, size_t len, offset, paint, nullptr, 0, nullptr); } +void SkPDFDevice::drawGlyphRunList(SkGlyphRunList* glyphRunList) { + auto blob = glyphRunList->blob(); + + if (blob == nullptr) { + glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0)); + } else { + auto origin = glyphRunList->origin(); + auto paint = glyphRunList->paint(); + this->drawTextBlob(blob, origin.x(), origin.y(), paint); + } +} + void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint &paint) { for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) { diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h index 6077aafd7a..1691baa51e 100644 --- a/src/pdf/SkPDFDevice.h +++ b/src/pdf/SkPDFDevice.h @@ -98,6 +98,7 @@ public: const SkScalar pos[], int scalarsPerPos, const SkPoint& offset, const SkPaint&) override; void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint &) override; + void drawGlyphRunList(SkGlyphRunList* glyphRunList) override; void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode, const SkPaint&) override; void drawDevice(SkBaseDevice*, int x, int y,