aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/typeface.cpp83
-rw-r--r--gyp/gmslides.gypi1
-rw-r--r--include/pipe/SkGPipe.h17
-rw-r--r--src/pipe/SkGPipePriv.h5
-rw-r--r--src/pipe/SkGPipeRead.cpp13
-rw-r--r--src/pipe/SkGPipeWrite.cpp37
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;
}