OLD | NEW |
| (Empty) |
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 #include "SkJSONRenderer.h" | |
9 | |
10 #include "SkBlurMaskFilter.h" | |
11 #include "SkDashPathEffect.h" | |
12 #include "SkJSONCanvas.h" | |
13 #include "SkJSONCPP.h" | |
14 #include "SkPath.h" | |
15 #include "SkTextBlob.h" | |
16 #include "SkTypeface.h" | |
17 #include "SkValidatingReadBuffer.h" | |
18 | |
19 namespace SkJSONRenderer { | |
20 | |
21 class Renderer { | |
22 public: | |
23 void getPaint(Json::Value& paint, SkPaint* result); | |
24 | |
25 void getRect(Json::Value& rect, SkRect* result); | |
26 | |
27 void getRRect(Json::Value& rrect, SkRRect* result); | |
28 | |
29 void getPath(Json::Value& path, SkPath* result); | |
30 | |
31 void getMatrix(Json::Value& matrix, SkMatrix* result); | |
32 | |
33 SkRegion::Op getRegionOp(Json::Value& op); | |
34 | |
35 void processCommand(Json::Value& command, SkCanvas* target); | |
36 | |
37 void processTranslate(Json::Value& command, SkCanvas* target); | |
38 | |
39 void processScale(Json::Value& command, SkCanvas* target); | |
40 | |
41 void processMatrix(Json::Value& command, SkCanvas* target); | |
42 | |
43 void processSave(Json::Value& command, SkCanvas* target); | |
44 | |
45 void processRestore(Json::Value& command, SkCanvas* target); | |
46 | |
47 void processSaveLayer(Json::Value& command, SkCanvas* target); | |
48 | |
49 void processPaint(Json::Value& command, SkCanvas* target); | |
50 | |
51 void processRect(Json::Value& command, SkCanvas* target); | |
52 | |
53 void processRRect(Json::Value& command, SkCanvas* target); | |
54 | |
55 void processOval(Json::Value& command, SkCanvas* target); | |
56 | |
57 void processPath(Json::Value& command, SkCanvas* target); | |
58 | |
59 void processText(Json::Value& command, SkCanvas* target); | |
60 | |
61 void processPosText(Json::Value& command, SkCanvas* target); | |
62 | |
63 void processTextOnPath(Json::Value& command, SkCanvas* target); | |
64 | |
65 void processTextBlob(Json::Value& command, SkCanvas* target); | |
66 | |
67 void processPoints(Json::Value& command, SkCanvas* target); | |
68 | |
69 void processImage(Json::Value& command, SkCanvas* target); | |
70 | |
71 void processImageRect(Json::Value& command, SkCanvas* target); | |
72 | |
73 void processBitmap(Json::Value& command, SkCanvas* target); | |
74 | |
75 void processBitmapRect(Json::Value& command, SkCanvas* target); | |
76 | |
77 void processClipRect(Json::Value& command, SkCanvas* target); | |
78 | |
79 void processClipRRect(Json::Value& command, SkCanvas* target); | |
80 | |
81 void processClipPath(Json::Value& command, SkCanvas* target); | |
82 }; | |
83 | |
84 void Renderer::processCommand(Json::Value& command, SkCanvas* target) { | |
85 const char* name = command[SKJSONCANVAS_COMMAND].asCString(); | |
86 // TODO speed this up with a hash | |
87 if (!strcmp(name, SKJSONCANVAS_COMMAND_TRANSLATE)) { | |
88 this->processTranslate(command, target); | |
89 } | |
90 else if (!strcmp(name, SKJSONCANVAS_COMMAND_SCALE)) { | |
91 this->processScale(command, target); | |
92 } | |
93 else if (!strcmp(name, SKJSONCANVAS_COMMAND_MATRIX)) { | |
94 this->processMatrix(command, target); | |
95 } | |
96 else if (!strcmp(name, SKJSONCANVAS_COMMAND_SAVE)) { | |
97 this->processSave(command, target); | |
98 } | |
99 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RESTORE)) { | |
100 this->processRestore(command, target); | |
101 } | |
102 else if (!strcmp(name, SKJSONCANVAS_COMMAND_SAVELAYER)) { | |
103 this->processSaveLayer(command, target); | |
104 } | |
105 else if (!strcmp(name, SKJSONCANVAS_COMMAND_PAINT)) { | |
106 this->processPaint(command, target); | |
107 } | |
108 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RECT)) { | |
109 this->processRect(command, target); | |
110 } | |
111 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RRECT)) { | |
112 this->processRRect(command, target); | |
113 } | |
114 else if (!strcmp(name, SKJSONCANVAS_COMMAND_OVAL)) { | |
115 this->processOval(command, target); | |
116 } | |
117 else if (!strcmp(name, SKJSONCANVAS_COMMAND_PATH)) { | |
118 this->processPath(command, target); | |
119 } | |
120 else if (!strcmp(name, SKJSONCANVAS_COMMAND_TEXT)) { | |
121 this->processText(command, target); | |
122 } | |
123 else if (!strcmp(name, SKJSONCANVAS_COMMAND_POSTEXT)) { | |
124 this->processPosText(command, target); | |
125 } | |
126 else if (!strcmp(name, SKJSONCANVAS_COMMAND_TEXTONPATH)) { | |
127 this->processTextOnPath(command, target); | |
128 } | |
129 else if (!strcmp(name, SKJSONCANVAS_COMMAND_TEXTBLOB)) { | |
130 this->processTextBlob(command, target); | |
131 } | |
132 else if (!strcmp(name, SKJSONCANVAS_COMMAND_POINTS)) { | |
133 this->processPoints(command, target); | |
134 } | |
135 else if (!strcmp(name, SKJSONCANVAS_COMMAND_IMAGE)) { | |
136 this->processImage(command, target); | |
137 } | |
138 else if (!strcmp(name, SKJSONCANVAS_COMMAND_IMAGERECT)) { | |
139 this->processImageRect(command, target); | |
140 } | |
141 else if (!strcmp(name, SKJSONCANVAS_COMMAND_BITMAP)) { | |
142 this->processBitmap(command, target); | |
143 } | |
144 else if (!strcmp(name, SKJSONCANVAS_COMMAND_BITMAPRECT)) { | |
145 this->processBitmapRect(command, target); | |
146 } | |
147 else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRECT)) { | |
148 this->processClipRect(command, target); | |
149 } | |
150 else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRRECT)) { | |
151 this->processClipRRect(command, target); | |
152 } | |
153 else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPPATH)) { | |
154 this->processClipPath(command, target); | |
155 } | |
156 else { | |
157 SkDebugf("unsupported JSON command: %s\n", name); | |
158 } | |
159 } | |
160 | |
161 static void apply_paint_color(Json::Value& jsonPaint, SkPaint* target) { | |
162 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_COLOR)) { | |
163 Json::Value color = jsonPaint[SKJSONCANVAS_ATTRIBUTE_COLOR]; | |
164 target->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), colo
r[2].asInt(), | |
165 color[3].asInt())); | |
166 } | |
167 } | |
168 | |
169 // note that the caller is responsible for freeing the pointer | |
170 static Json::ArrayIndex decode_data(Json::Value bytes, void** target) { | |
171 Json::ArrayIndex size = bytes.size(); | |
172 *target = sk_malloc_throw(size); | |
173 for (Json::ArrayIndex i = 0; i < size; i++) { | |
174 ((uint8_t*) *target)[i] = bytes[i].asInt(); | |
175 } | |
176 return size; | |
177 } | |
178 | |
179 static SkFlattenable* load_flattenable(Json::Value jsonFlattenable) { | |
180 if (!jsonFlattenable.isMember(SKJSONCANVAS_ATTRIBUTE_NAME)) { | |
181 return nullptr; | |
182 } | |
183 const char* name = jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_NAME].asCString(); | |
184 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name); | |
185 if (factory == nullptr) { | |
186 SkDebugf("no factory for loading '%s'\n", name); | |
187 return nullptr; | |
188 } | |
189 void* data; | |
190 int size = decode_data(jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_BYTES], &data)
; | |
191 SkValidatingReadBuffer buffer(data, size); | |
192 SkFlattenable* result = factory(buffer); | |
193 free(data); | |
194 if (!buffer.isValid()) { | |
195 SkDebugf("invalid buffer loading flattenable\n"); | |
196 return nullptr; | |
197 } | |
198 return result; | |
199 } | |
200 | |
201 static SkColorType colortype_from_name(const char* name) { | |
202 if (!strcmp(name, SKJSONCANVAS_COLORTYPE_ARGB4444)) { | |
203 return kARGB_4444_SkColorType; | |
204 } | |
205 else if (!strcmp(name, SKJSONCANVAS_COLORTYPE_RGBA8888)) { | |
206 return kRGBA_8888_SkColorType; | |
207 } | |
208 else if (!strcmp(name, SKJSONCANVAS_COLORTYPE_BGRA8888)) { | |
209 return kBGRA_8888_SkColorType; | |
210 } | |
211 else if (!strcmp(name, SKJSONCANVAS_COLORTYPE_565)) { | |
212 return kRGB_565_SkColorType; | |
213 } | |
214 else if (!strcmp(name, SKJSONCANVAS_COLORTYPE_GRAY8)) { | |
215 return kGray_8_SkColorType; | |
216 } | |
217 else if (!strcmp(name, SKJSONCANVAS_COLORTYPE_INDEX8)) { | |
218 return kIndex_8_SkColorType; | |
219 } | |
220 else if (!strcmp(name, SKJSONCANVAS_COLORTYPE_ALPHA8)) { | |
221 return kAlpha_8_SkColorType; | |
222 } | |
223 SkASSERT(false); | |
224 return kN32_SkColorType; | |
225 } | |
226 | |
227 static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) { | |
228 if (bitmap->colorType() == colorType ) { | |
229 return bitmap; | |
230 } | |
231 SkBitmap* dst = new SkBitmap(); | |
232 if (bitmap->copyTo(dst, colorType)) { | |
233 delete bitmap; | |
234 return dst; | |
235 } | |
236 SkASSERT(false); | |
237 delete dst; | |
238 return bitmap; | |
239 } | |
240 | |
241 // caller is responsible for freeing return value | |
242 static SkBitmap* load_bitmap(const Json::Value& jsonBitmap) { | |
243 if (!jsonBitmap.isMember(SKJSONCANVAS_ATTRIBUTE_BYTES)) { | |
244 SkDebugf("invalid bitmap\n"); | |
245 return nullptr; | |
246 } | |
247 void* data; | |
248 int size = decode_data(jsonBitmap[SKJSONCANVAS_ATTRIBUTE_BYTES], &data); | |
249 SkMemoryStream stream(data, size); | |
250 SkImageDecoder* decoder = SkImageDecoder::Factory(&stream); | |
251 SkBitmap* bitmap = new SkBitmap(); | |
252 SkImageDecoder::Result result = decoder->decode(&stream, bitmap, | |
253 SkImageDecoder::kDecodePixel
s_Mode); | |
254 free(decoder); | |
255 if (result != SkImageDecoder::kFailure) { | |
256 free(data); | |
257 if (jsonBitmap.isMember(SKJSONCANVAS_ATTRIBUTE_COLOR)) { | |
258 const char* ctName = jsonBitmap[SKJSONCANVAS_ATTRIBUTE_COLOR].asCStr
ing(); | |
259 SkColorType ct = colortype_from_name(ctName); | |
260 if (ct != kIndex_8_SkColorType) { | |
261 bitmap = convert_colortype(bitmap, ct); | |
262 } | |
263 } | |
264 return bitmap; | |
265 } | |
266 SkDebugf("image decode failed\n"); | |
267 free(data); | |
268 return nullptr; | |
269 } | |
270 | |
271 static SkImage* load_image(const Json::Value& jsonImage) { | |
272 SkBitmap* bitmap = load_bitmap(jsonImage); | |
273 if (bitmap == nullptr) { | |
274 return nullptr; | |
275 } | |
276 SkImage* result = SkImage::NewFromBitmap(*bitmap); | |
277 delete bitmap; | |
278 return result; | |
279 } | |
280 | |
281 static void apply_paint_shader(Json::Value& jsonPaint, SkPaint* target) { | |
282 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_SHADER)) { | |
283 Json::Value jsonShader = jsonPaint[SKJSONCANVAS_ATTRIBUTE_SHADER]; | |
284 SkShader* shader = (SkShader*) load_flattenable(jsonShader); | |
285 if (shader != nullptr) { | |
286 target->setShader(shader); | |
287 shader->unref(); | |
288 } | |
289 } | |
290 } | |
291 | |
292 static void apply_paint_patheffect(Json::Value& jsonPaint, SkPaint* target) { | |
293 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_PATHEFFECT)) { | |
294 Json::Value jsonPathEffect = jsonPaint[SKJSONCANVAS_ATTRIBUTE_PATHEFFECT
]; | |
295 SkPathEffect* pathEffect = (SkPathEffect*) load_flattenable(jsonPathEffe
ct); | |
296 if (pathEffect != nullptr) { | |
297 target->setPathEffect(pathEffect); | |
298 pathEffect->unref(); | |
299 } | |
300 } | |
301 } | |
302 | |
303 static void apply_paint_maskfilter(Json::Value& jsonPaint, SkPaint* target) { | |
304 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_MASKFILTER)) { | |
305 Json::Value jsonMaskFilter = jsonPaint[SKJSONCANVAS_ATTRIBUTE_MASKFILTER
]; | |
306 SkMaskFilter* maskFilter = (SkMaskFilter*) load_flattenable(jsonMaskFilt
er); | |
307 if (maskFilter != nullptr) { | |
308 target->setMaskFilter(maskFilter); | |
309 maskFilter->unref(); | |
310 } | |
311 } | |
312 } | |
313 | |
314 static void apply_paint_colorfilter(Json::Value& jsonPaint, SkPaint* target) { | |
315 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_COLORFILTER)) { | |
316 Json::Value jsonColorFilter = jsonPaint[SKJSONCANVAS_ATTRIBUTE_COLORFILT
ER]; | |
317 SkColorFilter* colorFilter = (SkColorFilter*) load_flattenable(jsonColor
Filter); | |
318 if (colorFilter != nullptr) { | |
319 target->setColorFilter(colorFilter); | |
320 colorFilter->unref(); | |
321 } | |
322 } | |
323 } | |
324 | |
325 static void apply_paint_xfermode(Json::Value& jsonPaint, SkPaint* target) { | |
326 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_XFERMODE)) { | |
327 Json::Value jsonXfermode = jsonPaint[SKJSONCANVAS_ATTRIBUTE_XFERMODE]; | |
328 SkXfermode* xfermode = (SkXfermode*) load_flattenable(jsonXfermode); | |
329 if (xfermode != nullptr) { | |
330 target->setXfermode(xfermode); | |
331 xfermode->unref(); | |
332 } | |
333 } | |
334 } | |
335 | |
336 static void apply_paint_imagefilter(Json::Value& jsonPaint, SkPaint* target) { | |
337 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_IMAGEFILTER)) { | |
338 Json::Value jsonImageFilter = jsonPaint[SKJSONCANVAS_ATTRIBUTE_IMAGEFILT
ER]; | |
339 SkImageFilter* imageFilter = (SkImageFilter*) load_flattenable(jsonImage
Filter); | |
340 if (imageFilter != nullptr) { | |
341 target->setImageFilter(imageFilter); | |
342 imageFilter->unref(); | |
343 } | |
344 } | |
345 } | |
346 | |
347 static void apply_paint_style(Json::Value& jsonPaint, SkPaint* target) { | |
348 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STYLE)) { | |
349 const char* style = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STYLE].asCString(); | |
350 if (!strcmp(style, SKJSONCANVAS_STYLE_FILL)) { | |
351 target->setStyle(SkPaint::kFill_Style); | |
352 } | |
353 else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKE)) { | |
354 target->setStyle(SkPaint::kStroke_Style); | |
355 } | |
356 else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKEANDFILL)) { | |
357 target->setStyle(SkPaint::kStrokeAndFill_Style); | |
358 } | |
359 } | |
360 } | |
361 | |
362 static void apply_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) { | |
363 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH)) { | |
364 float strokeWidth = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH].asFloa
t(); | |
365 target->setStrokeWidth(strokeWidth); | |
366 } | |
367 } | |
368 | |
369 static void apply_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) { | |
370 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STROKEMITER)) { | |
371 float strokeMiter = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STROKEMITER].asFloa
t(); | |
372 target->setStrokeMiter(strokeMiter); | |
373 } | |
374 } | |
375 | |
376 static void apply_paint_cap(Json::Value& jsonPaint, SkPaint* target) { | |
377 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_CAP)) { | |
378 const char* cap = jsonPaint[SKJSONCANVAS_ATTRIBUTE_CAP].asCString(); | |
379 if (!strcmp(cap, SKJSONCANVAS_CAP_BUTT)) { | |
380 target->setStrokeCap(SkPaint::kButt_Cap); | |
381 } | |
382 else if (!strcmp(cap, SKJSONCANVAS_CAP_ROUND)) { | |
383 target->setStrokeCap(SkPaint::kRound_Cap); | |
384 } | |
385 else if (!strcmp(cap, SKJSONCANVAS_CAP_SQUARE)) { | |
386 target->setStrokeCap(SkPaint::kSquare_Cap); | |
387 } | |
388 } | |
389 } | |
390 | |
391 static void apply_paint_antialias(Json::Value& jsonPaint, SkPaint* target) { | |
392 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_ANTIALIAS)) { | |
393 target->setAntiAlias(jsonPaint[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool(
)); | |
394 } | |
395 } | |
396 | |
397 static void apply_paint_blur(Json::Value& jsonPaint, SkPaint* target) { | |
398 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_BLUR)) { | |
399 Json::Value blur = jsonPaint[SKJSONCANVAS_ATTRIBUTE_BLUR]; | |
400 SkScalar sigma = blur[SKJSONCANVAS_ATTRIBUTE_SIGMA].asFloat(); | |
401 SkBlurStyle style; | |
402 const char* jsonStyle = blur[SKJSONCANVAS_ATTRIBUTE_STYLE].asCString(); | |
403 if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_NORMAL)) { | |
404 style = SkBlurStyle::kNormal_SkBlurStyle; | |
405 } | |
406 else if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_SOLID)) { | |
407 style = SkBlurStyle::kSolid_SkBlurStyle; | |
408 } | |
409 else if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_OUTER)) { | |
410 style = SkBlurStyle::kOuter_SkBlurStyle; | |
411 } | |
412 else if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_INNER)) { | |
413 style = SkBlurStyle::kInner_SkBlurStyle; | |
414 } | |
415 else { | |
416 SkASSERT(false); | |
417 style = SkBlurStyle::kNormal_SkBlurStyle; | |
418 } | |
419 SkBlurMaskFilter::BlurFlags flags; | |
420 const char* jsonQuality = blur[SKJSONCANVAS_ATTRIBUTE_QUALITY].asCString
(); | |
421 if (!strcmp(jsonQuality, SKJSONCANVAS_BLURQUALITY_LOW)) { | |
422 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag; | |
423 } | |
424 else if (!strcmp(jsonQuality, SKJSONCANVAS_BLURQUALITY_HIGH)) { | |
425 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag; | |
426 } | |
427 else { | |
428 SkASSERT(false); | |
429 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag; | |
430 } | |
431 target->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags)); | |
432 } | |
433 } | |
434 | |
435 static void apply_paint_dashing(Json::Value& jsonPaint, SkPaint* target) { | |
436 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_DASHING)) { | |
437 Json::Value dash = jsonPaint[SKJSONCANVAS_ATTRIBUTE_DASHING]; | |
438 Json::Value jsonIntervals = dash[SKJSONCANVAS_ATTRIBUTE_INTERVALS]; | |
439 Json::ArrayIndex count = jsonIntervals.size(); | |
440 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScala
r)); | |
441 for (Json::ArrayIndex i = 0; i < count; i++) { | |
442 intervals[i] = jsonIntervals[i].asFloat(); | |
443 } | |
444 SkScalar phase = dash[SKJSONCANVAS_ATTRIBUTE_PHASE].asFloat(); | |
445 target->setPathEffect(SkDashPathEffect::Create(intervals, count, phase))
; | |
446 free(intervals); | |
447 } | |
448 } | |
449 | |
450 static void apply_paint_textalign(Json::Value& jsonPaint, SkPaint* target) { | |
451 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTALIGN)) { | |
452 SkPaint::Align textAlign; | |
453 const char* jsonAlign = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN].asCS
tring(); | |
454 if (!strcmp(jsonAlign, SKJSONCANVAS_ALIGN_LEFT)) { | |
455 textAlign = SkPaint::kLeft_Align; | |
456 } | |
457 else if (!strcmp(jsonAlign, SKJSONCANVAS_ALIGN_CENTER)) { | |
458 textAlign = SkPaint::kCenter_Align; | |
459 } | |
460 else if (!strcmp(jsonAlign, SKJSONCANVAS_ALIGN_RIGHT)) { | |
461 textAlign = SkPaint::kRight_Align; | |
462 } | |
463 else { | |
464 SkASSERT(false); | |
465 textAlign = SkPaint::kLeft_Align; | |
466 } | |
467 target->setTextAlign(textAlign); | |
468 } | |
469 } | |
470 | |
471 static void apply_paint_textsize(Json::Value& jsonPaint, SkPaint* target) { | |
472 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSIZE)) { | |
473 float textSize = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSIZE].asFloat(); | |
474 target->setTextSize(textSize); | |
475 } | |
476 } | |
477 | |
478 static void apply_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) { | |
479 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX)) { | |
480 float textScaleX = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat(
); | |
481 target->setTextScaleX(textScaleX); | |
482 } | |
483 } | |
484 | |
485 static void apply_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) { | |
486 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX)) { | |
487 float textSkewX = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat(); | |
488 target->setTextSkewX(textSkewX); | |
489 } | |
490 } | |
491 | |
492 static void apply_paint_typeface(Json::Value& jsonPaint, SkPaint* target) { | |
493 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TYPEFACE)) { | |
494 Json::Value jsonTypeface = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TYPEFACE]; | |
495 Json::Value bytes = jsonTypeface[SKJSONCANVAS_ATTRIBUTE_BYTES]; | |
496 void* data; | |
497 Json::ArrayIndex length = decode_data(bytes, &data); | |
498 SkMemoryStream buffer(data, length); | |
499 SkTypeface* typeface = SkTypeface::Deserialize(&buffer); | |
500 free(data); | |
501 target->setTypeface(typeface); | |
502 } | |
503 } | |
504 | |
505 void Renderer::getPaint(Json::Value& paint, SkPaint* result) { | |
506 apply_paint_color(paint, result); | |
507 apply_paint_shader(paint, result); | |
508 apply_paint_patheffect(paint, result); | |
509 apply_paint_maskfilter(paint, result); | |
510 apply_paint_colorfilter(paint, result); | |
511 apply_paint_xfermode(paint, result); | |
512 apply_paint_imagefilter(paint, result); | |
513 apply_paint_style(paint, result); | |
514 apply_paint_strokewidth(paint, result); | |
515 apply_paint_strokemiter(paint, result); | |
516 apply_paint_cap(paint, result); | |
517 apply_paint_antialias(paint, result); | |
518 apply_paint_blur(paint, result); | |
519 apply_paint_dashing(paint, result); | |
520 apply_paint_textalign(paint, result); | |
521 apply_paint_textsize(paint, result); | |
522 apply_paint_textscalex(paint, result); | |
523 apply_paint_textskewx(paint, result); | |
524 apply_paint_typeface(paint, result); | |
525 } | |
526 | |
527 void Renderer::getRect(Json::Value& rect, SkRect* result) { | |
528 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3]
.asFloat()); | |
529 } | |
530 | |
531 void Renderer::getRRect(Json::Value& rrect, SkRRect* result) { | |
532 SkVector radii[4] = { | |
533 { rrect[1][0].asFloat(), rrect[1][1].asFloat() }, | |
534 { rrect[2][0].asFloat(), rrect[2][1].asFloat() }, | |
535 { rrect[3][0].asFloat(), rrect[3][1].asFloat() }, | |
536 { rrect[4][0].asFloat(), rrect[4][1].asFloat() } | |
537 }; | |
538 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asF
loat(), | |
539 rrect[0][2].asFloat(), rrect[0][3].asF
loat()), | |
540 radii); | |
541 } | |
542 | |
543 void Renderer::getMatrix(Json::Value& matrix, SkMatrix* result) { | |
544 SkScalar values[] = { | |
545 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(), | |
546 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(), | |
547 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat() | |
548 }; | |
549 result->set9(values); | |
550 } | |
551 | |
552 void Renderer::getPath(Json::Value& path, SkPath* result) { | |
553 const char* fillType = path[SKJSONCANVAS_ATTRIBUTE_FILLTYPE].asCString(); | |
554 if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_WINDING)) { | |
555 result->setFillType(SkPath::kWinding_FillType); | |
556 } | |
557 else if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_EVENODD)) { | |
558 result->setFillType(SkPath::kEvenOdd_FillType); | |
559 } | |
560 else if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_INVERSEWINDING)) { | |
561 result->setFillType(SkPath::kInverseWinding_FillType); | |
562 } | |
563 else if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_INVERSEEVENODD)) { | |
564 result->setFillType(SkPath::kInverseEvenOdd_FillType); | |
565 } | |
566 Json::Value verbs = path[SKJSONCANVAS_ATTRIBUTE_VERBS]; | |
567 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) { | |
568 Json::Value verb = verbs[i]; | |
569 if (verb.isString()) { | |
570 SkASSERT(!strcmp(verb.asCString(), SKJSONCANVAS_VERB_CLOSE)); | |
571 result->close(); | |
572 } | |
573 else { | |
574 if (verb.isMember(SKJSONCANVAS_VERB_MOVE)) { | |
575 Json::Value move = verb[SKJSONCANVAS_VERB_MOVE]; | |
576 result->moveTo(move[0].asFloat(), move[1].asFloat()); | |
577 } | |
578 else if (verb.isMember(SKJSONCANVAS_VERB_LINE)) { | |
579 Json::Value line = verb[SKJSONCANVAS_VERB_LINE]; | |
580 result->lineTo(line[0].asFloat(), line[1].asFloat()); | |
581 } | |
582 else if (verb.isMember(SKJSONCANVAS_VERB_QUAD)) { | |
583 Json::Value quad = verb[SKJSONCANVAS_VERB_QUAD]; | |
584 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(), | |
585 quad[1][0].asFloat(), quad[1][1].asFloat()); | |
586 } | |
587 else if (verb.isMember(SKJSONCANVAS_VERB_CUBIC)) { | |
588 Json::Value cubic = verb[SKJSONCANVAS_VERB_CUBIC]; | |
589 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(), | |
590 cubic[1][0].asFloat(), cubic[1][1].asFloat(), | |
591 cubic[2][0].asFloat(), cubic[2][1].asFloat()); | |
592 } | |
593 else if (verb.isMember(SKJSONCANVAS_VERB_CONIC)) { | |
594 Json::Value conic = verb[SKJSONCANVAS_VERB_CONIC]; | |
595 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(), | |
596 conic[1][0].asFloat(), conic[1][1].asFloat(), | |
597 conic[2].asFloat()); | |
598 } | |
599 else { | |
600 SkASSERT(false); | |
601 } | |
602 } | |
603 } | |
604 } | |
605 | |
606 SkRegion::Op Renderer::getRegionOp(Json::Value& jsonOp) { | |
607 const char* op = jsonOp.asCString(); | |
608 if (!strcmp(op, SKJSONCANVAS_REGIONOP_DIFFERENCE)) { | |
609 return SkRegion::kDifference_Op; | |
610 } | |
611 else if (!strcmp(op, SKJSONCANVAS_REGIONOP_INTERSECT)) { | |
612 return SkRegion::kIntersect_Op; | |
613 } | |
614 else if (!strcmp(op, SKJSONCANVAS_REGIONOP_UNION)) { | |
615 return SkRegion::kUnion_Op; | |
616 } | |
617 else if (!strcmp(op, SKJSONCANVAS_REGIONOP_XOR)) { | |
618 return SkRegion::kXOR_Op; | |
619 } | |
620 else if (!strcmp(op, SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE)) { | |
621 return SkRegion::kReverseDifference_Op; | |
622 } | |
623 else if (!strcmp(op, SKJSONCANVAS_REGIONOP_REPLACE)) { | |
624 return SkRegion::kReplace_Op; | |
625 } | |
626 SkASSERT(false); | |
627 return SkRegion::kIntersect_Op; | |
628 } | |
629 | |
630 void Renderer::processTranslate(Json::Value& command, SkCanvas* target) { | |
631 target->translate(command[SKJSONCANVAS_ATTRIBUTE_X].asFloat(), | |
632 command[SKJSONCANVAS_ATTRIBUTE_Y].asFloat()); | |
633 } | |
634 | |
635 void Renderer::processScale(Json::Value& command, SkCanvas* target) { | |
636 target->scale(command[SKJSONCANVAS_ATTRIBUTE_X].asFloat(), | |
637 command[SKJSONCANVAS_ATTRIBUTE_Y].asFloat()); | |
638 } | |
639 | |
640 void Renderer::processMatrix(Json::Value& command, SkCanvas* target) { | |
641 SkMatrix matrix; | |
642 this->getMatrix(command[SKJSONCANVAS_ATTRIBUTE_MATRIX], &matrix); | |
643 target->setMatrix(matrix); | |
644 } | |
645 | |
646 void Renderer::processSave(Json::Value& command, SkCanvas* target) { | |
647 target->save(); | |
648 } | |
649 | |
650 void Renderer::processRestore(Json::Value& command, SkCanvas* target) { | |
651 target->restore(); | |
652 } | |
653 | |
654 void Renderer::processSaveLayer(Json::Value& command, SkCanvas* target) { | |
655 SkCanvas::SaveLayerRec rec; | |
656 SkRect bounds; | |
657 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_BOUNDS)) { | |
658 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_BOUNDS], &bounds); | |
659 rec.fBounds = &bounds; | |
660 } | |
661 SkPaint paint; | |
662 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) { | |
663 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
664 rec.fPaint = &paint; | |
665 } | |
666 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_BACKDROP)) { | |
667 rec.fBackdrop = (SkImageFilter*) load_flattenable(command[SKJSONCANVAS_A
TTRIBUTE_BACKDROP]); | |
668 } | |
669 target->saveLayer(rec); | |
670 if (rec.fBackdrop != nullptr) { | |
671 rec.fBackdrop->unref(); | |
672 } | |
673 } | |
674 | |
675 void Renderer::processPaint(Json::Value& command, SkCanvas* target) { | |
676 SkPaint paint; | |
677 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
678 target->drawPaint(paint); | |
679 } | |
680 | |
681 void Renderer::processRect(Json::Value& command, SkCanvas* target) { | |
682 SkRect rect; | |
683 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_COORDS], &rect); | |
684 SkPaint paint; | |
685 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
686 target->drawRect(rect, paint); | |
687 } | |
688 | |
689 void Renderer::processRRect(Json::Value& command, SkCanvas* target) { | |
690 SkRRect rrect; | |
691 this->getRRect(command[SKJSONCANVAS_ATTRIBUTE_COORDS], &rrect); | |
692 SkPaint paint; | |
693 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
694 target->drawRRect(rrect, paint); | |
695 } | |
696 | |
697 void Renderer::processOval(Json::Value& command, SkCanvas* target) { | |
698 SkRect rect; | |
699 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_COORDS], &rect); | |
700 SkPaint paint; | |
701 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
702 target->drawOval(rect, paint); | |
703 } | |
704 | |
705 void Renderer::processPath(Json::Value& command, SkCanvas* target) { | |
706 SkPath path; | |
707 this->getPath(command[SKJSONCANVAS_ATTRIBUTE_PATH], &path); | |
708 SkPaint paint; | |
709 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
710 target->drawPath(path, paint); | |
711 } | |
712 | |
713 void Renderer::processText(Json::Value& command, SkCanvas* target) { | |
714 const char* text = command[SKJSONCANVAS_ATTRIBUTE_TEXT].asCString(); | |
715 SkPaint paint; | |
716 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
717 Json::Value coords = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
718 target->drawText(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(
), paint); | |
719 } | |
720 | |
721 void Renderer::processPosText(Json::Value& command, SkCanvas* target) { | |
722 const char* text = command[SKJSONCANVAS_ATTRIBUTE_TEXT].asCString(); | |
723 SkPaint paint; | |
724 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
725 Json::Value coords = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
726 int count = (int) coords.size(); | |
727 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); | |
728 for (int i = 0; i < count; i++) { | |
729 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat()
); | |
730 } | |
731 target->drawPosText(text, strlen(text), points, paint); | |
732 free(points); | |
733 } | |
734 | |
735 void Renderer::processTextOnPath(Json::Value& command, SkCanvas* target) { | |
736 const char* text = command[SKJSONCANVAS_ATTRIBUTE_TEXT].asCString(); | |
737 SkPath path; | |
738 this->getPath(command[SKJSONCANVAS_ATTRIBUTE_PATH], &path); | |
739 SkMatrix* matrixPtr; | |
740 SkMatrix matrix; | |
741 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_MATRIX)) { | |
742 this->getMatrix(command[SKJSONCANVAS_ATTRIBUTE_MATRIX], &matrix); | |
743 matrixPtr = &matrix; | |
744 } | |
745 else { | |
746 matrixPtr = nullptr; | |
747 } | |
748 SkPaint paint; | |
749 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
750 target->drawTextOnPath(text, strlen(text), path, matrixPtr, paint); | |
751 } | |
752 | |
753 void Renderer::processTextBlob(Json::Value& command, SkCanvas* target) { | |
754 SkTextBlobBuilder builder; | |
755 Json::Value runs = command[SKJSONCANVAS_ATTRIBUTE_RUNS]; | |
756 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) { | |
757 Json::Value run = runs[i]; | |
758 SkPaint font; | |
759 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | |
760 this->getPaint(run[SKJSONCANVAS_ATTRIBUTE_FONT], &font); | |
761 Json::Value glyphs = run[SKJSONCANVAS_ATTRIBUTE_GLYPHS]; | |
762 int count = glyphs.size(); | |
763 Json::Value coords = run[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
764 SkScalar x = coords[0].asFloat(); | |
765 SkScalar y = coords[1].asFloat(); | |
766 if (run.isMember(SKJSONCANVAS_ATTRIBUTE_POSITIONS)) { | |
767 Json::Value positions = run[SKJSONCANVAS_ATTRIBUTE_POSITIONS]; | |
768 if (positions.size() > 0 && positions[0].isNumeric()) { | |
769 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font,
count, y); | |
770 for (int j = 0; j < count; j++) { | |
771 buffer.glyphs[j] = glyphs[j].asUInt(); | |
772 buffer.pos[j] = positions[j].asFloat(); | |
773 } | |
774 } | |
775 else { | |
776 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font,
count); | |
777 for (int j = 0; j < count; j++) { | |
778 buffer.glyphs[j] = glyphs[j].asUInt(); | |
779 buffer.pos[j * 2] = positions[j][0].asFloat(); | |
780 buffer.pos[j * 2 + 1] = positions[j][1].asFloat(); | |
781 } | |
782 } | |
783 } | |
784 else { | |
785 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count,
x, y); | |
786 for (int j = 0; j < count; j++) { | |
787 buffer.glyphs[j] = glyphs[j].asUInt(); | |
788 } | |
789 } | |
790 } | |
791 SkScalar x = command[SKJSONCANVAS_ATTRIBUTE_X].asFloat(); | |
792 SkScalar y = command[SKJSONCANVAS_ATTRIBUTE_Y].asFloat(); | |
793 SkPaint paint; | |
794 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
795 target->drawTextBlob(builder.build(), x, y, paint); | |
796 } | |
797 | |
798 void Renderer::processPoints(Json::Value& command, SkCanvas* target) { | |
799 SkCanvas::PointMode mode; | |
800 const char* jsonMode = command[SKJSONCANVAS_ATTRIBUTE_MODE].asCString(); | |
801 if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_POINTS)) { | |
802 mode = SkCanvas::kPoints_PointMode; | |
803 } | |
804 else if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_LINES)) { | |
805 mode = SkCanvas::kLines_PointMode; | |
806 } | |
807 else if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_POLYGON)) { | |
808 mode = SkCanvas::kPolygon_PointMode; | |
809 } | |
810 else { | |
811 SkASSERT(false); | |
812 return; | |
813 } | |
814 Json::Value jsonPoints = command[SKJSONCANVAS_ATTRIBUTE_POINTS]; | |
815 int count = (int) jsonPoints.size(); | |
816 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); | |
817 for (int i = 0; i < count; i++) { | |
818 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].a
sFloat()); | |
819 } | |
820 SkPaint paint; | |
821 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
822 target->drawPoints(mode, count, points, paint); | |
823 free(points); | |
824 } | |
825 | |
826 void Renderer::processClipRect(Json::Value& command, SkCanvas* target) { | |
827 SkRect rect; | |
828 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_COORDS], &rect); | |
829 target->clipRect(rect, this->getRegionOp(command[SKJSONCANVAS_ATTRIBUTE_REGI
ONOP]), | |
830 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); | |
831 } | |
832 | |
833 void Renderer::processClipRRect(Json::Value& command, SkCanvas* target) { | |
834 SkRRect rrect; | |
835 this->getRRect(command[SKJSONCANVAS_ATTRIBUTE_COORDS], &rrect); | |
836 target->clipRRect(rrect, this->getRegionOp(command[SKJSONCANVAS_ATTRIBUTE_RE
GIONOP]), | |
837 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); | |
838 } | |
839 | |
840 void Renderer::processClipPath(Json::Value& command, SkCanvas* target) { | |
841 SkPath path; | |
842 this->getPath(command[SKJSONCANVAS_ATTRIBUTE_PATH], &path); | |
843 target->clipPath(path, this->getRegionOp(command[SKJSONCANVAS_ATTRIBUTE_REGI
ONOP]), | |
844 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); | |
845 } | |
846 | |
847 void Renderer::processImage(Json::Value& command, SkCanvas* target) { | |
848 SkImage* image = load_image(command[SKJSONCANVAS_ATTRIBUTE_IMAGE]); | |
849 if (image == nullptr) { | |
850 return; | |
851 } | |
852 Json::Value point = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
853 SkPaint* paintPtr; | |
854 SkPaint paint; | |
855 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) { | |
856 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
857 paintPtr = &paint; | |
858 } | |
859 else { | |
860 paintPtr = nullptr; | |
861 } | |
862 target->drawImage(image, point[0].asFloat(), point[1].asFloat(), paintPtr); | |
863 image->unref(); | |
864 } | |
865 | |
866 void Renderer::processImageRect(Json::Value& command, SkCanvas* target) { | |
867 SkImage* image = load_image(command[SKJSONCANVAS_ATTRIBUTE_IMAGE]); | |
868 if (image == nullptr) { | |
869 return; | |
870 } | |
871 SkRect dst; | |
872 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_DST], &dst); | |
873 SkPaint* paintPtr; | |
874 SkPaint paint; | |
875 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) { | |
876 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
877 paintPtr = &paint; | |
878 } | |
879 else { | |
880 paintPtr = nullptr; | |
881 } | |
882 SkCanvas::SrcRectConstraint constraint; | |
883 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_STRICT) && | |
884 command[SKJSONCANVAS_ATTRIBUTE_STRICT].asBool()) { | |
885 constraint = SkCanvas::kStrict_SrcRectConstraint; | |
886 } | |
887 else { | |
888 constraint = SkCanvas::kFast_SrcRectConstraint; | |
889 } | |
890 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_SRC)) { | |
891 SkRect src; | |
892 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_SRC], &src); | |
893 target->drawImageRect(image, src, dst, paintPtr, constraint); | |
894 } | |
895 else { | |
896 target->drawImageRect(image, dst, paintPtr, constraint); | |
897 } | |
898 image->unref(); | |
899 } | |
900 | |
901 void Renderer::processBitmap(Json::Value& command, SkCanvas* target) { | |
902 SkImage* image = load_image(command[SKJSONCANVAS_ATTRIBUTE_BITMAP]); | |
903 if (image == nullptr) { | |
904 return; | |
905 } | |
906 Json::Value point = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
907 SkPaint* paintPtr; | |
908 SkPaint paint; | |
909 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) { | |
910 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
911 paintPtr = &paint; | |
912 } | |
913 else { | |
914 paintPtr = nullptr; | |
915 } | |
916 target->drawImage(image, point[0].asFloat(), point[1].asFloat(), paintPtr); | |
917 image->unref(); | |
918 } | |
919 | |
920 void Renderer::processBitmapRect(Json::Value& command, SkCanvas* target) { | |
921 SkBitmap* bitmap = load_bitmap(command[SKJSONCANVAS_ATTRIBUTE_BITMAP]); | |
922 if (bitmap == nullptr) { | |
923 return; | |
924 } | |
925 SkRect dst; | |
926 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_DST], &dst); | |
927 SkPaint* paintPtr; | |
928 SkPaint paint; | |
929 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) { | |
930 this->getPaint(command[SKJSONCANVAS_ATTRIBUTE_PAINT], &paint); | |
931 paintPtr = &paint; | |
932 } | |
933 else { | |
934 paintPtr = nullptr; | |
935 } | |
936 SkCanvas::SrcRectConstraint constraint; | |
937 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_STRICT) && | |
938 command[SKJSONCANVAS_ATTRIBUTE_STRICT].asBool()) { | |
939 constraint = SkCanvas::kStrict_SrcRectConstraint; | |
940 } | |
941 else { | |
942 constraint = SkCanvas::kFast_SrcRectConstraint; | |
943 } | |
944 if (command.isMember(SKJSONCANVAS_ATTRIBUTE_SRC)) { | |
945 SkRect src; | |
946 this->getRect(command[SKJSONCANVAS_ATTRIBUTE_SRC], &src); | |
947 target->drawBitmapRect(*bitmap, src, dst, paintPtr, constraint); | |
948 } | |
949 else { | |
950 target->drawBitmapRect(*bitmap, dst, paintPtr, constraint); | |
951 } | |
952 free(bitmap); | |
953 } | |
954 | |
955 void render(const char* json, SkCanvas* target) { | |
956 Renderer renderer; | |
957 Json::Reader reader; | |
958 Json::Value root; | |
959 if (reader.parse(std::string(json), root)) { | |
960 SkASSERT(root[SKJSONCANVAS_VERSION].asInt() == 1); | |
961 Json::Value commands = root[SKJSONCANVAS_COMMANDS]; | |
962 for (Json::ArrayIndex i = 0; i < commands.size(); i++) { | |
963 renderer.processCommand(commands[i], target); | |
964 } | |
965 } | |
966 else { | |
967 SkDebugf(json); | |
968 SkFAIL("json parse failure"); | |
969 } | |
970 } | |
971 | |
972 } // namespace | |
OLD | NEW |