diff options
-rw-r--r-- | include/core/SkTextBlob.h | 3 | ||||
-rw-r--r-- | src/core/SkGlyphRun.cpp | 5 | ||||
-rw-r--r-- | src/core/SkGlyphRun.h | 4 | ||||
-rw-r--r-- | src/core/SkTextBlob.cpp | 21 | ||||
-rw-r--r-- | tests/TextBlobTest.cpp | 16 |
5 files changed, 48 insertions, 1 deletions
diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h index 40d5130907..8dce082512 100644 --- a/include/core/SkTextBlob.h +++ b/include/core/SkTextBlob.h @@ -36,6 +36,9 @@ public: */ uint32_t uniqueID() const { return fUniqueID; } + static sk_sp<SkTextBlob> MakeAsDrawText( + const void* text, size_t byteLength, const SkPaint& paint); + enum GlyphPositioning : uint8_t { kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index 549dce8ee8..3548dfa203 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -68,6 +68,11 @@ void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) { callback(fTemporaryShuntGlyphIDs.size(), bytes, pos); } +void SkGlyphRun::filloutGlyphsAndPositions(SkGlyphID* glyphIDs, SkPoint* positions) { + memcpy(glyphIDs, fTemporaryShuntGlyphIDs.data(), fTemporaryShuntGlyphIDs.size_bytes()); + memcpy(positions, fPositions.data(), fPositions.size_bytes()); +} + // -- SkGlyphRunList ------------------------------------------------------------------------------- SkGlyphRunList::SkGlyphRunList( const SkPaint& paint, diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index c220a26424..001c3c4548 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -37,6 +37,7 @@ public: T* data() const { return fPtr; } size_t size() const { return fSize; } bool empty() const { return fSize == 0; } + size_t size_bytes() const { return fSize * sizeof(T); } private: T* fPtr; @@ -59,8 +60,9 @@ public: void temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin); using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>; void temporaryShuntToCallback(TemporaryShuntCallback callback); + void filloutGlyphsAndPositions(SkGlyphID* glyphIDs, SkPoint* positions); - size_t runSize() const { return fUniqueGlyphIDIndices.size(); } + size_t runSize() const { return fTemporaryShuntGlyphIDs.size(); } SkSpan<const SkPoint> positions() const { return fPositions; } const SkPaint& paint() const { return fRunPaint; } diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp index dd2f7bd1dd..fec7c527a2 100644 --- a/src/core/SkTextBlob.cpp +++ b/src/core/SkTextBlob.cpp @@ -7,6 +7,7 @@ #include "SkTextBlobRunIterator.h" +#include "SkGlyphRun.h" #include "SkPaintPriv.h" #include "SkReadBuffer.h" #include "SkSafeMath.h" @@ -886,6 +887,26 @@ sk_sp<SkTextBlob> SkTextBlobPriv::MakeFromBuffer(SkReadBuffer& reader) { return blobBuilder.make(); } +sk_sp<SkTextBlob> SkTextBlob::MakeAsDrawText( + const void* text, size_t byteLength, const SkPaint& paint) { + SkGlyphRunBuilder runBuilder; + + runBuilder.drawText(paint, text, byteLength, SkPoint::Make(0, 0)); + + auto list = runBuilder.useGlyphRunList(); + SkTextBlobBuilder blobBuilder; + if (!list->empty()) { + auto run = (*list)[0]; + SkPaint blobPaint(paint); + blobPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + + auto runData = blobBuilder.allocRunPos(blobPaint, run.runSize()); + run.filloutGlyphsAndPositions(runData.glyphs, (SkPoint *)runData.pos); + } + + return blobBuilder.make(); +} + sk_sp<SkData> SkTextBlob::serialize(const SkSerialProcs& procs) const { SkBinaryWriteBuffer buffer; buffer.setSerialProcs(procs); diff --git a/tests/TextBlobTest.cpp b/tests/TextBlobTest.cpp index c94955838c..7780ef7a7f 100644 --- a/tests/TextBlobTest.cpp +++ b/tests/TextBlobTest.cpp @@ -456,3 +456,19 @@ DEF_TEST(TextBlob_serialize, reporter) { REPORTER_ASSERT(reporter, sk_tool_utils::equal_pixels(img0.get(), img1.get())); } } + +DEF_TEST(TextBlob_MakeAsDrawText, reporter) { + SkPaint paint; + paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); + const char text[] = "Hello"; + auto blob = SkTextBlob::MakeAsDrawText(text, strlen(text), paint); + + int runs = 0; + for(SkTextBlobRunIterator it(blob.get()); !it.done(); it.next()) { + REPORTER_ASSERT(reporter, it.glyphCount() == strlen(text)); + REPORTER_ASSERT(reporter, it.positioning() == SkTextBlob::kFull_Positioning); + runs += 1; + } + REPORTER_ASSERT(reporter, runs == 1); + +} |