diff options
author | Khushal <khushalsagar@chromium.org> | 2018-04-03 17:51:40 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-04 01:25:11 +0000 |
commit | 42f8bc40fd3702c801c9f5b9d438fabcc77fb58b (patch) | |
tree | 99f0fcd1ae3747d6553b9a77282442aa2693d78b | |
parent | 46117c83d22886286196f7965f5fdffeb7e43457 (diff) |
Add API for SkTextBlob serialization into caller's memory.
R=reed@google.com
Change-Id: Iaeb67504aabf0dc036e81fa23c1a3c949b72b2b9
Reviewed-on: https://skia-review.googlesource.com/114262
Commit-Queue: Khusal Sagar <khushalsagar@chromium.org>
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Reed <reed@google.com>
-rw-r--r-- | include/core/SkFlattenable.h | 2 | ||||
-rw-r--r-- | include/core/SkTextBlob.h | 6 | ||||
-rw-r--r-- | src/core/SkFlattenable.cpp | 10 | ||||
-rw-r--r-- | src/core/SkTextBlob.cpp | 7 | ||||
-rw-r--r-- | tests/SerializationTest.cpp | 44 |
5 files changed, 69 insertions, 0 deletions
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h index 05b8fba9a7..ed343c82ae 100644 --- a/include/core/SkFlattenable.h +++ b/include/core/SkFlattenable.h @@ -135,6 +135,8 @@ public: // public ways to serialize / deserialize // sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const; + size_t serialize(void* memory, size_t memory_size, + const SkSerialProcs* = nullptr) const; static sk_sp<SkFlattenable> Deserialize(Type, const void* data, size_t length, const SkDeserialProcs* procs = nullptr); diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h index 89c6697cc9..59151d3002 100644 --- a/include/core/SkTextBlob.h +++ b/include/core/SkTextBlob.h @@ -67,6 +67,12 @@ public: 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. diff --git a/src/core/SkFlattenable.cpp b/src/core/SkFlattenable.cpp index 0c673181a7..c8766f88be 100644 --- a/src/core/SkFlattenable.cpp +++ b/src/core/SkFlattenable.cpp @@ -154,6 +154,16 @@ sk_sp<SkData> SkFlattenable::serialize(const SkSerialProcs* procs) const { return data; } +size_t SkFlattenable::serialize(void* memory, size_t memory_size, + const SkSerialProcs* procs) const { + SkBinaryWriteBuffer writer(memory, memory_size); + if (procs) { + writer.setSerialProcs(*procs); + } + writer.writeFlattenable(this); + return writer.usingInitialStorage() ? writer.bytesWritten() : 0u; +} + sk_sp<SkFlattenable> SkFlattenable::Deserialize(SkFlattenable::Type type, const void* data, size_t size, const SkDeserialProcs* procs) { SkReadBuffer buffer(data, size); diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp index 182cf72ec2..eac2430f5f 100644 --- a/src/core/SkTextBlob.cpp +++ b/src/core/SkTextBlob.cpp @@ -912,6 +912,13 @@ sk_sp<SkData> SkTextBlob::serialize(SkTypefaceCatalogerProc proc, void* ctx) con 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); + this->flatten(buffer); + return buffer.usingInitialStorage() ? buffer.bytesWritten() : 0u; +} + namespace { struct ResolverState { SkTypefaceResolverProc fProc; diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp index da797398c1..c6d529b0cb 100644 --- a/tests/SerializationTest.cpp +++ b/tests/SerializationTest.cpp @@ -8,6 +8,7 @@ #include "Resources.h" #include "SkAnnotationKeys.h" #include "SkCanvas.h" +#include "SkDashPathEffect.h" #include "SkFixed.h" #include "SkFontDescriptor.h" #include "SkImage.h" @@ -21,6 +22,7 @@ #include "SkShaderBase.h" #include "SkTableColorFilter.h" #include "SkTemplates.h" +#include "SkTextBlob.h" #include "SkTypeface.h" #include "SkWriteBuffer.h" #include "SkXfermodeImageFilter.h" @@ -666,3 +668,45 @@ DEF_TEST(WriteBuffer_storage, reporter) { REPORTER_ASSERT(reporter, !writer.usingInitialStorage()); // this is the change REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize); } + +DEF_TEST(WriteBuffer_external_memory_textblob, reporter) { + SkPaint font; + font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + font.setTypeface(SkTypeface::MakeDefault()); + + SkTextBlobBuilder builder; + int glyph_count = 5; + const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f); + // allocRun() allocates only the glyph buffer. + std::fill(run.glyphs, run.glyphs + glyph_count, 0); + auto blob = builder.make(); + SkSerialProcs procs; + SkAutoTMalloc<uint8_t> storage; + size_t blob_size = 0u; + size_t storage_size = 0u; + + blob_size = SkAlign4(blob->serialize(procs)->size()); + REPORTER_ASSERT(reporter, blob_size > 4u); + storage_size = blob_size - 4; + storage.realloc(storage_size); + REPORTER_ASSERT(reporter, blob->serialize(procs, storage.get(), storage_size) == 0u); + storage_size = blob_size; + storage.realloc(storage_size); + REPORTER_ASSERT(reporter, blob->serialize(procs, storage.get(), storage_size) != 0u); +} + +DEF_TEST(WriteBuffer_external_memory_flattenable, reporter) { + SkScalar intervals[] = {1.f, 1.f}; + auto path_effect = SkDashPathEffect::Make(intervals, 2, 0); + size_t path_size = SkAlign4(path_effect->serialize()->size()); + REPORTER_ASSERT(reporter, path_size > 4u); + SkAutoTMalloc<uint8_t> storage; + + size_t storage_size = path_size - 4; + storage.realloc(storage_size); + REPORTER_ASSERT(reporter, path_effect->serialize(storage.get(), storage_size) == 0u); + + storage_size = path_size; + storage.realloc(storage_size); + REPORTER_ASSERT(reporter, path_effect->serialize(storage.get(), storage_size) != 0u); +} |