diff options
-rw-r--r-- | include/core/SkTextBlob.h | 22 | ||||
-rw-r--r-- | src/core/SkTextBlob.cpp | 49 | ||||
-rw-r--r-- | tests/TextBlobTest.cpp | 49 |
3 files changed, 32 insertions, 88 deletions
diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h index 8dce082512..cf77a78ca5 100644 --- a/include/core/SkTextBlob.h +++ b/include/core/SkTextBlob.h @@ -17,9 +17,6 @@ struct SkSerialProcs; struct SkDeserialProcs; -typedef void (*SkTypefaceCatalogerProc)(SkTypeface*, void* ctx); -typedef sk_sp<SkTypeface> (*SkTypefaceResolverProc)(uint32_t id, void* ctx); - /** \class SkTextBlob SkTextBlob combines multiple text runs into an immutable, ref-counted structure. @@ -46,28 +43,15 @@ public: }; /** - * Serialize the typeface into a data blob, storing type uniqueID of each referenced typeface. - * During this process, each time a typeface is encountered, it is passed to the catalog, - * allowing the caller to what typeface IDs will need to be resolved in Deserialize(). - */ - sk_sp<SkData> serialize(SkTypefaceCatalogerProc, void* ctx) const; - - /** * Similar to serialize above, but writes directly into |memory|. Returns bytes written or 0u * if serialization failed due to insufficient size. */ size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const; - /** - * Re-create a text blob previously serialized. Since the serialized form records the uniqueIDs - * of its typefaces, deserialization requires that the caller provide the corresponding - * SkTypefaces for those IDs. - */ - static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, - SkTypefaceResolverProc, void* ctx); + sk_sp<SkData> serialize(const SkSerialProcs& procs) const; - sk_sp<SkData> serialize(const SkSerialProcs&) const; - static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, const SkDeserialProcs&); + static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, + const SkDeserialProcs& procs); private: friend class SkNVRefCnt<SkTextBlob>; diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp index fec7c527a2..4528e64f15 100644 --- a/src/core/SkTextBlob.cpp +++ b/src/core/SkTextBlob.cpp @@ -927,58 +927,9 @@ sk_sp<SkTextBlob> SkTextBlob::Deserialize(const void* data, size_t length, /////////////////////////////////////////////////////////////////////////////////////////////////// -namespace { - struct CatalogState { - SkTypefaceCatalogerProc fProc; - void* fCtx; - }; - - sk_sp<SkData> catalog_typeface_proc(SkTypeface* face, void* ctx) { - CatalogState* state = static_cast<CatalogState*>(ctx); - state->fProc(face, state->fCtx); - uint32_t id = face->uniqueID(); - return SkData::MakeWithCopy(&id, sizeof(uint32_t)); - } -} - -sk_sp<SkData> SkTextBlob::serialize(SkTypefaceCatalogerProc proc, void* ctx) const { - CatalogState state = { proc, ctx }; - SkSerialProcs procs; - procs.fTypefaceProc = catalog_typeface_proc; - procs.fTypefaceCtx = &state; - return this->serialize(procs); -} - size_t SkTextBlob::serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const { SkBinaryWriteBuffer buffer(memory, memory_size); buffer.setSerialProcs(procs); SkTextBlobPriv::Flatten(*this, buffer); return buffer.usingInitialStorage() ? buffer.bytesWritten() : 0u; } - -namespace { - struct ResolverState { - SkTypefaceResolverProc fProc; - void* fCtx; - }; - - sk_sp<SkTypeface> resolver_typeface_proc(const void* data, size_t length, void* ctx) { - if (length != 4) { - return nullptr; - } - - ResolverState* state = static_cast<ResolverState*>(ctx); - uint32_t id; - memcpy(&id, data, length); - return state->fProc(id, state->fCtx); - } -} - -sk_sp<SkTextBlob> SkTextBlob::Deserialize(const void* data, size_t length, - SkTypefaceResolverProc proc, void* ctx) { - ResolverState state = { proc, ctx }; - SkDeserialProcs procs; - procs.fTypefaceProc = resolver_typeface_proc; - procs.fTypefaceCtx = &state; - return Deserialize(data, length, procs); -} diff --git a/tests/TextBlobTest.cpp b/tests/TextBlobTest.cpp index 7780ef7a7f..5018d7a79b 100644 --- a/tests/TextBlobTest.cpp +++ b/tests/TextBlobTest.cpp @@ -7,6 +7,7 @@ #include "SkPaint.h" #include "SkPoint.h" +#include "SkSerialProcs.h" #include "SkTextBlobRunIterator.h" #include "SkTo.h" #include "SkTypeface.h" @@ -412,6 +413,25 @@ static sk_sp<SkImage> render(const SkTextBlob* blob) { return surf->makeImageSnapshot(); } +static sk_sp<SkData> SerializeTypeface(SkTypeface* tf, void* ctx) { + auto array = (SkTDArray<SkTypeface*>*)ctx; + *array->append() = tf; + return sk_sp<SkData>(nullptr); +} + +static sk_sp<SkTypeface> DeserializeTypeface(const void* data, size_t length, void* ctx) { + auto array = (SkTDArray<SkTypeface*>*)ctx; + for (int i = 0; i < array->count(); ++i) { + auto result = (*array)[i]; + if (result) { + (*array)[i] = nullptr; + return sk_ref_sp(result); + } + } + SkASSERT(false); + return sk_sp<SkTypeface>(nullptr); +} + /* * Build a blob with more than one typeface. * Draw it into an offscreen, @@ -429,26 +449,15 @@ DEF_TEST(TextBlob_serialize, reporter) { }(); SkTDArray<SkTypeface*> array; - sk_sp<SkData> data = blob0->serialize([](SkTypeface* tf, void* ctx) { - auto array = (SkTDArray<SkTypeface*>*)ctx; - if (array->find(tf) < 0) { - *array->append() = tf; - } - }, &array); - // we only expect 1, since null would not have been serialized, but the default would - REPORTER_ASSERT(reporter, array.count() == 1); - - sk_sp<SkTextBlob> blob1 = SkTextBlob::Deserialize(data->data(), data->size(), - [](uint32_t uniqueID, void* ctx) { - auto array = (SkTDArray<SkTypeface*>*)ctx; - for (int i = 0; i < array->count(); ++i) { - if ((*array)[i]->uniqueID() == uniqueID) { - return sk_ref_sp((*array)[i]); - } - } - SkASSERT(false); - return sk_sp<SkTypeface>(nullptr); - }, &array); + SkSerialProcs serializeProcs; + serializeProcs.fTypefaceProc = &SerializeTypeface; + serializeProcs.fTypefaceCtx = (void*) &array; + sk_sp<SkData> data = blob0->serialize(serializeProcs); + REPORTER_ASSERT(reporter, array.count() == 2); + SkDeserialProcs deserializeProcs; + deserializeProcs.fTypefaceProc = &DeserializeTypeface; + deserializeProcs.fTypefaceCtx = (void*) &array; + sk_sp<SkTextBlob> blob1 = SkTextBlob::Deserialize(data->data(), data->size(), deserializeProcs); sk_sp<SkImage> img0 = render(blob0.get()); sk_sp<SkImage> img1 = render(blob1.get()); |