diff options
-rw-r--r-- | gm/typeface.cpp | 83 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | include/pipe/SkGPipe.h | 17 | ||||
-rw-r--r-- | src/pipe/SkGPipePriv.h | 5 | ||||
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 13 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 37 |
6 files changed, 143 insertions, 13 deletions
diff --git a/gm/typeface.cpp b/gm/typeface.cpp new file mode 100644 index 0000000000..af04725a3f --- /dev/null +++ b/gm/typeface.cpp @@ -0,0 +1,83 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkCanvas.h" +#include "SkString.h" +#include "SkTypeface.h" +#include "SkTypes.h" + +namespace skiagm { + +const char* gFaces[] = { + "Times Roman", + "Hiragino Maru Gothic Pro", + "Papyrus", + "Helvetica", + "Courier New" +}; + +class TypefaceGM : public GM { +public: + TypefaceGM() { + fFaces = new SkTypeface*[SK_ARRAY_COUNT(gFaces)]; + for (size_t i = 0; i < SK_ARRAY_COUNT(gFaces); i++) { + fFaces[i] = SkTypeface::CreateFromName(gFaces[i], SkTypeface::kNormal); + } + } + + virtual ~TypefaceGM() { + for (size_t i = 0; i < SK_ARRAY_COUNT(gFaces); i++) { + fFaces[i]->unref(); + } + delete fFaces; + } + +protected: + virtual SkString onShortName() SK_OVERRIDE { + return SkString("typeface"); + } + + virtual SkISize onISize() SK_OVERRIDE { + return SkISize::Make(640, 480); + } + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + SkString text("Typefaces are fun!"); + SkScalar y = 0; + + SkPaint paint; + paint.setAntiAlias(true); + for (size_t i = 0; i < SK_ARRAY_COUNT(gFaces); i++) { + this->drawWithFace(text, i, y, paint, canvas); + } + // Now go backwards + for (int i = SK_ARRAY_COUNT(gFaces) - 1; i >= 0; i--) { + this->drawWithFace(text, i, y, paint, canvas); + } + } + +private: + void drawWithFace(const SkString& text, int i, SkScalar& y, SkPaint& paint, + SkCanvas* canvas) { + paint.setTypeface(fFaces[i]); + y += paint.getFontMetrics(NULL); + canvas->drawText(text.c_str(), text.size(), 0, y, paint); + } + + SkTypeface** fFaces; + + typedef GM INHERITED; +}; + +//////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new TypefaceGM; } +static GMRegistry reg(MyFactory); + +} // skiagm diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 6a032a1f9d..5e25eb37b8 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -62,6 +62,7 @@ '../gm/tilemodes.cpp', '../gm/tinybitmap.cpp', '../gm/twopointradial.cpp', + '../gm/typeface.cpp', '../gm/verttext.cpp', '../gm/verttext2.cpp', '../gm/xfermodes.cpp', diff --git a/include/pipe/SkGPipe.h b/include/pipe/SkGPipe.h index d06148c662..a1f425c699 100644 --- a/include/pipe/SkGPipe.h +++ b/include/pipe/SkGPipe.h @@ -46,8 +46,13 @@ private: /////////////////////////////////////////////////////////////////////////////// +class SkGPipeCanvas; + class SkGPipeController { public: + SkGPipeController() : fCanvas(NULL) {} + virtual ~SkGPipeController(); + /** * Called periodically by the writer, to get a working buffer of RAM to * write into. The actual size of the block is also returned, and must be @@ -69,6 +74,12 @@ public: */ virtual void notifyWritten(size_t bytes) = 0; virtual int numberOfReaders() const { return 1; } + +private: + friend class SkGPipeWriter; + void setCanvas(SkGPipeCanvas*); + + SkGPipeCanvas* fCanvas; }; class SkGPipeWriter { @@ -116,9 +127,9 @@ public: size_t storageAllocatedForRecording(); private: - class SkGPipeCanvas* fCanvas; - SkFactorySet fFactorySet; - SkWriter32 fWriter; + SkGPipeCanvas* fCanvas; + SkFactorySet* fFactorySet; + SkWriter32 fWriter; }; #endif diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h index 72b7f377a4..3f8a7480d8 100644 --- a/src/pipe/SkGPipePriv.h +++ b/src/pipe/SkGPipePriv.h @@ -65,6 +65,7 @@ enum DrawOps { kTranslate_DrawOp, kPaintOp_DrawOp, + kSetTypeface_DrawOp, kDef_Typeface_DrawOp, kDef_Flattenable_DrawOp, @@ -193,8 +194,8 @@ private: }; static inline bool shouldFlattenBitmaps(uint32_t flags) { - return flags & SkGPipeWriter::kCrossProcess_Flag - && !(flags & SkGPipeWriter::kSharedAddressSpace_Flag); + return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag + && !(flags & SkGPipeWriter::kSharedAddressSpace_Flag)); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index e2cd151d28..450f19ce77 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -509,13 +509,23 @@ static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, break; } - case kTypeface_PaintOp: state->setTypeface(p, data); break; + case kTypeface_PaintOp: + SkASSERT(SkToBool(state->getFlags() & + SkGPipeWriter::kCrossProcess_Flag)); + state->setTypeface(p, data); break; default: SkDEBUGFAIL("bad paintop"); return; } SkASSERT(reader->offset() <= stop); } while (reader->offset() < stop); } +static void typeface_rp(SkCanvas*, SkReader32* reader, uint32_t, + SkGPipeState* state) { + SkASSERT(!SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag)); + SkPaint* p = state->editPaint(); + p->setTypeface(static_cast<SkTypeface*>(reader->readPtr())); +} + /////////////////////////////////////////////////////////////////////////////// static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) { @@ -585,6 +595,7 @@ static const ReadProc gReadTable[] = { translate_rp, paintOp_rp, + typeface_rp, def_Typeface_rp, def_PaintFlat_rp, def_Bitmap_rp, diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index a6ffae1a37..66cde1bd15 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -522,7 +522,7 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) { } uint32_t writeBufferFlags; - if (fFlags & SkGPipeWriter::kCrossProcess_Flag) { + if (SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag)) { writeBufferFlags = (SkFlattenableWriteBuffer::kInlineFactoryNames_Flag | SkFlattenableWriteBuffer::kCrossProcess_Flag); } else { @@ -1213,8 +1213,18 @@ void SkGPipeCanvas::writePaint(const SkPaint& paint) { } if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) { - uint32_t id = this->getTypefaceID(paint.getTypeface()); - *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id); + if (SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag)) { + uint32_t id = this->getTypefaceID(paint.getTypeface()); + *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id); + } else if (this->needOpBytes(sizeof(void*))) { + // Add to the set for ref counting. + fTypefaceSet.add(paint.getTypeface()); + // It is safe to write the typeface to the stream before the rest + // of the paint unless we ever send a kReset_PaintOp, which we + // currently never do. + this->writeOp(kSetTypeface_DrawOp); + fWriter.writePtr(paint.getTypeface()); + } base.setTypeface(paint.getTypeface()); } @@ -1251,23 +1261,36 @@ void SkGPipeCanvas::writePaint(const SkPaint& paint) { #include "SkGPipe.h" -SkGPipeWriter::SkGPipeWriter() : fWriter(0) { +SkGPipeController::~SkGPipeController() { + SkSafeUnref(fCanvas); +} + +void SkGPipeController::setCanvas(SkGPipeCanvas* canvas) { + SkRefCnt_SafeAssign(fCanvas, canvas); +} + +/////////////////////////////////////////////////////////////////////////////// + +SkGPipeWriter::SkGPipeWriter() +: fFactorySet(SkNEW(SkFactorySet)) +, fWriter(0) { fCanvas = NULL; } SkGPipeWriter::~SkGPipeWriter() { this->endRecording(); - SkSafeUnref(fCanvas); + fFactorySet->unref(); } SkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller, uint32_t flags) { if (NULL == fCanvas) { fWriter.reset(NULL, 0); - fFactorySet.reset(); + fFactorySet->reset(); fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, (flags & kCrossProcess_Flag) ? - &fFactorySet : NULL, flags)); + fFactorySet : NULL, flags)); } + controller->setCanvas(fCanvas); return fCanvas; } |