diff options
author | Herb Derby <herb@google.com> | 2018-07-09 15:53:57 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-10 16:57:25 +0000 |
commit | b77822b4442d57d69835355c6c9e9a1354d65fce (patch) | |
tree | 40cc30bb3c4c5efcd2f8fa8b0c938eddb86533af | |
parent | 1d784ceafa9e0f3e32ef341900bc349f90abb81d (diff) |
Remove the SkGlyphRunInfo code
The SkGlyphRunInfo code caused most of the complication.
Maintaining the various different indices became
unwieldy.
Change-Id: Ia0a1259338c8572c57bb11d2407f5709459e0c72
Reviewed-on: https://skia-review.googlesource.com/140001
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
-rw-r--r-- | src/core/SkDevice.cpp | 4 | ||||
-rw-r--r-- | src/core/SkGlyphRun.cpp | 153 | ||||
-rw-r--r-- | src/core/SkGlyphRun.h | 98 |
3 files changed, 90 insertions, 165 deletions
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index c1359e7075..2b7fef62fb 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -165,7 +165,7 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, SkGlyphRunBuilder builder; builder.prepareDrawText(runPaint, (const char*) it.glyphs(), textLen, origin); auto glyphRun = builder.useGlyphRun(); - glyphRun->temporaryShuntToDrawPosText(runPaint, this); + glyphRun->temporaryShuntToDrawPosText(this); } break; case SkTextBlob::kHorizontal_Positioning: @@ -255,7 +255,7 @@ void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun) { SkPaint glyphPaint(paint); glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - glyphRun->temporaryShuntToDrawPosText(glyphPaint, this); + glyphRun->temporaryShuntToDrawPosText(this); } void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap, diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index fa070da3a7..426b8fbbcb 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -85,33 +85,37 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu } // -- SkGlyphRun ----------------------------------------------------------------------------------- -SkGlyphRun::SkGlyphRun(const SkIndexedRunInfo* runInfo, - size_t denseOffset, size_t denseSize, - size_t uniqueOffset, uint16_t uniqueSize, - SkSpan<SkGlyphID> scratchGlyphs, +SkGlyphRun::SkGlyphRun(SkPaint&& runPaint, + SkSpan<const uint16_t> denseIndices, + SkSpan<const SkPoint> positions, + SkSpan<const SkGlyphID> glyphIDs, + SkSpan<const SkGlyphID> uniqueGlyphIDs, SkSpan<const char> text, - SkSpan<uint32_t> clusters) - : fRunInfo{runInfo} - , fDenseOffset{denseOffset}, fDenseSize{denseSize} - , fUniqueOffset{uniqueOffset}, fUniqueSize{uniqueSize} - , fTemporaryShuntGlyphIDs{scratchGlyphs} + SkSpan<const uint32_t> clusters) + : fUniqueGlyphIDIndices{denseIndices} + , fPositions{positions} + , fTemporaryShuntGlyphIDs{glyphIDs} + , fUniqueGlyphIDs{uniqueGlyphIDs} , fText{text} - , fClusters{clusters} { } + , fClusters{clusters} + , fRunPaint{std::move(runPaint)} {} - -void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) { +void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device) { auto pos = (const SkScalar*) this->positions().data(); + auto origin = SkPoint::Make(0, 0); - device->drawPosText( - fTemporaryShuntGlyphIDs.data(), fDenseSize * sizeof(SkGlyphID), - pos, 2, SkPoint::Make(0, 0), paint); + if (!fTemporaryShuntGlyphIDs.empty()) { + device->drawPosText( + fTemporaryShuntGlyphIDs.data(), fTemporaryShuntGlyphIDs.size() * sizeof(SkGlyphID), + pos, 2, origin, fRunPaint); + } } void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) { auto bytes = (const char *)fTemporaryShuntGlyphIDs.data(); auto pos = (const SkScalar*) this->positions().data(); - callback(this->runSize(), bytes, pos); + callback(fTemporaryShuntGlyphIDs.size(), bytes, pos); } // -- SkGlyphRunBuilder ---------------------------------------------------------------------------- @@ -122,7 +126,7 @@ void SkGlyphRunBuilder::prepareDrawText( if (paint.getTextEncoding() != SkPaint::kUTF8_TextEncoding) { originalText = SkSpan<const char>(); } - this->drawText(paint, bytes, byteLength, origin, originalText, SkSpan<uint32_t>()); + this->drawText(paint, bytes, byteLength, origin, originalText, SkSpan<const uint32_t>()); } void SkGlyphRunBuilder::prepareDrawPosTextH(const SkPaint& paint, const void* bytes, @@ -130,75 +134,31 @@ void SkGlyphRunBuilder::prepareDrawPosTextH(const SkPaint& paint, const void* by SkScalar constY) { this->initialize(); this->drawPosTextH( - paint, bytes, byteLength, xpos, constY, SkSpan<const char>(), SkSpan<uint32_t>()); + paint, bytes, byteLength, xpos, constY, SkSpan<const char>(), SkSpan<const uint32_t>()); } void SkGlyphRunBuilder::prepareDrawPosText(const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint* pos) { this->initialize(); - this->drawPosText(paint, bytes, byteLength, pos, SkSpan<const char>(), SkSpan<uint32_t>()); -} - -void SkGlyphRunBuilder::prepareTextBlob( - const SkPaint& paint, const SkTextBlob& blob, SkPoint origin) { - this->initialize(); - fUniqueID = blob.uniqueID(); - - SkPaint runPaint = paint; - - for (SkTextBlobRunIterator it(&blob); !it.done(); it.next()) { - // applyFontToPaint() always overwrites the exact same attributes, - // so it is safe to not re-seed the paint for this reason. - it.applyFontToPaint(&runPaint); - - // These better be glyphs - SkASSERT(runPaint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding); - - auto text = SkSpan<const char>(it.text(), it.textSize()); - auto clusters = SkSpan<uint32_t>(it.clusters(), it.glyphCount()); - size_t glyphLen = it.glyphCount() * sizeof(SkGlyphID); - const SkPoint& offset = it.offset(); - - switch (it.positioning()) { - case SkTextBlob::kDefault_Positioning: { - auto dtOrigin = origin + offset; - this->drawText(runPaint, it.glyphs(), glyphLen, dtOrigin, text, clusters); - } - break; - case SkTextBlob::kHorizontal_Positioning: { - auto constY = origin.y() + offset.y(); - this->drawPosTextH( - runPaint, it.glyphs(), glyphLen, it.pos(), constY, text, clusters); - } - break; - case SkTextBlob::kFull_Positioning: - this->drawPosText( - runPaint, it.glyphs(), glyphLen, (const SkPoint*)it.pos(), text, clusters); - break; - default: - SK_ABORT("unhandled positioning mode"); - } - } + this->drawPosText(paint, bytes, byteLength, pos, + SkSpan<const char>(), SkSpan<const uint32_t>()); } SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() { return &fScratchGlyphRun; } -size_t SkGlyphRunBuilder::runSize() const { return fDenseIndex.size() - fLastDenseIndex; } - -size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphIDs.size() - fLastUniqueIndex; } - void SkGlyphRunBuilder::initialize() { fUniqueID = 0; fDenseIndex.clear(); fPositions.clear(); fUniqueGlyphIDs.clear(); - fLastDenseIndex = 0; - fLastUniqueIndex = 0; + + // Be sure to clean up the last run before we reuse it. + fScratchGlyphRun.~SkGlyphRun(); } -SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique( +void SkGlyphRunBuilder::addDenseAndUnique( const SkPaint& paint, const void* bytes, size_t byteLength) { size_t runSize = 0; @@ -227,50 +187,47 @@ SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique( fDenseIndex.push_back(fGlyphSet.add(glyphIDs[i])); } } - - return glyphIDs; } void SkGlyphRunBuilder::makeGlyphRun( - SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters) { + const SkPaint& runPaint, + SkSpan<const char> text, SkSpan<const uint32_t> clusters) { // Ignore empty runs. - if (fDenseIndex.size() != fLastDenseIndex) { - auto runSize = this->runSize(); - auto uniqueSize = this->uniqueSize(); + if (!fDenseIndex.empty()) { + SkPaint glyphRunPaint{runPaint}; + glyphRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + glyphRunPaint.setTextAlign(SkPaint::kLeft_Align); new ((void*)&fScratchGlyphRun) SkGlyphRun{ - &fIndexed, - fLastDenseIndex, runSize, - fLastUniqueIndex, SkTo<uint16_t>(uniqueSize), - SkSpan<SkGlyphID>(temporaryShuntGlyphIDs, runSize), + std::move(glyphRunPaint), + SkSpan<const uint16_t>{fDenseIndex}, + SkSpan<const SkPoint>{fPositions}, + SkSpan<const SkGlyphID>{fScratchGlyphIDs}, + SkSpan<const SkGlyphID>{fUniqueGlyphIDs}, text, clusters }; - - fLastDenseIndex = fDenseIndex.size(); - fLastUniqueIndex = fUniqueGlyphIDs.size(); } } void SkGlyphRunBuilder::drawText( const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin, - SkSpan<const char> text, SkSpan<uint32_t> clusters) { + SkSpan<const char> text, SkSpan<const uint32_t> clusters) { - SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength); + this->addDenseAndUnique(paint, bytes, byteLength); - fScratchAdvances.resize(this->uniqueSize()); + fScratchAdvances.resize(fUniqueGlyphIDs.size()); { auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint); - cache->getAdvances( - fIndexed.uniqueGlyphIDs(fLastUniqueIndex, uniqueSize()), fScratchAdvances.data()); + cache->getAdvances(SkSpan<const SkGlyphID>{fUniqueGlyphIDs}, fScratchAdvances.data()); } SkPoint endOfLastGlyph = origin; - for (size_t i = 0; i < this->runSize(); i++) { + for (size_t i = 0; i < fDenseIndex.size(); i++) { fPositions.push_back(endOfLastGlyph); - endOfLastGlyph += fScratchAdvances[fDenseIndex[fLastDenseIndex + i]]; + endOfLastGlyph += fScratchAdvances[fDenseIndex[i]]; } if (paint.getTextAlign() != SkPaint::kLeft_Align) { @@ -278,38 +235,38 @@ void SkGlyphRunBuilder::drawText( if (paint.getTextAlign() == SkPaint::kCenter_Align) { len.scale(SK_ScalarHalf); } - for (size_t i = fLastDenseIndex; i < this->runSize(); i++) { + for (size_t i = 0; i < fDenseIndex.size(); i++) { fPositions[i] -= len; } } - this->makeGlyphRun(temporaryShuntGlyphIDs, text, clusters); + this->makeGlyphRun(paint, text, clusters); } void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, const void* bytes, size_t byteLength, const SkScalar* xpos, SkScalar constY, - SkSpan<const char> text, SkSpan<uint32_t> clusters) { + SkSpan<const char> text, SkSpan<const uint32_t> clusters) { - SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength); + this->addDenseAndUnique(paint, bytes, byteLength); - for (size_t i = 0; i < runSize(); i++) { + for (size_t i = 0; i < fDenseIndex.size(); i++) { fPositions.push_back(SkPoint::Make(xpos[i], constY)); } - this->makeGlyphRun(temporaryShuntGlyphIDs, text, clusters); + this->makeGlyphRun(paint, text, clusters); } void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint* pos, - SkSpan<const char> text, SkSpan<uint32_t> clusters) { - SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength); + SkSpan<const char> text, SkSpan<const uint32_t> clusters) { + this->addDenseAndUnique(paint, bytes, byteLength); - for (size_t i = 0; i < runSize(); i++) { + for (size_t i = 0; i < fDenseIndex.size(); i++) { fPositions.push_back(pos[i]); } - this->makeGlyphRun(temporaryShuntGlyphIDs, text, clusters); + this->makeGlyphRun(paint, text, clusters); } diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 653b1f9ae1..d3f8c07cab 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -25,7 +25,8 @@ class SkSpan { public: SkSpan() : fPtr{nullptr}, fSize{0} {} SkSpan(T* ptr, ptrdiff_t size) : fPtr{ptr}, fSize{size} { SkASSERT(size >= 0); } - explicit SkSpan(std::vector<T>& v) : fPtr{v.data()}, fSize{SkTo<ptrdiff_t>(v.size())} {} + template <typename U> + explicit SkSpan(std::vector<U>& v) : fPtr{v.data()}, fSize{SkTo<ptrdiff_t>(v.size())} {} SkSpan(const SkSpan<T>& o) = default; SkSpan& operator=( const SkSpan& other ) = default; T& operator [] (ptrdiff_t i) const { return fPtr[i]; } @@ -42,70 +43,44 @@ private: ptrdiff_t fSize; }; -struct SkIndexedRunInfo { - SkIndexedRunInfo(const std::vector<uint16_t>* denseIndex, - const std::vector<SkPoint>* positions, - const std::vector<SkGlyphID>* uniqueGlyphIDs) - : fDenseIndex{denseIndex} - , fPositions{positions} - , fUniqueGlyphIDs{uniqueGlyphIDs} {} - - SkSpan<const uint16_t> denseIndex(size_t start, size_t size) { - return SkSpan<const uint16_t>(&(*fDenseIndex)[start], size); - } - - SkSpan<const SkPoint> positions(size_t start, size_t size) const { - return SkSpan<const SkPoint>(&(*fPositions)[start], size); - } - - SkSpan<const SkGlyphID> uniqueGlyphIDs(size_t start, size_t size) const { - return SkSpan<const SkGlyphID>(&(*fUniqueGlyphIDs)[start], size); - } - -private: - const std::vector<uint16_t>* fDenseIndex; - const std::vector<SkPoint>* fPositions; - const std::vector<SkGlyphID>* fUniqueGlyphIDs; -}; - class SkGlyphRun { public: SkGlyphRun() = default; - SkGlyphRun(const SkIndexedRunInfo* runInfo, - size_t denseOffset, size_t denseSize, - size_t fUniqueOffset, uint16_t fUniqueSize, - SkSpan<SkGlyphID> scratchGlyphs, + SkGlyphRun(SkPaint&& runPaint, + SkSpan<const uint16_t> denseIndices, + SkSpan<const SkPoint> positions, + SkSpan<const SkGlyphID> glyphIDs, + SkSpan<const SkGlyphID> uniqueGlyphIDs, SkSpan<const char> text, - SkSpan<uint32_t> clusters); + SkSpan<const uint32_t> clusters); // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs // are developed. - void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device); + void temporaryShuntToDrawPosText(SkBaseDevice* device); using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>; void temporaryShuntToCallback(TemporaryShuntCallback callback); - size_t runSize() const { return fDenseSize; } - uint16_t uniqueSize() const { return fUniqueSize; } - SkSpan<const SkPoint> positions() const { - return fRunInfo->positions(fDenseOffset, fDenseSize); - } - SkSpan<const SkGlyphID> uniqueGlyphIDs() const { - return fRunInfo->uniqueGlyphIDs(fUniqueOffset, fUniqueSize); - } + size_t runSize() const { return fUniqueGlyphIDIndices.size(); } + uint16_t uniqueSize() const { return fUniqueGlyphIDs.size(); } + SkSpan<const SkPoint> positions() const { return fPositions; } + SkSpan<const SkGlyphID> uniqueGlyphIDs() const { return fUniqueGlyphIDs; } + SkSpan<const SkGlyphID> shuntGlyphsIDs() const { return fTemporaryShuntGlyphIDs; } private: - const SkIndexedRunInfo* fRunInfo; - size_t fDenseOffset; - size_t fDenseSize; - size_t fUniqueOffset; - uint16_t fUniqueSize; - + // + const SkSpan<const uint16_t> fUniqueGlyphIDIndices; + // + const SkSpan<const SkPoint> fPositions; // This is temporary while converting from the old per glyph code to the bulk code. - const SkSpan<SkGlyphID> fTemporaryShuntGlyphIDs; + const SkSpan<const SkGlyphID> fTemporaryShuntGlyphIDs; + // The unique glyphs from fTemporaryShuntGlyphIDs. + const SkSpan<const SkGlyphID> fUniqueGlyphIDs; // Original text from SkTextBlob if present. Will be empty of not present. const SkSpan<const char> fText; // Original clusters from SkTextBlob if present. Will be empty if not present. - const SkSpan<uint32_t> fClusters; + const SkSpan<const uint32_t> fClusters; + // Paint for this run modified to have glyph encoding and left alignment. + const SkPaint fRunPaint; }; // A faster set implementation that does not need any initialization, and reading the set items @@ -145,41 +120,34 @@ public: SkGlyphRun* useGlyphRun(); private: - size_t runSize() const; - size_t uniqueSize() const; void initialize(); - SkGlyphID* addDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength); + void addDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength); void makeGlyphRun( - SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters); + const SkPaint& runPaint, SkSpan<const char> text, SkSpan<const uint32_t> clusters); void drawText( const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin, - SkSpan<const char> text, SkSpan<uint32_t> clusters); + SkSpan<const char> text, SkSpan<const uint32_t> clusters); void drawPosTextH( const SkPaint& paint, const void* bytes, size_t byteLength, const SkScalar* xpos, SkScalar constY, - SkSpan<const char> text, SkSpan<uint32_t> clusters); + SkSpan<const char> text, SkSpan<const uint32_t> clusters); void drawPosText( const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint* pos, - SkSpan<const char> text, SkSpan<uint32_t> clusters); + SkSpan<const char> text, SkSpan<const uint32_t> clusters); - uint64_t fUniqueID{0}; + uint64_t fUniqueID{0}; - std::vector<uint16_t> fDenseIndex; - std::vector<SkPoint> fPositions; + std::vector<uint16_t> fDenseIndex; + std::vector<SkPoint> fPositions; std::vector<SkGlyphID> fUniqueGlyphIDs; - SkIndexedRunInfo fIndexed{&fDenseIndex, &fPositions, &fUniqueGlyphIDs}; - - size_t fLastDenseIndex{0}; - size_t fLastUniqueIndex{0}; - // Used as a temporary for preparing using utfN text. This implies that only one run of // glyph ids will ever be needed because blobs are already glyph based. std::vector<SkGlyphID> fScratchGlyphIDs; // Used as temporary storage for calculating positions for drawText. - std::vector<SkPoint> fScratchAdvances; + std::vector<SkPoint> fScratchAdvances; // Used as temporary glyph run for the rest of the Text stack. |