diff options
-rw-r--r-- | src/core/SkCanvas.cpp | 9 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 7 | ||||
-rw-r--r-- | src/core/SkDevice.h | 4 | ||||
-rw-r--r-- | src/core/SkGlyphRun.cpp | 46 | ||||
-rw-r--r-- | src/core/SkGlyphRun.h | 47 | ||||
-rw-r--r-- | src/gpu/text/GrTextContext.cpp | 11 |
6 files changed, 78 insertions, 46 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 494bd3b837..be55947efd 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2452,7 +2452,8 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca while (iter.next()) { fScratchGlyphRunBuilder->prepareDrawText(paint, text, byteLength, SkPoint::Make(x, y)); - iter.fDevice->drawGlyphRun(looper.paint(), fScratchGlyphRunBuilder.get()); + auto glyphRun = fScratchGlyphRunBuilder->useGlyphRun(); + iter.fDevice->drawGlyphRun(looper.paint(), glyphRun); } LOOPER_END @@ -2465,7 +2466,8 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint while (iter.next()) { fScratchGlyphRunBuilder->prepareDrawPosText(paint, text, byteLength, pos); - iter.fDevice->drawGlyphRun(looper.paint(), fScratchGlyphRunBuilder.get()); + auto glyphRun = fScratchGlyphRunBuilder->useGlyphRun(); + iter.fDevice->drawGlyphRun(looper.paint(), glyphRun); } LOOPER_END @@ -2478,7 +2480,8 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala while (iter.next()) { fScratchGlyphRunBuilder->prepareDrawPosTextH(paint, text, byteLength, xpos, constY); - iter.fDevice->drawGlyphRun(looper.paint(), fScratchGlyphRunBuilder.get()); + const auto& glyphRun = fScratchGlyphRunBuilder->useGlyphRun(); + iter.fDevice->drawGlyphRun(looper.paint(), glyphRun); } LOOPER_END diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index aea08c55ab..23560986bc 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -165,7 +165,8 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, auto origin = SkPoint::Make(x + offset.x(), y + offset.y()); SkGlyphRunBuilder builder; builder.prepareDrawText(runPaint, (const char*) it.glyphs(), textLen, origin); - builder.temporaryShuntToDrawPosText(runPaint, this); + auto glyphRun = builder.useGlyphRun(); + glyphRun->temporaryShuntToDrawPosText(runPaint, this); } break; case SkTextBlob::kHorizontal_Positioning: @@ -251,11 +252,11 @@ void SkBaseDevice::drawImageLattice(const SkImage* image, } } -void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRunBuilder* runBuilder) { +void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun) { SkPaint glyphPaint(paint); glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - runBuilder->temporaryShuntToDrawPosText(glyphPaint, this); + glyphRun->temporaryShuntToDrawPosText(glyphPaint, this); } void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap, diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index 25008336c6..f840cf6218 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -224,7 +224,7 @@ protected: * Does not handle text decoration. * Decorations (underline and stike-thru) will be handled by SkCanvas. */ - virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRunBuilder* info); + virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun); virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) = 0; virtual void drawShadow(const SkPath&, const SkDrawShadowRec&); @@ -348,7 +348,7 @@ private: friend class DeviceTestingAccess; // Temporarily friend the SkGlyphRunBuilder until drawPosText is gone. - friend class SkGlyphRunBuilder; + friend class SkGlyphRun; virtual void drawPosText(const void* text, size_t len, const SkScalar pos[], int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) = 0; diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index caea07a076..29c1dfdb78 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -76,6 +76,24 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu // correctly even when the fIndexes buffer is uninitialized! } +// -- SkGlyphRun ----------------------------------------------------------------------------------- + +void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) { + + auto pos = (const SkScalar*) fPositions.data(); + + device->drawPosText( + fTemporaryShuntGlyphIDs.data(), fDenseIndex.size() * sizeof(SkGlyphID), + pos, 2, SkPoint::Make(0, 0), paint); +} + +void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) { + auto bytes = (const char *)fTemporaryShuntGlyphIDs.data(); + auto pos = (const SkScalar*)fPositions.data(); + callback(this->runSize(), bytes, pos); +} + + // -- SkGlyphRunBuilder ---------------------------------------------------------------------------- void SkGlyphRunBuilder::prepareDrawText( const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin) { @@ -127,26 +145,14 @@ void SkGlyphRunBuilder::prepareDrawPosText(const SkPaint& paint, const void* byt } } -const SkGlyphRun& SkGlyphRunBuilder::useGlyphRun() const { +SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() { + fScratchGlyphRun.~SkGlyphRun(); new ((void*)&fScratchGlyphRun) SkGlyphRun{SkSpan<uint16_t>(fDenseIndex), - SkSpan<SkPoint>(fPositions), - SkSpan<SkGlyphID>(fUniqueGlyphs)}; - return fScratchGlyphRun; -} - -void SkGlyphRunBuilder::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) { - - auto pos = (const SkScalar*) fPositions.data(); - - device->drawPosText( - fTemporaryShuntGlyphIDs, fDenseIndex.size() * 2, - pos, 2, SkPoint::Make(0, 0), paint); -} - -void SkGlyphRunBuilder::temporaryShuntToCallback(TemporaryShuntCallback callback) { - auto bytes = (const char *)fTemporaryShuntGlyphIDs; - auto pos = (const SkScalar*)fPositions.data(); - callback(this->runSize(), bytes, pos); + SkSpan<SkPoint>(fPositions), + SkSpan<SkGlyphID>( + fTemporaryShuntGlyphIDs, fDenseIndex.size()), + SkSpan<SkGlyphID>(fUniqueGlyphs)}; + return &fScratchGlyphRun; } void SkGlyphRunBuilder::initializeDenseAndUnique( @@ -175,6 +181,8 @@ void SkGlyphRunBuilder::initializeDenseAndUnique( glyphIDs = (const SkGlyphID*)bytes; } + SkASSERT(glyphIDs != nullptr); + if (runSize == 0) { return; } fTemporaryShuntGlyphIDs = glyphIDs; diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index eeb9c2924e..243d5d121c 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -23,13 +23,17 @@ class SkBaseDevice; template <typename T> class SkSpan { public: - SkSpan() = default; + SkSpan() : fPtr{nullptr}, fSize{0} {} SkSpan(const T* ptr, size_t size) : fPtr{ptr}, fSize{size} {} explicit SkSpan(const std::vector<T>& v) : fPtr{v.data()}, fSize{v.size()} {} const T& operator [] (ptrdiff_t i) const { return fPtr[i]; } - const T* begin() const { return fPtr; } - const T* end() const { return fPtr + fSize; } + T* begin() const { return fPtr; } + T* end() const { return fPtr + fSize; } + const T* cbegin() const { return fPtr; } + const T* cend() const { return fPtr + fSize; } + const T* data() const { return fPtr; } ptrdiff_t size() const { return fSize; } + bool empty() const { return fSize == 0; } private: const T* fPtr; @@ -39,20 +43,37 @@ private: class SkGlyphRun { public: SkGlyphRun() = default; - SkGlyphRun(SkSpan<uint16_t> denseIndex, SkSpan<SkPoint> positions, + SkGlyphRun(SkSpan<uint16_t> denseIndex, + SkSpan<SkPoint> positions, + SkSpan<SkGlyphID> scratchGlyphs, SkSpan<SkGlyphID> uniqueGlyphIDs) : fDenseIndex{denseIndex} , fPositions{positions} - , fUniqueGlyphIDs{uniqueGlyphIDs} {} + , fTemporaryShuntGlyphIDs{scratchGlyphs} + , fUniqueGlyphIDs{uniqueGlyphIDs} { + SkASSERT(denseIndex.size() == positions.size()); + SkASSERT(denseIndex.size() == scratchGlyphs.size()); + } + + // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs + // are developed. + void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device); + using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>; + void temporaryShuntToCallback(TemporaryShuntCallback callback); size_t runSize() const { return fDenseIndex.size(); } uint16_t uniqueSize() const { return fUniqueGlyphIDs.size(); } SkSpan<SkPoint> positions() const { return SkSpan<SkPoint>(fPositions); } private: - SkSpan<uint16_t> fDenseIndex; - SkSpan<SkPoint> fPositions; - SkSpan<SkGlyphID> fUniqueGlyphIDs; + // Indices into the unique glyph IDs. On for each original glyph. + const SkSpan<uint16_t> fDenseIndex; + // The base line position of all the glyphs in source space. + const SkSpan<SkPoint> fPositions; + // This is temporary while converting from the old per glyph code to the bulk code. + const SkSpan<SkGlyphID> fTemporaryShuntGlyphIDs; + // The set of unique glyphs in the run. + const SkSpan<SkGlyphID> fUniqueGlyphIDs; }; // A faster set implementation that does not need any initialization, and reading the set items @@ -89,13 +110,7 @@ public: size_t runSize() const {return fDenseIndex.size();} size_t uniqueSize() const {return fUniqueGlyphs.size();} - const SkGlyphRun& useGlyphRun() const; - - // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs - // are developed. - void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device); - using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>; - void temporaryShuntToCallback(TemporaryShuntCallback callback); + SkGlyphRun* useGlyphRun(); private: void initializeDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength); @@ -119,7 +134,7 @@ private: const SkGlyphID* fTemporaryShuntGlyphIDs{nullptr}; // Used for collecting the set of unique glyphs. - SkGlyphSet fGlyphSet; + SkGlyphSet fGlyphSet; }; #endif // SkGlyphRunInfo_DEFINED diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp index b63b726079..6da4c0d014 100644 --- a/src/gpu/text/GrTextContext.cpp +++ b/src/gpu/text/GrTextContext.cpp @@ -217,7 +217,9 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob, builder.prepareDrawText(runPaint.skPaint(), (const char*)it.glyphs(), textLen, origin); - builder.temporaryShuntToCallback( + auto glyphRun = builder.useGlyphRun(); + + glyphRun->temporaryShuntToCallback( [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) { this->drawDFPosText( cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, @@ -250,7 +252,9 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob, builder.prepareDrawText(runPaint.skPaint(), (const char*)it.glyphs(), textLen, origin); - builder.temporaryShuntToCallback( + auto glyphRun = builder.useGlyphRun(); + + glyphRun->temporaryShuntToCallback( [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) { this->DrawBmpPosText( cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, @@ -782,8 +786,9 @@ std::unique_ptr<GrDrawOp> GrTextContext::createOp_TestingOnly(GrContext* context builder.prepareDrawText(skPaint, text, textLen, origin); sk_sp<GrTextBlob> blob; + auto glyphRun = builder.useGlyphRun(); // Use the text and textLen below, because we don't want to mess with the paint. - builder.temporaryShuntToCallback( + glyphRun->temporaryShuntToCallback( [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) { blob = textContext->makeDrawPosTextBlob( context->contextPriv().getTextBlobCache(), glyphCache, |