aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGlyphRun.h
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-06-07 12:44:09 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-08 19:25:43 +0000
commit59d997a6e1d32f2d0a3021931aed87984d15a7ee (patch)
treee5f920dc6f1b33b4fcde0f1058738512e376021b /src/core/SkGlyphRun.h
parentf0aacafe9e7a74475493c71c4c3679e80a8b2a82 (diff)
New more efficient run builder
A system for building glyph runs. In the future the builder will only live in canvas, but it's internal structures facilitate interacting with the cache a single glyph at a time. When all the bulk code is in place, only runs will be passed around. Passing the builder down the text draw stack is temporary. Change-Id: I6e3ed184b3f3a58b919377f2d31936e971bd8efa Reviewed-on: https://skia-review.googlesource.com/132928 Reviewed-by: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkGlyphRun.h')
-rw-r--r--src/core/SkGlyphRun.h124
1 files changed, 81 insertions, 43 deletions
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index 53d57af8c4..eeb9c2924e 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -8,6 +8,7 @@
#ifndef SkGlyphRunInfo_DEFINED
#define SkGlyphRunInfo_DEFINED
+#include <functional>
#include <memory>
#include <vector>
@@ -17,6 +18,43 @@
#include "SkPoint.h"
#include "SkTypes.h"
+class SkBaseDevice;
+
+template <typename T>
+class SkSpan {
+public:
+ SkSpan() = default;
+ 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; }
+ ptrdiff_t size() const { return fSize; }
+
+private:
+ const T* fPtr;
+ size_t fSize;
+};
+
+class SkGlyphRun {
+public:
+ SkGlyphRun() = default;
+ SkGlyphRun(SkSpan<uint16_t> denseIndex, SkSpan<SkPoint> positions,
+ SkSpan<SkGlyphID> uniqueGlyphIDs)
+ : fDenseIndex{denseIndex}
+ , fPositions{positions}
+ , fUniqueGlyphIDs{uniqueGlyphIDs} {}
+
+ 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;
+};
+
// 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
@@ -25,63 +63,63 @@ class SkGlyphSet {
public:
SkGlyphSet() = default;
uint16_t add(SkGlyphID glyphID);
- std::vector<SkGlyphID> uniqueGlyphIDs();
- void reuse(uint32_t glyphUniverseSize);
+ void reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqueGlyphIDs);
private:
uint32_t fUniverseSize{0};
std::vector<uint16_t> fIndices;
- std::vector<SkGlyphID> fUniqueGlyphIDs;
+ std::vector<SkGlyphID>* fUniqueGlyphIDs{nullptr};
};
-class SkGlyphRun {
+// 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:
- SkGlyphRun() = default;
- SkGlyphRun(SkGlyphRun&&) = default;
- static SkGlyphRun MakeFromDrawText(
+ SkGlyphRunBuilder() = default;
+ void prepareDrawText(
+ const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin);
+ void prepareDrawPosTextH(
const SkPaint& paint, const void* bytes, size_t byteLength,
- SkPoint origin, SkGlyphSet* glyphSet);
- static SkGlyphRun MakeFromDrawPosTextH(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkScalar xpos[], SkScalar constY, SkGlyphSet* glyphSet);
- static SkGlyphRun MakeFromDrawPosText(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkPoint pos[], SkGlyphSet* glyphSet);
+ const SkScalar xpos[], SkScalar constY);
+ void prepareDrawPosText(
+ const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint pos[]);
+
+ size_t runSize() const {return fDenseIndex.size();}
+ size_t uniqueSize() const {return fUniqueGlyphs.size();}
- size_t runSize() const { return fRunSize; }
- uint16_t uniqueSize() const { return fUniqueGlyphs.size(); }
+ const SkGlyphRun& useGlyphRun() const;
- // copyGlyphIDs is temporary glue to work with the existing system. Don't use with new code.
- std::unique_ptr<SkGlyphID[]> copyGlyphIDs() const;
- const SkScalar* getPositions() const {
- return reinterpret_cast<const SkScalar*>(fPositions.get());
- }
+ // 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);
private:
- SkGlyphRun(size_t runSize,
- std::unique_ptr<uint16_t[]>&& denseIndex,
- std::unique_ptr<SkPoint[]>&& positions,
- std::vector<SkGlyphID>&& uniqueGlyphIDs);
-
- std::unique_ptr<uint16_t[]> fDenseIndex;
- std::unique_ptr<SkPoint[]> fPositions;
- std::vector<SkGlyphID> fUniqueGlyphs;
- const size_t fRunSize{0};
-};
+ void initializeDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength);
-template <typename T>
-class SkSpan {
-public:
- SkSpan(const T* ptr, size_t size) : fPtr{ptr}, fSize{size} {}
- 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; }
- ptrdiff_t size() const { return fSize; }
+ std::vector<uint16_t> fDenseIndex;
+ std::vector<SkPoint> fPositions;
+ std::vector<SkGlyphID> fUniqueGlyphs;
-private:
- const T* fPtr;
- size_t fSize;
+ // 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;
+
+ // 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 for collecting the set of unique glyphs.
+ SkGlyphSet fGlyphSet;
};
#endif // SkGlyphRunInfo_DEFINED