Index: src/pipe/SkPipeReader.cpp |
diff --git a/src/pipe/SkPipeReader.cpp b/src/pipe/SkPipeReader.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9b4ce23fd9e2f62048d2f80f741d5b188128424e |
--- /dev/null |
+++ b/src/pipe/SkPipeReader.cpp |
@@ -0,0 +1,332 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkCanvas.h" |
+#include "SkPipeFormat.h" |
+#include "SkReadBuffer.h" |
+ |
+class SkPipeReader { |
+public: |
+ |
+ bool parse(SkReadBuffer&, SkCanvas*); |
+}; |
+ |
+template <typename T> const T* skip(SkReadBuffer& reader, int count) { |
+ return (const T*)reader.skip(count * sizeof(T)); |
+} |
+ |
+template <typename T> const T* skip(SkReadBuffer& reader) { |
+ return (const T*)reader.skip(sizeof(T)); |
+} |
+ |
+static SkRRect read_rrect(SkReadBuffer& reader) { |
+ SkRRect rrect; |
+ rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMemory); |
+ return rrect; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+#define CHECK_SET_SCALAR(Field) \ |
+ do { if (nondef & k##Field##_NonDef) { \ |
+ paint.set##Field(reader.readScalar()); \ |
+ }} while (0) |
+ |
+#define CHECK_SET_FLATTENABLE(Field) \ |
+ do { if (nondef & k##Field##_NonDef) { \ |
+ paint.set##Field(reader.read##Field()); \ |
+ }} while (0) |
+ |
+/* |
+ * Header: |
+ * paint flags : 32 |
+ * non_def bits : 16 |
+ * xfermode enum : 8 |
+ * pad zeros : 8 |
+ */ |
+static SkPaint read_paint(SkReadBuffer& reader) { |
+ uint32_t packedFlags = reader.read32(); |
+ uint32_t extra = reader.read32(); |
+ unsigned nondef = extra >> 16; |
+ SkXfermode::Mode mode = (SkXfermode::Mode)((extra >> 8) & 0xFF); |
+ SkASSERT((extra & 0xFF) == 0); |
+ |
+ SkPaint paint; |
+ |
+ packedFlags >>= 6; |
+ paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3)); packedFlags >>= 2; |
+ paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3)); packedFlags >>= 2; |
+ paint.setFilterQuality((SkFilterQuality)(packedFlags & 3)); packedFlags >>= 2; |
+ paint.setTextAlign((SkPaint::Align)(packedFlags & 3)); packedFlags >>= 2; |
+ paint.setHinting((SkPaint::Hinting)(packedFlags & 2)); packedFlags >>= 2; |
+ paint.setFlags(packedFlags); |
+ |
+ CHECK_SET_SCALAR(TextSize); |
+ CHECK_SET_SCALAR(TextScaleX); |
+ CHECK_SET_SCALAR(TextSkewX); |
+ CHECK_SET_SCALAR(StrokeWidth); |
+ CHECK_SET_SCALAR(StrokeMiter); |
+ |
+ if (nondef & kColor_NonDef) { |
+ paint.setColor(reader.read32()); |
+ } |
+ if (nondef & kTypeface_NonDef) { |
+ } |
+ |
+ CHECK_SET_FLATTENABLE(PathEffect); |
+ CHECK_SET_FLATTENABLE(Shader); |
+ CHECK_SET_FLATTENABLE(Xfermode); |
+ CHECK_SET_FLATTENABLE(MaskFilter); |
+ CHECK_SET_FLATTENABLE(ColorFilter); |
+ CHECK_SET_FLATTENABLE(Rasterizer); |
+ CHECK_SET_FLATTENABLE(ImageFilter); |
+ |
+ if (!(nondef & kXfermode_NonDef)) { |
+ paint.setXfermodeMode(mode); |
+ } |
+ |
+ return paint; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+typedef void (*SkPipeHandler)(SkReadBuffer&, uint32_t packedVerb, SkCanvas*); |
+ |
+static void save_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kSave_Verb == unpack_verb(packedVerb)); |
+ canvas->save(); |
+} |
+ |
+static void restore_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kRestore_Verb == unpack_verb(packedVerb)); |
+ canvas->restore(); |
+} |
+ |
+static void concat_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kConcat_Verb == unpack_verb(packedVerb)); |
+ SkMatrix::TypeMask tm = (SkMatrix::TypeMask)unpack_verb_extra(packedVerb); |
+ |
+ SkMatrix matrix; |
+ matrix.reset(); |
+ if (tm & SkMatrix::kPerspective_Mask) { |
+ matrix.set9(skip<SkScalar>(reader, 9)); |
+ } else if (tm & SkMatrix::kAffine_Mask) { |
+ const SkScalar* tmp = skip<SkScalar>(reader, 6); |
+ matrix[SkMatrix::kMScaleX] = tmp[0]; |
+ matrix[SkMatrix::kMSkewX] = tmp[1]; |
+ matrix[SkMatrix::kMTransX] = tmp[2]; |
+ matrix[SkMatrix::kMScaleY] = tmp[3]; |
+ matrix[SkMatrix::kMSkewY] = tmp[4]; |
+ matrix[SkMatrix::kMTransY] = tmp[5]; |
+ } else if (tm & SkMatrix::kScale_Mask) { |
+ const SkScalar* tmp = skip<SkScalar>(reader, 4); |
+ matrix[SkMatrix::kMScaleX] = tmp[0]; |
+ matrix[SkMatrix::kMTransX] = tmp[1]; |
+ matrix[SkMatrix::kMScaleY] = tmp[2]; |
+ matrix[SkMatrix::kMTransY] = tmp[3]; |
+ } else if (tm & SkMatrix::kTranslate_Mask) { |
+ const SkScalar* tmp = skip<SkScalar>(reader, 2); |
+ matrix[SkMatrix::kMTransX] = tmp[0]; |
+ matrix[SkMatrix::kMTransY] = tmp[1]; |
+ } |
+ canvas->concat(matrix); |
+} |
+ |
+static void clipRect_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kClipRect_Verb == unpack_verb(packedVerb)); |
+ SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); |
+ bool isAA = unpack_verb_extra(packedVerb) & 1; |
+ canvas->clipRect(*skip<SkRect>(reader), op, isAA); |
+} |
+ |
+static void clipRRect_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kClipRect_Verb == unpack_verb(packedVerb)); |
+ SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); |
+ bool isAA = unpack_verb_extra(packedVerb) & 1; |
+ canvas->clipRRect(read_rrect(reader), op, isAA); |
+} |
+ |
+static void clipPath_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kClipRect_Verb == unpack_verb(packedVerb)); |
+ SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); |
+ bool isAA = unpack_verb_extra(packedVerb) & 1; |
+ SkPath path; |
+ reader.readPath(&path); |
+ canvas->clipPath(path, op, isAA); |
+} |
+ |
+static void clipRegion_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kClipRect_Verb == unpack_verb(packedVerb)); |
+ SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); |
+ SkRegion region; |
+ reader.readRegion(®ion); |
+ canvas->clipRegion(region, op); |
+} |
+ |
+static void drawDRRect_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kDrawDRRect_Verb == unpack_verb(packedVerb)); |
+ const SkRRect* outer = skip<SkRRect>(reader); |
+ const SkRRect* inner = skip<SkRRect>(reader); |
+ canvas->drawDRRect(*outer, *inner, read_paint(reader)); |
+} |
+ |
+static void drawText_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kDrawText_Verb == unpack_verb(packedVerb)); |
+ uint32_t len = unpack_verb_extra(packedVerb); |
+ if (0 == len) { |
+ len = reader.read32(); |
+ } |
+ const void* text = reader.skip(SkAlign4(len)); |
+ SkScalar x = reader.readScalar(); |
+ SkScalar y = reader.readScalar(); |
+ canvas->drawText(text, len, x, y, read_paint(reader)); |
+} |
+ |
+static void drawPosText_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kDrawPosText_Verb == unpack_verb(packedVerb)); |
+ uint32_t len = unpack_verb_extra(packedVerb); |
+ if (0 == len) { |
+ len = reader.read32(); |
+ } |
+ const void* text = reader.skip(SkAlign4(len)); |
+ int count = reader.read32(); |
+ const SkPoint* pos = skip<SkPoint>(reader); |
+ SkPaint paint = read_paint(reader); |
+ SkASSERT(paint.countText(text, len) == count); |
+ canvas->drawPosText(text, len, pos, paint); |
+} |
+ |
+static void drawPosTextH_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ SkASSERT(kDrawPosTextH_Verb == unpack_verb(packedVerb)); |
+ uint32_t len = unpack_verb_extra(packedVerb); |
+ if (0 == len) { |
+ len = reader.read32(); |
+ } |
+ const void* text = reader.skip(SkAlign4(len)); |
+ int count = reader.read32(); |
+ const SkScalar* xpos = skip<SkScalar>(reader); |
+ SkScalar constY = reader.readScalar(); |
+ SkPaint paint = read_paint(reader); |
+ SkASSERT(paint.countText(text, len) == count); |
+ canvas->drawPosTextH(text, len, xpos, constY, paint); |
+} |
+ |
+static void drawTextOnPath_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawTextBlob_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawTextRSXform_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawPatch_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawPaint_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawRect_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawOval_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawRRect_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawPath_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawPoints_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawImage_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawImageRect_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawImageNine_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawVertices_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawPicture_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+static void drawAnnotation_handler(SkReadBuffer& reader, uint32_t packedVerb, SkCanvas* canvas) { |
+ sk_throw(); |
+} |
+ |
+const SkPipeHandler gPipeHandlers[] = { |
+ save_handler, |
+ restore_handler, |
+ concat_handler, |
+ |
+ clipRect_handler, |
+ clipRRect_handler, |
+ clipPath_handler, |
+ clipRegion_handler, |
+ |
+ drawDRRect_handler, |
+ drawText_handler, |
+ drawPosText_handler, |
+ drawPosTextH_handler, |
+ drawTextOnPath_handler, |
+ drawTextBlob_handler, |
+ drawTextRSXform_handler, |
+ drawPatch_handler, |
+ drawPaint_handler, |
+ drawPoints_handler, |
+ drawRect_handler, |
+ drawPath_handler, |
+ drawOval_handler, |
+ drawRRect_handler, |
+ |
+ drawImage_handler, |
+ drawImageRect_handler, |
+ drawImageNine_handler, |
+ |
+ drawVertices_handler, |
+ |
+ drawPicture_handler, |
+ drawAnnotation_handler, |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+bool SkPipeReader::parse(SkReadBuffer& reader, SkCanvas* canvas) { |
+ while (!reader.eof()) { |
+ uint32_t packedVerb = reader.read32(); |
+ Verb verb = unpack_verb(packedVerb); |
+ if (verb > SK_ARRAY_COUNT(gPipeHandlers)) { |
+ return false; |
+ } |
+ gPipeHandlers[verb](reader, packedVerb, canvas); |
+ if (!reader.isValid()) { |
+ return false; |
+ } |
+ } |
+ return true; |
+} |