diff options
Diffstat (limited to 'src/core/SkGlyphRun.h')
-rw-r--r-- | src/core/SkGlyphRun.h | 104 |
1 files changed, 70 insertions, 34 deletions
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 243d5d121c..1b41da5350 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -24,36 +24,32 @@ template <typename T> class SkSpan { public: 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]; } + SkSpan(T* ptr, size_t size) : fPtr{ptr}, fSize{size} {} + explicit SkSpan(std::vector<T>& v) : fPtr{v.data()}, fSize{v.size()} {} + SkSpan& operator=( const SkSpan& other ) = default; + T& operator [] (ptrdiff_t i) const { return fPtr[i]; } 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; } + T* data() const { return fPtr; } ptrdiff_t size() const { return fSize; } bool empty() const { return fSize == 0; } private: - const T* fPtr; + T* fPtr; size_t fSize; }; class SkGlyphRun { public: SkGlyphRun() = default; - SkGlyphRun(SkSpan<uint16_t> denseIndex, - SkSpan<SkPoint> positions, - SkSpan<SkGlyphID> scratchGlyphs, - SkSpan<SkGlyphID> uniqueGlyphIDs) - : fDenseIndex{denseIndex} - , fPositions{positions} - , fTemporaryShuntGlyphIDs{scratchGlyphs} - , fUniqueGlyphIDs{uniqueGlyphIDs} { - SkASSERT(denseIndex.size() == positions.size()); - SkASSERT(denseIndex.size() == scratchGlyphs.size()); - } + SkGlyphRun(SkSpan<uint16_t> denseIndex, + SkSpan<SkPoint> positions, + SkSpan<SkGlyphID> scratchGlyphs, + SkSpan<SkGlyphID> uniqueGlyphIDs, + SkSpan<const char> text, + SkSpan<uint32_t> clusters); // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs // are developed. @@ -67,19 +63,43 @@ public: private: // Indices into the unique glyph IDs. On for each original glyph. - const SkSpan<uint16_t> fDenseIndex; + const SkSpan<uint16_t> fDenseIndex; // The base line position of all the glyphs in source space. - const SkSpan<SkPoint> fPositions; + const SkSpan<SkPoint> fPositions; // This is temporary while converting from the old per glyph code to the bulk code. - const SkSpan<SkGlyphID> fTemporaryShuntGlyphIDs; + const SkSpan<SkGlyphID> fTemporaryShuntGlyphIDs; // The set of unique glyphs in the run. - const SkSpan<SkGlyphID> fUniqueGlyphIDs; + 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. + const SkSpan<uint32_t> fClusters; +}; + +class SkGlyphRunList { + const uint64_t fUniqueID{0}; + SkSpan<SkGlyphRun> fGlyphRuns; + +public: + SkGlyphRunList() = default; + SkGlyphRunList(SkSpan<SkGlyphRun> glyphRuns, uint64_t uniqueID); + + uint64_t uniqueID() const { return fUniqueID; } + + 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 operator [] (ptrdiff_t i) -> decltype(fGlyphRuns[i]) { return fGlyphRuns[i]; } }; // A faster set implementation that does not need any initialization, and reading the set items // is order the number of items, and not the size of the universe. // This implementation is based on the paper by Briggs and Torczon, "An Efficient Representation // for Sparse Sets" +// +// This implementation assumes that the unique glyphs added are appended to a vector that may +// already have unique glyph from a previous computation. This allows the packing of multiple +// UniqueID sequences in a single vector. class SkGlyphSet { public: SkGlyphSet() = default; @@ -87,15 +107,13 @@ public: void reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqueGlyphIDs); private: + uint32_t uniqueSize(); uint32_t fUniverseSize{0}; + size_t fStartOfUniqueIDs{0}; std::vector<uint16_t> fIndices; std::vector<SkGlyphID>* fUniqueGlyphIDs{nullptr}; }; -// Currently the old code is passing around SkGlyphRunBuilder because it facilitates working in the -// old single glyph lookup style with the cache. When the lower level code is transitioned over to -// the bulk glyph cache style, then the builder will only be used in the canvas, and only runs will -// be passed around. class SkGlyphRunBuilder { public: SkGlyphRunBuilder() = default; @@ -106,32 +124,50 @@ public: const SkScalar xpos[], SkScalar constY); void prepareDrawPosText( const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint pos[]); + void prepareTextBlob(const SkPaint& paint, const SkTextBlob& blob, SkPoint origin); - size_t runSize() const {return fDenseIndex.size();} - size_t uniqueSize() const {return fUniqueGlyphs.size();} - + SkGlyphRunList* useGlyphRunList(); SkGlyphRun* useGlyphRun(); private: - void initializeDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength); + size_t runSize() const; + size_t uniqueSize() const; + void initialize(); + SkGlyphID* addDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength); + void addGlyphRunToList( + SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters); + + void drawText( + const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin, + SkSpan<const char> text, SkSpan<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); + void drawPosText( + const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint* pos, + SkSpan<const char> text, SkSpan<uint32_t> clusters); + + uint64_t fUniqueID{0}; std::vector<uint16_t> fDenseIndex; std::vector<SkPoint> fPositions; std::vector<SkGlyphID> fUniqueGlyphs; + size_t fLastDenseIndex{0}; + size_t fLastUniqueIndex{0}; + // Used as a temporary for preparing using utfN text. std::vector<SkGlyphID> fScratchGlyphIDs; // Used as temporary storage for calculating positions for drawText. std::vector<SkPoint> fScratchAdvances; - // Used to temporarily use of a glyph run for bulk cache API calls (just an experiment at - // this point). - SkGlyphRun fScratchGlyphRun; + // Vector for accumulating runs. This is later deposited in fScratchGlyphRunList; + std::vector<SkGlyphRun> fGlyphRuns; - // Used as an aid to shunt from glyph runs to drawPosText. It will either be fScratchIDs or - // the bytes passed in. - const SkGlyphID* fTemporaryShuntGlyphIDs{nullptr}; + // Used as temporary glyph run for the rest of the Text stack. + SkGlyphRunList fScratchGlyphRunList; // Used for collecting the set of unique glyphs. SkGlyphSet fGlyphSet; |