diff options
-rw-r--r-- | src/core/SkGlyphCache.cpp | 2 | ||||
-rw-r--r-- | src/core/SkGlyphCache.h | 2 | ||||
-rw-r--r-- | src/core/SkGlyphRun.cpp | 42 | ||||
-rw-r--r-- | src/core/SkGlyphRun.h | 63 | ||||
-rw-r--r-- | tests/GlyphRunTest.cpp | 27 |
5 files changed, 90 insertions, 46 deletions
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index e5c871fd7d..45e67f2c14 100644 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -130,7 +130,7 @@ const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType); } -void SkGlyphCache::getAdvances(SkSpan<SkGlyphID> glyphIDs, SkPoint advances[]) { +void SkGlyphCache::getAdvances(SkSpan<const SkGlyphID> glyphIDs, SkPoint advances[]) { for (ptrdiff_t i = 0; i < glyphIDs.size(); i++) { auto glyph = this->getGlyphIDAdvance(glyphIDs[i]); advances[i] = SkPoint::Make(glyph.fAdvanceX, glyph.fAdvanceY); diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index 612ddb48c6..0d979d3afa 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -68,7 +68,7 @@ public: const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y); const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y); - void getAdvances(SkSpan<SkGlyphID>, SkPoint[]); + void getAdvances(SkSpan<const SkGlyphID>, SkPoint[]); /** Return the glyphID for the specified Unichar. If the char has already been seen, use the existing cache entry. If not, ask the scalercontext to compute it for us. diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index 61909656c0..5bf1aa86f9 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -35,7 +35,6 @@ static SkTypeface::Encoding convert_encoding(SkPaint::TextEncoding encoding) { } } // namespace - // -- SkGlyphSet ---------------------------------------------------------------------------------- uint32_t SkGlyphSet::uniqueSize() { // The size is how big the vector is grown since being passed into reuse. @@ -86,34 +85,32 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu } // -- SkGlyphRun ----------------------------------------------------------------------------------- -SkGlyphRun::SkGlyphRun(SkSpan<uint16_t> denseIndex, - SkSpan<SkPoint> positions, +SkGlyphRun::SkGlyphRun(const SkIndexedRunInfo& runInfo, + size_t denseOffset, size_t denseSize, + size_t uniqueOffset, uint16_t uniqueSize, SkSpan<SkGlyphID> scratchGlyphs, - SkSpan<SkGlyphID> uniqueGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters) - : fDenseIndex{denseIndex}, fPositions{positions} + : fRunInfo{runInfo} + , fDenseOffset{denseOffset}, fDenseSize{denseSize} + , fUniqueOffset{uniqueOffset}, fUniqueSize{uniqueSize} , fTemporaryShuntGlyphIDs{scratchGlyphs} - , fUniqueGlyphIDs{uniqueGlyphIDs} , fText{text} - , fClusters{clusters} { - SkASSERT(denseIndex.size() == positions.size()); - SkASSERT(denseIndex.size() == scratchGlyphs.size()); -} + , fClusters{clusters} { } void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) { - auto pos = (const SkScalar*) fPositions.data(); + auto pos = (const SkScalar*) this->positions().data(); device->drawPosText( - fTemporaryShuntGlyphIDs.data(), fDenseIndex.size() * sizeof(SkGlyphID), + fTemporaryShuntGlyphIDs.data(), fDenseSize * 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(); + auto pos = (const SkScalar*) this->positions().data(); callback(this->runSize(), bytes, pos); } @@ -202,13 +199,13 @@ SkGlyphRunList* SkGlyphRunBuilder::useGlyphRunList() { size_t SkGlyphRunBuilder::runSize() const { return fDenseIndex.size() - fLastDenseIndex; } -size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphs.size() - fLastUniqueIndex; } +size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphIDs.size() - fLastUniqueIndex; } void SkGlyphRunBuilder::initialize() { fUniqueID = 0; fDenseIndex.clear(); fPositions.clear(); - fUniqueGlyphs.clear(); + fUniqueGlyphIDs.clear(); fGlyphRuns.clear(); fLastDenseIndex = 0; fLastUniqueIndex = 0; @@ -238,7 +235,7 @@ SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique( SkASSERT(glyphIDs != nullptr); if (runSize > 0) { - fGlyphSet.reuse(typeface->countGlyphs(), &fUniqueGlyphs); + fGlyphSet.reuse(typeface->countGlyphs(), &fUniqueGlyphIDs); for (size_t i = 0; i < runSize; i++) { fDenseIndex.push_back(fGlyphSet.add(glyphIDs[i])); } @@ -256,15 +253,15 @@ void SkGlyphRunBuilder::addGlyphRunToList( auto uniqueSize = this->uniqueSize(); fGlyphRuns.emplace_back( - SkSpan<uint16_t>(&fDenseIndex[fLastDenseIndex], runSize), - SkSpan<SkPoint>(&fPositions[fLastDenseIndex], runSize), + fIndexed, + fLastDenseIndex, runSize, + fLastUniqueIndex, uniqueSize, SkSpan<SkGlyphID>(temporaryShuntGlyphIDs, runSize), - SkSpan<SkGlyphID>(&fUniqueGlyphs[fLastDenseIndex], uniqueSize), text, clusters); fLastDenseIndex = fDenseIndex.size(); - fLastUniqueIndex = fUniqueGlyphs.size(); + fLastUniqueIndex = fUniqueGlyphIDs.size(); } } @@ -277,14 +274,15 @@ void SkGlyphRunBuilder::drawText( fScratchAdvances.resize(this->uniqueSize()); { auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint); - cache->getAdvances(SkSpan<SkGlyphID>{fUniqueGlyphs}, fScratchAdvances.data()); + cache->getAdvances( + fIndexed.uniqueGlyphIDs(fLastUniqueIndex, uniqueSize()), fScratchAdvances.data()); } SkPoint endOfLastGlyph = origin; for (size_t i = 0; i < this->runSize(); i++) { fPositions.push_back(endOfLastGlyph); - endOfLastGlyph += fScratchAdvances[fDenseIndex[i]]; + endOfLastGlyph += fScratchAdvances[fDenseIndex[fLastDenseIndex + i]]; } if (paint.getTextAlign() != SkPaint::kLeft_Align) { diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 1b41da5350..739ad0bc38 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -41,13 +41,38 @@ private: size_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(SkSpan<uint16_t> denseIndex, - SkSpan<SkPoint> positions, + SkGlyphRun(const SkIndexedRunInfo& runInfo, + size_t denseOffset, size_t denseSize, + size_t fUniqueOffset, uint16_t fUniqueSize, SkSpan<SkGlyphID> scratchGlyphs, - SkSpan<SkGlyphID> uniqueGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters); @@ -57,19 +82,24 @@ public: 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); } + 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); + } private: - // 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; + const SkIndexedRunInfo& fRunInfo; + const size_t fDenseOffset; + const size_t fDenseSize; + const size_t fUniqueOffset; + const uint16_t fUniqueSize; + // 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; // 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. @@ -152,12 +182,15 @@ private: std::vector<uint16_t> fDenseIndex; std::vector<SkPoint> fPositions; - std::vector<SkGlyphID> fUniqueGlyphs; + 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. + // 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. diff --git a/tests/GlyphRunTest.cpp b/tests/GlyphRunTest.cpp index ca97404e7c..cd2a221719 100644 --- a/tests/GlyphRunTest.cpp +++ b/tests/GlyphRunTest.cpp @@ -44,7 +44,8 @@ DEF_TEST(GlyphRunBasic, reporter) { } DEF_TEST(GlyphRunBlob, reporter) { - constexpr uint16_t count = 10; + constexpr uint16_t count = 5; + constexpr int runCount = 2; auto tf = SkTypeface::MakeFromName("monospace", SkFontStyle()); @@ -57,14 +58,14 @@ DEF_TEST(GlyphRunBlob, reporter) { font.setTextSize(1u); SkTextBlobBuilder blobBuilder; - for (int runNum = 0; runNum < 2; runNum++) { + for (int runNum = 0; runNum < runCount; runNum++) { const auto& runBuffer = blobBuilder.allocRunPosH(font, count, runNum); SkASSERT(runBuffer.utf8text == nullptr); SkASSERT(runBuffer.clusters == nullptr); for (int i = 0; i < count; i++) { - runBuffer.glyphs[i] = static_cast<SkGlyphID>(i + runNum * 10); - runBuffer.pos[i] = SkIntToScalar(i + runNum * 10); + runBuffer.glyphs[i] = static_cast<SkGlyphID>(i + runNum * count); + runBuffer.pos[i] = SkIntToScalar(i + runNum * count); } } @@ -78,9 +79,21 @@ DEF_TEST(GlyphRunBlob, reporter) { auto runList = runBuilder.useGlyphRunList(); - REPORTER_ASSERT(reporter, runList->size() == 2); + REPORTER_ASSERT(reporter, runList->size() == runCount); + int runIndex = 0; for (auto& run : *runList) { - REPORTER_ASSERT(reporter, run.runSize() == 10); - REPORTER_ASSERT(reporter, run.uniqueSize() == 10); + REPORTER_ASSERT(reporter, run.runSize() == count); + REPORTER_ASSERT(reporter, run.uniqueSize() == count); + + int index = 0; + for (auto p : run.positions()) { + if (p.x() != runIndex * count + index) { + ERRORF(reporter, "x: %g != k: %d", p.x(), runIndex * count + index); + break; + } + index += 1; + } + + runIndex += 1; } }
\ No newline at end of file |