aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGlyphRun.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkGlyphRun.h')
-rw-r--r--src/core/SkGlyphRun.h104
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;