diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-05-04 18:30:04 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-05-04 18:30:04 +0000 |
commit | f5842f773b7e8612a52784b3c35c7455e67cb90a (patch) | |
tree | a0ff55aaef7a1f3cb69f29dccf3f6aac6f1841a6 | |
parent | 8a6400ef3ea9950f89629f24455250edf6ffd615 (diff) |
add typeface flattening
git-svn-id: http://skia.googlecode.com/svn/trunk@1245 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/pipe/SkGPipePriv.h | 4 | ||||
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 25 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 58 |
3 files changed, 82 insertions, 5 deletions
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h index 7ce7f1065a..b4c108ef53 100644 --- a/src/pipe/SkGPipePriv.h +++ b/src/pipe/SkGPipePriv.h @@ -58,6 +58,7 @@ enum DrawOps { // these edit paints kPaintOp_DrawOp, + kDefineTypeface_DrawOp, // these are signals to playback, not drawing verbs kDone_DrawOp, @@ -144,7 +145,8 @@ enum PaintOps { kTextSize_PaintOp, // arg scalar - text kTextScaleX_PaintOp,// arg scalar - text kTextSkewX_PaintOp, // arg scalar - text - + kTypeface_PaintOp, // arg inline (index) - text + kPathEffect_PaintOp, // arg inline kShader_PaintOp, kXfermode_PaintOp, diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index f022277c68..43abf899c5 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -20,6 +20,8 @@ #include "SkGPipe.h" #include "SkGPipePriv.h" #include "SkReader32.h" +#include "SkStream.h" +#include "SkTypeface.h" class SkGPipeState { public: @@ -32,9 +34,22 @@ public: // Returns the specified paint from our list, or creates a new paint if // index == count. If index > count, return NULL SkPaint* editPaint(uint32_t drawOp32); - + + SkTypeface* findTypeface(int id) const { + SkASSERT(id <= fTypefaces.count()); + return id ? fTypefaces[id - 1] : NULL; + } + void addTypeface(SkReader32* reader) { + size_t size = reader->readU32(); + const void* data = reader->skip(SkAlign4(size)); + SkMemoryStream stream(data, size, false); + // fTypefaces takes over ownership of the typeface reference + *fTypefaces.append() = SkTypeface::Deserialize(&stream); + } + private: SkTDArray<SkPaint*> fPaints; + SkTDArray<SkTypeface*> fTypefaces; }; /////////////////////////////////////////////////////////////////////////////// @@ -389,6 +404,7 @@ static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break; case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break; case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break; + case kTypeface_PaintOp: p->setTypeface(state->findTypeface(data)); break; // flag to reference a cached index instead of inflating? case kPathEffect_PaintOp: inflate_patheffect(reader, p); break; @@ -403,6 +419,11 @@ static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, } while (!done); } +static void defTypeface_rp(SkCanvas*, SkReader32* reader, uint32_t, + SkGPipeState* state) { + state->addTypeface(reader); +} + /////////////////////////////////////////////////////////////////////////////// static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) { @@ -446,6 +467,7 @@ static const ReadProc gReadTable[] = { skew_rp, translate_rp, paintOp_rp, + defTypeface_rp, done_rp }; @@ -457,6 +479,7 @@ SkGPipeState::SkGPipeState() { } SkGPipeState::~SkGPipeState() { + fTypefaces.unrefAll(); fPaints.deleteAll(); } diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 03a0251471..f0238cab0a 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -19,6 +19,8 @@ #include "SkPaint.h" #include "SkGPipe.h" #include "SkGPipePriv.h" +#include "SkStream.h" +#include "SkTypeface.h" #include "SkWriter32.h" static size_t estimateFlattenSize(const SkPath& path) { @@ -49,6 +51,18 @@ static void writeMatrix(SkWriter32* writer, const SkMatrix& matrix) { matrix.flatten(writer->reserve(size)); } +static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) { + SkASSERT(typeface); + SkDynamicMemoryWStream stream; + typeface->serialize(&stream); + size_t size = stream.getOffset(); + if (writer) { + writer->write32(size); + writer->write(stream.getStream(), size); + } + return 4 + size; +} + /////////////////////////////////////////////////////////////////////////////// class SkGPipeCanvas : public SkCanvas { @@ -115,6 +129,10 @@ private: size_t fBytesNotified; bool fDone; + SkRefCntSet fTypefaceSet; + + uint32_t getTypefaceID(SkTypeface*); + inline void writeOp(DrawOps op, unsigned flags, unsigned data) { fWriter.write32(DrawOp_packOpFlagData(op, flags, data)); } @@ -186,6 +204,22 @@ bool SkGPipeCanvas::needOpBytes(size_t needed) { return true; } +uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) { + uint32_t id = 0; // 0 means default/null typeface + if (face) { + id = fTypefaceSet.find(face); + if (0 == id) { + id = fTypefaceSet.add(face); + size_t size = writeTypeface(NULL, face); + if (this->needOpBytes(size)) { + this->writeOp(kDefineTypeface_DrawOp); + writeTypeface(&fWriter, face); + } + } + } + return id; +} + /////////////////////////////////////////////////////////////////////////////// #define NOTIFY_SETUP(canvas) \ @@ -567,7 +601,7 @@ template <typename T> uint32_t castToU32(T value) { } unsigned SkGPipeCanvas::writePaint(const SkPaint& paint) { - const SkPaint& base = *fPaints[0]; + SkPaint& base = *fPaints[0]; uint32_t storage[32]; uint32_t* ptr = storage; uint32_t* last = NULL; @@ -575,66 +609,84 @@ unsigned SkGPipeCanvas::writePaint(const SkPaint& paint) { if (base.getFlags() != paint.getFlags()) { last = ptr; *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags()); + base.setFlags(paint.getFlags()); } if (base.getColor() != paint.getColor()) { last = ptr; *ptr++ = PaintOp_packOp(kColor_PaintOp); *ptr++ = paint.getColor(); + base.setColor(paint.getColor()); } if (base.getStyle() != paint.getStyle()) { last = ptr; *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle()); + base.setStyle(paint.getStyle()); } if (base.getStrokeJoin() != paint.getStrokeJoin()) { last = ptr; *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin()); + base.setStrokeJoin(paint.getStrokeJoin()); } if (base.getStrokeCap() != paint.getStrokeCap()) { last = ptr; *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap()); + base.setStrokeCap(paint.getStrokeCap()); } if (base.getStrokeWidth() != paint.getStrokeWidth()) { last = ptr; *ptr++ = PaintOp_packOp(kWidth_PaintOp); *ptr++ = castToU32(paint.getStrokeWidth()); + base.setStrokeWidth(paint.getStrokeWidth()); } if (base.getStrokeMiter() != paint.getStrokeMiter()) { last = ptr; *ptr++ = PaintOp_packOp(kMiter_PaintOp); *ptr++ = castToU32(paint.getStrokeMiter()); + base.setStrokeMiter(paint.getStrokeMiter()); } if (base.getTextEncoding() != paint.getTextEncoding()) { last = ptr; *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding()); + base.setTextEncoding(paint.getTextEncoding()); } if (base.getHinting() != paint.getHinting()) { last = ptr; *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting()); + base.setHinting(paint.getHinting()); } if (base.getTextAlign() != paint.getTextAlign()) { last = ptr; *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign()); + base.setTextAlign(paint.getTextAlign()); } if (base.getTextSize() != paint.getTextSize()) { last = ptr; *ptr++ = PaintOp_packOp(kTextSize_PaintOp); *ptr++ = castToU32(paint.getTextSize()); + base.setTextSize(paint.getTextSize()); } if (base.getTextScaleX() != paint.getTextScaleX()) { last = ptr; *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp); *ptr++ = castToU32(paint.getTextScaleX()); + base.setTextScaleX(paint.getTextScaleX()); } if (base.getTextSkewX() != paint.getTextSkewX()) { last = ptr; *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp); *ptr++ = castToU32(paint.getTextSkewX()); + base.setTextSkewX(paint.getTextSkewX()); + } + + if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) { + uint32_t id = this->getTypefaceID(paint.getTypeface()); + last = ptr; + *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id); + base.setTypeface(paint.getTypeface()); } size_t size = (char*)ptr - (char*)storage; if (size && this->needOpBytes(size)) { - *fPaints[0] = paint; - this->writeOp(kPaintOp_DrawOp, 0, 0); size_t size = (char*)ptr - (char*)storage; *last |= kLastOp_PaintOpFlag << PAINTOPS_DATA_BITS; |