1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkJSONCanvas_DEFINED
9#define SkJSONCanvas_DEFINED
10
11#include "SkCanvas.h"
12#include "SkStream.h"
13#include "SkJSONCPP.h"
14
15#define SKJSONCANVAS_VERSION                     "version"
16#define SKJSONCANVAS_COMMANDS                    "commands"
17#define SKJSONCANVAS_COMMAND                     "command"
18
19#define SKJSONCANVAS_COMMAND_TRANSLATE           "Translate"
20#define SKJSONCANVAS_COMMAND_SCALE               "Scale"
21#define SKJSONCANVAS_COMMAND_MATRIX              "Matrix"
22#define SKJSONCANVAS_COMMAND_PAINT               "Paint"
23#define SKJSONCANVAS_COMMAND_RECT                "Rect"
24#define SKJSONCANVAS_COMMAND_OVAL                "Oval"
25#define SKJSONCANVAS_COMMAND_RRECT               "RRect"
26#define SKJSONCANVAS_COMMAND_DRRECT              "DRRect"
27#define SKJSONCANVAS_COMMAND_POINTS              "Points"
28#define SKJSONCANVAS_COMMAND_VERTICES            "Vertices"
29#define SKJSONCANVAS_COMMAND_ATLAS               "Atlas"
30#define SKJSONCANVAS_COMMAND_PATH                "Path"
31#define SKJSONCANVAS_COMMAND_IMAGE               "Image"
32#define SKJSONCANVAS_COMMAND_IMAGERECT           "ImageRect"
33#define SKJSONCANVAS_COMMAND_IMAGENINE           "ImageNine"
34#define SKJSONCANVAS_COMMAND_BITMAP              "Bitmap"
35#define SKJSONCANVAS_COMMAND_BITMAPRECT          "BitmapRect"
36#define SKJSONCANVAS_COMMAND_BITMAPNINE          "BitmapNine"
37#define SKJSONCANVAS_COMMAND_TEXT                "Text"
38#define SKJSONCANVAS_COMMAND_POSTEXT             "PosText"
39#define SKJSONCANVAS_COMMAND_POSTEXTH            "PosTextH"
40#define SKJSONCANVAS_COMMAND_TEXTONPATH          "TextOnPath"
41#define SKJSONCANVAS_COMMAND_TEXTBLOB            "TextBlob"
42#define SKJSONCANVAS_COMMAND_PATCH               "Patch"
43#define SKJSONCANVAS_COMMAND_DRAWABLE            "Drawable"
44#define SKJSONCANVAS_COMMAND_CLIPRECT            "ClipRect"
45#define SKJSONCANVAS_COMMAND_CLIPRRECT           "ClipRRect"
46#define SKJSONCANVAS_COMMAND_CLIPPATH            "ClipPath"
47#define SKJSONCANVAS_COMMAND_CLIPREGION          "ClipRegion"
48#define SKJSONCANVAS_COMMAND_SAVE                "Save"
49#define SKJSONCANVAS_COMMAND_RESTORE             "Restore"
50#define SKJSONCANVAS_COMMAND_SAVELAYER           "SaveLayer"
51
52#define SKJSONCANVAS_ATTRIBUTE_MATRIX            "matrix"
53#define SKJSONCANVAS_ATTRIBUTE_COORDS            "coords"
54#define SKJSONCANVAS_ATTRIBUTE_BOUNDS            "bounds"
55#define SKJSONCANVAS_ATTRIBUTE_PAINT             "paint"
56#define SKJSONCANVAS_ATTRIBUTE_OUTER             "outer"
57#define SKJSONCANVAS_ATTRIBUTE_INNER             "inner"
58#define SKJSONCANVAS_ATTRIBUTE_MODE              "mode"
59#define SKJSONCANVAS_ATTRIBUTE_POINTS            "points"
60#define SKJSONCANVAS_ATTRIBUTE_PATH              "path"
61#define SKJSONCANVAS_ATTRIBUTE_TEXT              "text"
62#define SKJSONCANVAS_ATTRIBUTE_COLOR             "color"
63#define SKJSONCANVAS_ATTRIBUTE_ALPHA             "alpha"
64#define SKJSONCANVAS_ATTRIBUTE_STYLE             "style"
65#define SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH       "strokeWidth"
66#define SKJSONCANVAS_ATTRIBUTE_STROKEMITER       "strokeMiter"
67#define SKJSONCANVAS_ATTRIBUTE_CAP               "cap"
68#define SKJSONCANVAS_ATTRIBUTE_ANTIALIAS         "antiAlias"
69#define SKJSONCANVAS_ATTRIBUTE_REGION            "region"
70#define SKJSONCANVAS_ATTRIBUTE_REGIONOP          "op"
71#define SKJSONCANVAS_ATTRIBUTE_EDGESTYLE         "edgeStyle"
72#define SKJSONCANVAS_ATTRIBUTE_DEVICEREGION      "deviceRegion"
73#define SKJSONCANVAS_ATTRIBUTE_BLUR              "blur"
74#define SKJSONCANVAS_ATTRIBUTE_SIGMA             "sigma"
75#define SKJSONCANVAS_ATTRIBUTE_QUALITY           "quality"
76#define SKJSONCANVAS_ATTRIBUTE_TEXTALIGN         "textAlign"
77#define SKJSONCANVAS_ATTRIBUTE_TEXTSIZE          "textSize"
78#define SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX        "textScaleX"
79#define SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX         "textSkewX"
80#define SKJSONCANVAS_ATTRIBUTE_DASHING           "dashing"
81#define SKJSONCANVAS_ATTRIBUTE_INTERVALS         "intervals"
82#define SKJSONCANVAS_ATTRIBUTE_PHASE             "phase"
83#define SKJSONCANVAS_ATTRIBUTE_FILLTYPE          "fillType"
84#define SKJSONCANVAS_ATTRIBUTE_VERBS             "verbs"
85#define SKJSONCANVAS_ATTRIBUTE_NAME              "name"
86#define SKJSONCANVAS_ATTRIBUTE_BYTES             "bytes"
87#define SKJSONCANVAS_ATTRIBUTE_SHADER            "shader"
88#define SKJSONCANVAS_ATTRIBUTE_PATHEFFECT        "pathEffect"
89#define SKJSONCANVAS_ATTRIBUTE_MASKFILTER        "maskFilter"
90#define SKJSONCANVAS_ATTRIBUTE_XFERMODE          "xfermode"
91#define SKJSONCANVAS_ATTRIBUTE_BACKDROP          "backdrop"
92#define SKJSONCANVAS_ATTRIBUTE_COLORFILTER       "colorfilter"
93#define SKJSONCANVAS_ATTRIBUTE_IMAGEFILTER       "imagefilter"
94#define SKJSONCANVAS_ATTRIBUTE_IMAGE             "image"
95#define SKJSONCANVAS_ATTRIBUTE_BITMAP            "bitmap"
96#define SKJSONCANVAS_ATTRIBUTE_SRC               "src"
97#define SKJSONCANVAS_ATTRIBUTE_DST               "dst"
98#define SKJSONCANVAS_ATTRIBUTE_STRICT            "strict"
99#define SKJSONCANVAS_ATTRIBUTE_DESCRIPTION       "description"
100#define SKJSONCANVAS_ATTRIBUTE_X                 "x"
101#define SKJSONCANVAS_ATTRIBUTE_Y                 "y"
102#define SKJSONCANVAS_ATTRIBUTE_RUNS              "runs"
103#define SKJSONCANVAS_ATTRIBUTE_POSITIONS         "positions"
104#define SKJSONCANVAS_ATTRIBUTE_GLYPHS            "glyphs"
105#define SKJSONCANVAS_ATTRIBUTE_FONT              "font"
106#define SKJSONCANVAS_ATTRIBUTE_TYPEFACE          "typeface"
107
108#define SKJSONCANVAS_VERB_MOVE                   "move"
109#define SKJSONCANVAS_VERB_LINE                   "line"
110#define SKJSONCANVAS_VERB_QUAD                   "quad"
111#define SKJSONCANVAS_VERB_CUBIC                  "cubic"
112#define SKJSONCANVAS_VERB_CONIC                  "conic"
113#define SKJSONCANVAS_VERB_CLOSE                  "close"
114
115#define SKJSONCANVAS_STYLE_FILL                  "fill"
116#define SKJSONCANVAS_STYLE_STROKE                "stroke"
117#define SKJSONCANVAS_STYLE_STROKEANDFILL         "strokeAndFill"
118
119#define SKJSONCANVAS_POINTMODE_POINTS            "points"
120#define SKJSONCANVAS_POINTMODE_LINES             "lines"
121#define SKJSONCANVAS_POINTMODE_POLYGON           "polygon"
122
123#define SKJSONCANVAS_REGIONOP_DIFFERENCE         "difference"
124#define SKJSONCANVAS_REGIONOP_INTERSECT          "intersect"
125#define SKJSONCANVAS_REGIONOP_UNION              "union"
126#define SKJSONCANVAS_REGIONOP_XOR                "xor"
127#define SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
128#define SKJSONCANVAS_REGIONOP_REPLACE            "replace"
129
130#define SKJSONCANVAS_BLURSTYLE_NORMAL            "normal"
131#define SKJSONCANVAS_BLURSTYLE_SOLID             "solid"
132#define SKJSONCANVAS_BLURSTYLE_OUTER             "outer"
133#define SKJSONCANVAS_BLURSTYLE_INNER             "inner"
134
135#define SKJSONCANVAS_BLURQUALITY_LOW             "low"
136#define SKJSONCANVAS_BLURQUALITY_HIGH            "high"
137
138#define SKJSONCANVAS_ALIGN_LEFT                  "left"
139#define SKJSONCANVAS_ALIGN_CENTER                "center"
140#define SKJSONCANVAS_ALIGN_RIGHT                 "right"
141
142#define SKJSONCANVAS_FILLTYPE_WINDING            "winding"
143#define SKJSONCANVAS_FILLTYPE_EVENODD            "evenOdd"
144#define SKJSONCANVAS_FILLTYPE_INVERSEWINDING     "inverseWinding"
145#define SKJSONCANVAS_FILLTYPE_INVERSEEVENODD     "inverseEvenOdd"
146
147#define SKJSONCANVAS_CAP_BUTT                    "butt"
148#define SKJSONCANVAS_CAP_ROUND                   "round"
149#define SKJSONCANVAS_CAP_SQUARE                  "square"
150
151#define SKJSONCANVAS_COLORTYPE_ARGB4444          "ARGB4444"
152#define SKJSONCANVAS_COLORTYPE_RGBA8888          "RGBA8888"
153#define SKJSONCANVAS_COLORTYPE_BGRA8888          "BGRA8888"
154#define SKJSONCANVAS_COLORTYPE_565               "565"
155#define SKJSONCANVAS_COLORTYPE_GRAY8             "Gray8"
156#define SKJSONCANVAS_COLORTYPE_INDEX8            "Index8"
157#define SKJSONCANVAS_COLORTYPE_ALPHA8            "Alpha8"
158
159#define SKJSONCANVAS_ALPHATYPE_OPAQUE            "opaque"
160#define SKJSONCANVAS_ALPHATYPE_PREMUL            "premul"
161#define SKJSONCANVAS_ALPHATYPE_UNPREMUL          "unpremul"
162
163/*
164 * Implementation of SkCanvas which writes JSON when drawn to. The JSON describes all of the draw
165 * commands issued to the canvas, and can later be turned back into draw commands using
166 * SkJSONRenderer. Be sure to call finish() when you are done drawing.
167 */
168class SkJSONCanvas : public SkCanvas {
169public:
170    /* Create a canvas which writes to the specified output stream. */
171    SkJSONCanvas(int width, int height, SkWStream& out, bool sendBinaries = false);
172
173    /* Complete the JSON document. */
174    void finish();
175
176    static Json::Value MakeMatrix(const SkMatrix& matrix);
177
178    static Json::Value MakeIRect(const SkIRect& irect);
179
180    // overridden SkCanvas API
181
182    void didConcat(const SkMatrix&) override;
183
184    void didSetMatrix(const SkMatrix&) override;
185
186    void onDrawPaint(const SkPaint&) override;
187
188    void onDrawRect(const SkRect&, const SkPaint&) override;
189
190    void onDrawOval(const SkRect&, const SkPaint&) override;
191
192    void onDrawRRect(const SkRRect&, const SkPaint&) override;
193
194    void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
195
196    void onDrawPoints(SkCanvas::PointMode, size_t count, const SkPoint pts[],
197                      const SkPaint&) override;
198
199    void onDrawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint vertices[],
200                        const SkPoint texs[], const SkColor colors[], SkXfermode*,
201                        const uint16_t indices[], int indexCount, const SkPaint&) override;
202
203    void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
204                     int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) override;
205
206    void onDrawPath(const SkPath&, const SkPaint&) override;
207
208    void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override;
209
210    void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
211                         SrcRectConstraint) override;
212
213    void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
214                         const SkPaint*) override;
215
216    void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*) override;
217
218    void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
219                          SkCanvas::SrcRectConstraint) override;
220
221    void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
222                          const SkPaint*) override;
223
224    void onDrawText(const void* text, size_t byteLength, SkScalar x,
225                    SkScalar y, const SkPaint& paint) override;
226
227    void onDrawPosText(const void* text, size_t byteLength,
228                       const SkPoint pos[], const SkPaint& paint) override;
229
230    void onDrawPosTextH(const void* text, size_t byteLength,
231                        const SkScalar xpos[], SkScalar constY,
232                        const SkPaint& paint) override;
233
234    void onDrawTextOnPath(const void* text, size_t byteLength,
235                          const SkPath& path, const SkMatrix* matrix,
236                          const SkPaint& paint) override;
237
238    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
239                        const SkPaint& paint) override;
240
241    void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
242                     const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) override;
243
244    void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
245
246    void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override;
247
248    void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override;
249
250    void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) override;
251
252    void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) override;
253
254    void willSave() override;
255
256    void willRestore() override;
257
258    SkCanvas::SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override;
259
260private:
261    // Helpers to turn values into JSON, these could probably be static
262    Json::Value makePoint(const SkPoint& point);
263
264    Json::Value makePoint(SkScalar x, SkScalar y);
265
266    Json::Value makeRect(const SkRect& rect);
267
268    Json::Value makeRRect(const SkRRect& rrect);
269
270    Json::Value makePath(const SkPath& path);
271
272    Json::Value makeRegion(const SkRegion& region);
273
274    Json::Value makePaint(const SkPaint& paint);
275
276    Json::Value makeRegionOp(SkRegion::Op op);
277
278    Json::Value makeEdgeStyle(SkCanvas::ClipEdgeStyle edgeStyle);
279
280    Json::Value makePointMode(SkCanvas::PointMode mode);
281
282    void updateMatrix();
283
284    SkWStream&  fOut;
285    Json::Value fRoot;
286    Json::Value fCommands;
287    bool        fSendBinaries;
288
289    typedef SkCanvas INHERITED;
290};
291
292#endif
293