Index: src/core/SkTextBlob.cpp |
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp |
index ded801aaa945312e9f329a823a636b9e887aa299..f8bd2db840e8c6d1821765771939f76f11ac381f 100644 |
--- a/src/core/SkTextBlob.cpp |
+++ b/src/core/SkTextBlob.cpp |
@@ -7,6 +7,9 @@ |
#include "SkTextBlob.h" |
+#include "SkReadBuffer.h" |
+#include "SkWriteBuffer.h" |
+ |
SkTextBlob::SkTextBlob(uint16_t *glyphs, SkScalar *pos, const SkTArray<Run> *runs, |
const SkRect& bounds) |
: fGlyphBuffer(glyphs) |
@@ -26,6 +29,92 @@ uint32_t SkTextBlob::uniqueID() const { |
return fUniqueID; |
} |
+unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) { |
+ // GlyphPositioning values are directly mapped to scalars-per-glyph. |
+ SkASSERT(pos <= 2); |
+ return pos; |
+} |
+ |
+void SkTextBlob::flatten(SkWriteBuffer& buffer) const { |
+ int runCount = (NULL == fRuns.get()) ? 0 : fRuns->count(); |
+ |
+ buffer.write32(runCount); |
+ buffer.writeRect(fBounds); |
+ |
+ size_t glyphBufferCount = 0; |
+ size_t posBufferCount = 0; |
+ |
+ for (int i = 0; i < runCount; ++i) { |
+ const Run& run = (*fRuns)[i]; |
+ SkASSERT(run.count > 0); |
+ |
+ buffer.write32(run.count); |
+ buffer.write32(run.glyphStart); |
+ buffer.write32(run.posStart); |
+ buffer.writePoint(run.offset); |
+ buffer.writePaint(run.font); |
+ buffer.write32(run.positioning); |
+ |
+ glyphBufferCount += run.count; |
+ posBufferCount += run.count * ScalarsPerGlyph(run.positioning); |
+ } |
+ |
+ buffer.writeByteArray(fGlyphBuffer, glyphBufferCount * sizeof(uint16_t)); |
+ buffer.writeByteArray(fPosBuffer, posBufferCount * sizeof(SkScalar)); |
+} |
+ |
+const SkTextBlob* SkTextBlob::CreateFromBuffer(SkReadBuffer& buffer) { |
+ int runCount = buffer.read32(); |
+ if (runCount <= 0) { |
+ return NULL; |
+ } |
+ |
+ SkRect bounds; |
+ buffer.readRect(&bounds); |
+ |
+ size_t glyphBufferCount = 0; |
+ size_t posBufferCount = 0; |
+ SkAutoTDelete<SkTArray<Run> > runs(SkNEW_ARGS(SkTArray<Run>, (runCount))); |
+ for (int i = 0; i < runCount; ++i) { |
+ Run& run = runs->push_back(); |
+ |
+ run.count = buffer.read32(); |
+ if (0 == run.count) { |
+ return NULL; |
+ } |
+ |
+ run.glyphStart = buffer.read32(); |
+ run.posStart = buffer.read32(); |
+ if (run.glyphStart != glyphBufferCount || run.posStart != posBufferCount) { |
+ return NULL; |
+ } |
+ |
+ buffer.readPoint(&run.offset); |
+ buffer.readPaint(&run.font); |
+ |
+ run.positioning = static_cast<GlyphPositioning>(buffer.read32()); |
+ if (run.positioning > 2) { |
+ return NULL; |
+ } |
+ |
+ glyphBufferCount += run.count; |
+ posBufferCount += run.count * ScalarsPerGlyph(run.positioning); |
+ } |
+ |
+ SkTDArray<uint16_t> glyphBuffer; |
+ SkTDArray<SkScalar> posBuffer; |
+ |
+ buffer.readByteArray(glyphBuffer.append(glyphBufferCount), |
+ glyphBufferCount * sizeof(uint16_t)); |
+ buffer.readByteArray(posBuffer.append(posBufferCount), |
+ posBufferCount * sizeof(SkScalar)); |
+ |
+ return SkNEW_ARGS(SkTextBlob, (glyphBuffer.detach(), |
+ posBuffer.detach(), |
+ runs.detach(), |
+ bounds)); |
+} |
+ |
SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob) |
: fBlob(blob) |
, fIndex(0) { |
@@ -161,9 +250,7 @@ void SkTextBlobBuilder::allocInternal(const SkPaint &font, |
this->ensureRun(font, positioning, offset); |
- // SkTextBlob::GlyphPositioning values are directly mapped to scalars-per-glyph. |
- unsigned posScalarsPerGlyph = positioning; |
- SkASSERT(posScalarsPerGlyph <= 2); |
+ unsigned posScalarsPerGlyph = SkTextBlob::ScalarsPerGlyph(positioning); |
fGlyphBuffer.append(count); |
fPosBuffer.append(count * posScalarsPerGlyph); |