From b983e6baa1db462a047e14ed83be759f2361838c Mon Sep 17 00:00:00 2001 From: Herb Derby Date: Fri, 13 Jul 2018 13:26:29 -0400 Subject: [PATCH] Device interface uses glyph run list Have devices just treat all runs as drawPosText except for SkGPUDevice and SkRemoteGlyphCache. Those two just pass the blob to the old code. This way the change over from blobs to run lists can happen in smaller steps. Change-Id: I3407bffeafe7fbd1c369f6b3c3db8d64b4b6c3b1 Reviewed-on: https://skia-review.googlesource.com/141300 Reviewed-by: Ben Wagner Commit-Queue: Herb Derby --- src/core/SkCanvas.cpp | 9 +++++---- src/core/SkDevice.cpp | 14 +++++++++++--- src/core/SkDevice.h | 15 ++++++++------- src/core/SkGlyphRun.cpp | 5 ++--- src/core/SkGlyphRun.h | 7 ++++--- src/core/SkRemoteGlyphCache.cpp | 13 +++++++++++++ src/core/SkTypeface_remote.h | 3 +-- src/gpu/SkGpuDevice.cpp | 16 ++++++++++++++++ src/gpu/SkGpuDevice.h | 1 + src/pdf/SkPDFDevice.cpp | 12 ++++++++++++ src/pdf/SkPDFDevice.h | 1 + 11 files changed, 74 insertions(+), 22 deletions(-) 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,