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 "SkJSONCanvas.h" 9 #include "SkColorFilter.h" 10 #include "SkImageFilter.h" 11 #include "SkMaskFilter.h" 12 #include "SkPaintDefaults.h" 13 #include "SkPath.h" 14 #include "SkPathEffect.h" 15 #include "SkRRect.h" 16 #include "SkTextBlob.h" 17 #include "SkTextBlobRunIterator.h" 18 #include "SkTypeface.h" 19 #include "SkWriteBuffer.h" 20 21 SkJSONCanvas::SkJSONCanvas(int width, int height, SkWStream& out, bool sendBinaries) 22 : INHERITED(width, height) 23 , fOut(out) 24 , fRoot(Json::objectValue) 25 , fCommands(Json::arrayValue) 26 , fSendBinaries(sendBinaries) { 27 fRoot[SKJSONCANVAS_VERSION] = Json::Value(1); 28 } 29 30 void SkJSONCanvas::finish() { 31 fRoot[SKJSONCANVAS_COMMANDS] = fCommands; 32 fOut.writeText(Json::FastWriter().write(fRoot).c_str()); 33 } 34 35 Json::Value SkJSONCanvas::makePoint(const SkPoint& point) { 36 Json::Value result(Json::arrayValue); 37 result.append(Json::Value(point.x())); 38 result.append(Json::Value(point.y())); 39 return result; 40 } 41 42 Json::Value SkJSONCanvas::makePoint(SkScalar x, SkScalar y) { 43 Json::Value result(Json::arrayValue); 44 result.append(Json::Value(x)); 45 result.append(Json::Value(y)); 46 return result; 47 } 48 49 Json::Value SkJSONCanvas::makeRect(const SkRect& rect) { 50 Json::Value result(Json::arrayValue); 51 result.append(Json::Value(rect.left())); 52 result.append(Json::Value(rect.top())); 53 result.append(Json::Value(rect.right())); 54 result.append(Json::Value(rect.bottom())); 55 return result; 56 } 57 58 Json::Value SkJSONCanvas::makeRRect(const SkRRect& rrect) { 59 Json::Value result(Json::arrayValue); 60 result.append(this->makeRect(rrect.rect())); 61 result.append(this->makePoint(rrect.radii(SkRRect::kUpperLeft_Corner))); 62 result.append(this->makePoint(rrect.radii(SkRRect::kUpperRight_Corner))); 63 result.append(this->makePoint(rrect.radii(SkRRect::kLowerRight_Corner))); 64 result.append(this->makePoint(rrect.radii(SkRRect::kLowerLeft_Corner))); 65 return result; 66 } 67 68 Json::Value SkJSONCanvas::makePath(const SkPath& path) { 69 Json::Value result(Json::objectValue); 70 switch (path.getFillType()) { 71 case SkPath::kWinding_FillType: 72 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_WINDING; 73 break; 74 case SkPath::kEvenOdd_FillType: 75 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_EVENODD; 76 break; 77 case SkPath::kInverseWinding_FillType: 78 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEWINDING; 79 break; 80 case SkPath::kInverseEvenOdd_FillType: 81 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEEVENODD; 82 break; 83 } 84 Json::Value verbs(Json::arrayValue); 85 SkPath::Iter iter(path, false); 86 SkPoint pts[4]; 87 SkPath::Verb verb; 88 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 89 switch (verb) { 90 case SkPath::kLine_Verb: { 91 Json::Value line(Json::objectValue); 92 line[SKJSONCANVAS_VERB_LINE] = this->makePoint(pts[1]); 93 verbs.append(line); 94 break; 95 } 96 case SkPath::kQuad_Verb: { 97 Json::Value quad(Json::objectValue); 98 Json::Value coords(Json::arrayValue); 99 coords.append(this->makePoint(pts[1])); 100 coords.append(this->makePoint(pts[2])); 101 quad[SKJSONCANVAS_VERB_QUAD] = coords; 102 verbs.append(quad); 103 break; 104 } 105 case SkPath::kCubic_Verb: { 106 Json::Value cubic(Json::objectValue); 107 Json::Value coords(Json::arrayValue); 108 coords.append(this->makePoint(pts[1])); 109 coords.append(this->makePoint(pts[2])); 110 coords.append(this->makePoint(pts[3])); 111 cubic[SKJSONCANVAS_VERB_CUBIC] = coords; 112 verbs.append(cubic); 113 break; 114 } 115 case SkPath::kConic_Verb: { 116 Json::Value conic(Json::objectValue); 117 Json::Value coords(Json::arrayValue); 118 coords.append(this->makePoint(pts[1])); 119 coords.append(this->makePoint(pts[2])); 120 coords.append(Json::Value(iter.conicWeight())); 121 conic[SKJSONCANVAS_VERB_CONIC] = coords; 122 verbs.append(conic); 123 break; 124 } 125 case SkPath::kMove_Verb: { 126 Json::Value move(Json::objectValue); 127 move[SKJSONCANVAS_VERB_MOVE] = this->makePoint(pts[0]); 128 verbs.append(move); 129 break; 130 } 131 case SkPath::kClose_Verb: 132 verbs.append(Json::Value(SKJSONCANVAS_VERB_CLOSE)); 133 break; 134 case SkPath::kDone_Verb: 135 break; 136 } 137 } 138 result[SKJSONCANVAS_ATTRIBUTE_VERBS] = verbs; 139 return result; 140 } 141 142 Json::Value SkJSONCanvas::makeRegion(const SkRegion& region) { 143 return Json::Value("<unimplemented>"); 144 } 145 146 static void store_scalar(Json::Value* target, const char* key, SkScalar value, 147 SkScalar defaultValue) { 148 if (value != defaultValue) { 149 (*target)[key] = Json::Value(value); 150 } 151 } 152 153 static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) { 154 if (value != defaultValue) { 155 (*target)[key] = Json::Value(value); 156 } 157 } 158 159 static void encode_data(const void* data, size_t count, Json::Value* target) { 160 // just use a brain-dead JSON array for now, switch to base64 or something else smarter down the 161 // road 162 for (size_t i = 0; i < count; i++) { 163 target->append(((const uint8_t*)data)[i]); 164 } 165 } 166 167 static void flatten(const SkFlattenable* flattenable, Json::Value* target, bool sendBinaries) { 168 if (sendBinaries) { 169 SkWriteBuffer buffer; 170 flattenable->flatten(buffer); 171 void* data = sk_malloc_throw(buffer.bytesWritten()); 172 buffer.writeToMemory(data); 173 Json::Value bytes; 174 encode_data(data, buffer.bytesWritten(), &bytes); 175 Json::Value jsonFlattenable; 176 jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName()); 177 jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes; 178 (*target) = jsonFlattenable; 179 free(data); 180 } 181 else { 182 (*target)[SKJSONCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(flattenable->getTypeName()); 183 } 184 } 185 186 static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target, 187 bool sendBinaries) { 188 if (sendBinaries) { 189 SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100); 190 if (encoded == nullptr) { 191 // PNG encode doesn't necessarily support all color formats, convert to a different 192 // format 193 size_t rowBytes = 4 * image.width(); 194 void* buffer = sk_malloc_throw(rowBytes * image.height()); 195 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(), 196 kN32_SkColorType, kPremul_SkAlphaType); 197 if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) { 198 SkDebugf("readPixels failed\n"); 199 return false; 200 } 201 SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes); 202 encoded = converted->encode(SkImageEncoder::kPNG_Type, 100); 203 if (encoded == nullptr) { 204 SkDebugf("image encode failed\n"); 205 return false; 206 } 207 free(converted); 208 free(buffer); 209 } 210 Json::Value bytes; 211 encode_data(encoded->data(), encoded->size(), &bytes); 212 (*target)[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes; 213 encoded->unref(); 214 } 215 else { 216 SkString description = SkStringPrintf("%dx%d pixel image", image.width(), image.height()); 217 (*target)[SKJSONCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(description.c_str()); 218 } 219 return true; 220 } 221 222 static const char* color_type_name(SkColorType colorType) { 223 switch (colorType) { 224 case kARGB_4444_SkColorType: 225 return SKJSONCANVAS_COLORTYPE_ARGB4444; 226 case kRGBA_8888_SkColorType: 227 return SKJSONCANVAS_COLORTYPE_RGBA8888; 228 case kBGRA_8888_SkColorType: 229 return SKJSONCANVAS_COLORTYPE_BGRA8888; 230 case kRGB_565_SkColorType: 231 return SKJSONCANVAS_COLORTYPE_565; 232 case kGray_8_SkColorType: 233 return SKJSONCANVAS_COLORTYPE_GRAY8; 234 case kIndex_8_SkColorType: 235 return SKJSONCANVAS_COLORTYPE_INDEX8; 236 case kAlpha_8_SkColorType: 237 return SKJSONCANVAS_COLORTYPE_ALPHA8; 238 default: 239 SkASSERT(false); 240 return SKJSONCANVAS_COLORTYPE_RGBA8888; 241 } 242 } 243 244 static const char* alpha_type_name(SkAlphaType alphaType) { 245 switch (alphaType) { 246 case kOpaque_SkAlphaType: 247 return SKJSONCANVAS_ALPHATYPE_OPAQUE; 248 case kPremul_SkAlphaType: 249 return SKJSONCANVAS_ALPHATYPE_PREMUL; 250 case kUnpremul_SkAlphaType: 251 return SKJSONCANVAS_ALPHATYPE_UNPREMUL; 252 default: 253 SkASSERT(false); 254 return SKJSONCANVAS_ALPHATYPE_OPAQUE; 255 } 256 } 257 258 static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target, 259 bool sendBinaries) { 260 bitmap.lockPixels(); 261 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap)); 262 bitmap.unlockPixels(); 263 (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType())); 264 (*target)[SKJSONCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType())); 265 bool success = flatten(*image, target, sendBinaries); 266 return success; 267 } 268 269 static void apply_paint_color(const SkPaint& paint, Json::Value* target) { 270 SkColor color = paint.getColor(); 271 if (color != SK_ColorBLACK) { 272 Json::Value colorValue(Json::arrayValue); 273 colorValue.append(Json::Value(SkColorGetA(color))); 274 colorValue.append(Json::Value(SkColorGetR(color))); 275 colorValue.append(Json::Value(SkColorGetG(color))); 276 colorValue.append(Json::Value(SkColorGetB(color))); 277 (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = colorValue;; 278 } 279 } 280 281 static void apply_paint_style(const SkPaint& paint, Json::Value* target) { 282 SkPaint::Style style = paint.getStyle(); 283 if (style != SkPaint::kFill_Style) { 284 switch (style) { 285 case SkPaint::kStroke_Style: { 286 Json::Value stroke(SKJSONCANVAS_STYLE_STROKE); 287 (*target)[SKJSONCANVAS_ATTRIBUTE_STYLE] = stroke; 288 break; 289 } 290 case SkPaint::kStrokeAndFill_Style: { 291 Json::Value strokeAndFill(SKJSONCANVAS_STYLE_STROKEANDFILL); 292 (*target)[SKJSONCANVAS_ATTRIBUTE_STYLE] = strokeAndFill; 293 break; 294 } 295 default: SkASSERT(false); 296 } 297 } 298 } 299 300 static void apply_paint_cap(const SkPaint& paint, Json::Value* target) { 301 SkPaint::Cap cap = paint.getStrokeCap(); 302 if (cap != SkPaint::kDefault_Cap) { 303 switch (cap) { 304 case SkPaint::kButt_Cap: { 305 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_BUTT); 306 break; 307 } 308 case SkPaint::kRound_Cap: { 309 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_ROUND); 310 break; 311 } 312 case SkPaint::kSquare_Cap: { 313 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_SQUARE); 314 break; 315 } 316 default: SkASSERT(false); 317 } 318 } 319 } 320 static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) { 321 SkMaskFilter* maskFilter = paint.getMaskFilter(); 322 if (maskFilter != nullptr) { 323 SkMaskFilter::BlurRec blurRec; 324 if (maskFilter->asABlur(&blurRec)) { 325 Json::Value blur(Json::objectValue); 326 blur[SKJSONCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma); 327 switch (blurRec.fStyle) { 328 case SkBlurStyle::kNormal_SkBlurStyle: 329 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_NORMAL); 330 break; 331 case SkBlurStyle::kSolid_SkBlurStyle: 332 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_SOLID); 333 break; 334 case SkBlurStyle::kOuter_SkBlurStyle: 335 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_OUTER); 336 break; 337 case SkBlurStyle::kInner_SkBlurStyle: 338 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_INNER); 339 break; 340 default: 341 SkASSERT(false); 342 } 343 switch (blurRec.fQuality) { 344 case SkBlurQuality::kLow_SkBlurQuality: 345 blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_LOW); 346 break; 347 case SkBlurQuality::kHigh_SkBlurQuality: 348 blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_HIGH); 349 break; 350 default: 351 SkASSERT(false); 352 } 353 (*target)[SKJSONCANVAS_ATTRIBUTE_BLUR] = blur; 354 } 355 else { 356 Json::Value jsonMaskFilter; 357 flatten(maskFilter, &jsonMaskFilter, sendBinaries); 358 (*target)[SKJSONCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter; 359 } 360 } 361 } 362 363 static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target, bool sendBinaries) { 364 SkPathEffect* pathEffect = paint.getPathEffect(); 365 if (pathEffect != nullptr) { 366 SkPathEffect::DashInfo dashInfo; 367 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo); 368 if (dashType == SkPathEffect::kDash_DashType) { 369 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar)); 370 pathEffect->asADash(&dashInfo); 371 Json::Value dashing(Json::objectValue); 372 Json::Value intervals(Json::arrayValue); 373 for (int32_t i = 0; i < dashInfo.fCount; i++) { 374 intervals.append(Json::Value(dashInfo.fIntervals[i])); 375 } 376 free(dashInfo.fIntervals); 377 dashing[SKJSONCANVAS_ATTRIBUTE_INTERVALS] = intervals; 378 dashing[SKJSONCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase; 379 (*target)[SKJSONCANVAS_ATTRIBUTE_DASHING] = dashing; 380 } 381 else { 382 Json::Value jsonPathEffect; 383 flatten(pathEffect, &jsonPathEffect, sendBinaries); 384 (*target)[SKJSONCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect; 385 } 386 } 387 } 388 389 static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) { 390 SkPaint::Align textAlign = paint.getTextAlign(); 391 if (textAlign != SkPaint::kLeft_Align) { 392 switch (textAlign) { 393 case SkPaint::kCenter_Align: { 394 (*target)[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_CENTER; 395 break; 396 } 397 case SkPaint::kRight_Align: { 398 (*target)[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_RIGHT; 399 break; 400 } 401 default: SkASSERT(false); 402 } 403 } 404 } 405 406 static void apply_paint_typeface(const SkPaint& paint, Json::Value* target, 407 bool sendBinaries) { 408 SkTypeface* typeface = paint.getTypeface(); 409 if (typeface != nullptr) { 410 if (sendBinaries) { 411 Json::Value jsonTypeface; 412 SkDynamicMemoryWStream buffer; 413 typeface->serialize(&buffer); 414 void* data = sk_malloc_throw(buffer.bytesWritten()); 415 buffer.copyTo(data); 416 Json::Value bytes; 417 encode_data(data, buffer.bytesWritten(), &bytes); 418 jsonTypeface[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes; 419 free(data); 420 (*target)[SKJSONCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface; 421 } 422 } 423 } 424 425 static void apply_paint_shader(const SkPaint& paint, Json::Value* target, bool sendBinaries) { 426 SkFlattenable* shader = paint.getShader(); 427 if (shader != nullptr) { 428 Json::Value jsonShader; 429 flatten(shader, &jsonShader, sendBinaries); 430 (*target)[SKJSONCANVAS_ATTRIBUTE_SHADER] = jsonShader; 431 } 432 } 433 434 static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, bool sendBinaries) { 435 SkFlattenable* xfermode = paint.getXfermode(); 436 if (xfermode != nullptr) { 437 Json::Value jsonXfermode; 438 flatten(xfermode, &jsonXfermode, sendBinaries); 439 (*target)[SKJSONCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode; 440 } 441 } 442 443 static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) { 444 SkFlattenable* imageFilter = paint.getImageFilter(); 445 if (imageFilter != nullptr) { 446 Json::Value jsonImageFilter; 447 flatten(imageFilter, &jsonImageFilter, sendBinaries); 448 (*target)[SKJSONCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter; 449 } 450 } 451 452 static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) { 453 SkFlattenable* colorFilter = paint.getColorFilter(); 454 if (colorFilter != nullptr) { 455 Json::Value jsonColorFilter; 456 flatten(colorFilter, &jsonColorFilter, sendBinaries); 457 (*target)[SKJSONCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter; 458 } 459 } 460 461 Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) { 462 Json::Value result(Json::objectValue); 463 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f); 464 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(), 465 SkPaintDefaults_MiterLimit); 466 store_bool(&result, SKJSONCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false); 467 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(), 468 SkPaintDefaults_TextSize); 469 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1); 470 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f); 471 apply_paint_color(paint, &result); 472 apply_paint_style(paint, &result); 473 apply_paint_cap(paint, &result); 474 apply_paint_textalign(paint, &result); 475 apply_paint_patheffect(paint, &result, fSendBinaries); 476 apply_paint_maskfilter(paint, &result, fSendBinaries); 477 apply_paint_shader(paint, &result, fSendBinaries); 478 apply_paint_xfermode(paint, &result, fSendBinaries); 479 apply_paint_imagefilter(paint, &result, fSendBinaries); 480 apply_paint_colorfilter(paint, &result, fSendBinaries); 481 apply_paint_typeface(paint, &result, fSendBinaries); 482 return result; 483 } 484 485 Json::Value SkJSONCanvas::MakeIRect(const SkIRect& rect) { 486 Json::Value result(Json::arrayValue); 487 result.append(Json::Value(rect.left())); 488 result.append(Json::Value(rect.top())); 489 result.append(Json::Value(rect.right())); 490 result.append(Json::Value(rect.bottom())); 491 return result; 492 } 493 494 Json::Value SkJSONCanvas::MakeMatrix(const SkMatrix& matrix) { 495 Json::Value result(Json::arrayValue); 496 Json::Value row1(Json::arrayValue); 497 row1.append(Json::Value(matrix[0])); 498 row1.append(Json::Value(matrix[1])); 499 row1.append(Json::Value(matrix[2])); 500 result.append(row1); 501 Json::Value row2(Json::arrayValue); 502 row2.append(Json::Value(matrix[3])); 503 row2.append(Json::Value(matrix[4])); 504 row2.append(Json::Value(matrix[5])); 505 result.append(row2); 506 Json::Value row3(Json::arrayValue); 507 row3.append(Json::Value(matrix[6])); 508 row3.append(Json::Value(matrix[7])); 509 row3.append(Json::Value(matrix[8])); 510 result.append(row3); 511 return result; 512 } 513 514 Json::Value SkJSONCanvas::makeRegionOp(SkRegion::Op op) { 515 switch (op) { 516 case SkRegion::kDifference_Op: 517 return Json::Value(SKJSONCANVAS_REGIONOP_DIFFERENCE); 518 case SkRegion::kIntersect_Op: 519 return Json::Value(SKJSONCANVAS_REGIONOP_INTERSECT); 520 case SkRegion::kUnion_Op: 521 return Json::Value(SKJSONCANVAS_REGIONOP_UNION); 522 case SkRegion::kXOR_Op: 523 return Json::Value(SKJSONCANVAS_REGIONOP_XOR); 524 case SkRegion::kReverseDifference_Op: 525 return Json::Value(SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE); 526 case SkRegion::kReplace_Op: 527 return Json::Value(SKJSONCANVAS_REGIONOP_REPLACE); 528 default: 529 SkASSERT(false); 530 return Json::Value("<invalid region op>"); 531 }; 532 } 533 534 Json::Value SkJSONCanvas::makePointMode(SkCanvas::PointMode mode) { 535 switch (mode) { 536 case SkCanvas::kPoints_PointMode: 537 return Json::Value(SKJSONCANVAS_POINTMODE_POINTS); 538 case SkCanvas::kLines_PointMode: 539 return Json::Value(SKJSONCANVAS_POINTMODE_LINES); 540 case SkCanvas::kPolygon_PointMode: 541 return Json::Value(SKJSONCANVAS_POINTMODE_POLYGON); 542 default: 543 SkASSERT(false); 544 return Json::Value("<invalid point mode>"); 545 }; 546 } 547 548 void SkJSONCanvas::didConcat(const SkMatrix& matrix) { 549 Json::Value command(Json::objectValue); 550 switch (matrix.getType()) { 551 case SkMatrix::kTranslate_Mask: 552 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TRANSLATE); 553 command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(matrix.get(SkMatrix::kMTransX)); 554 command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(matrix.get(SkMatrix::kMTransY)); 555 break; 556 case SkMatrix::kScale_Mask: 557 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SCALE); 558 command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(matrix.get(SkMatrix::kMScaleX)); 559 command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(matrix.get(SkMatrix::kMScaleY)); 560 break; 561 default: 562 this->didSetMatrix(this->getTotalMatrix()); 563 return; 564 } 565 fCommands.append(command); 566 } 567 568 void SkJSONCanvas::didSetMatrix(const SkMatrix& matrix) { 569 Json::Value command(Json::objectValue); 570 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_MATRIX); 571 command[SKJSONCANVAS_ATTRIBUTE_MATRIX] = this->MakeMatrix(matrix); 572 fCommands.append(command); 573 } 574 575 void SkJSONCanvas::onDrawPaint(const SkPaint& paint) { 576 Json::Value command(Json::objectValue); 577 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PAINT); 578 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 579 fCommands.append(command); 580 } 581 582 void SkJSONCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { 583 Json::Value command(Json::objectValue); 584 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RECT); 585 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect); 586 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 587 fCommands.append(command); 588 } 589 590 void SkJSONCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { 591 Json::Value command(Json::objectValue); 592 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_OVAL); 593 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect); 594 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 595 fCommands.append(command); 596 } 597 598 void SkJSONCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 599 Json::Value command(Json::objectValue); 600 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RRECT); 601 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect); 602 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 603 fCommands.append(command); 604 } 605 606 void SkJSONCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { 607 Json::Value command(Json::objectValue); 608 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RRECT); 609 command[SKJSONCANVAS_ATTRIBUTE_INNER] = this->makeRRect(inner); 610 command[SKJSONCANVAS_ATTRIBUTE_OUTER] = this->makeRRect(outer); 611 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 612 fCommands.append(command); 613 } 614 615 void SkJSONCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[], 616 const SkPaint& paint) { 617 Json::Value command(Json::objectValue); 618 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POINTS); 619 command[SKJSONCANVAS_ATTRIBUTE_MODE] = this->makePointMode(mode); 620 Json::Value points(Json::arrayValue); 621 for (size_t i = 0; i < count; i++) { 622 points.append(this->makePoint(pts[i])); 623 } 624 command[SKJSONCANVAS_ATTRIBUTE_POINTS] = points; 625 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 626 fCommands.append(command); 627 } 628 629 void SkJSONCanvas::onDrawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint vertices[], 630 const SkPoint texs[], const SkColor colors[], SkXfermode*, 631 const uint16_t indices[], int indexCount, const SkPaint&) { 632 SkDebugf("unsupported: drawVertices\n"); 633 Json::Value command(Json::objectValue); 634 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_VERTICES); 635 fCommands.append(command); 636 } 637 638 void SkJSONCanvas::onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], 639 int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) { 640 SkDebugf("unsupported: drawAtlas\n"); 641 Json::Value command(Json::objectValue); 642 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_ATLAS); 643 fCommands.append(command); 644 } 645 646 void SkJSONCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 647 Json::Value command(Json::objectValue); 648 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PATH); 649 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path); 650 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 651 fCommands.append(command); 652 } 653 654 void SkJSONCanvas::onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, 655 const SkPaint* paint) { 656 Json::Value encoded; 657 if (flatten(*image, &encoded, fSendBinaries)) { 658 Json::Value command(Json::objectValue); 659 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGE); 660 command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded; 661 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(dx, dy); 662 if (paint != nullptr) { 663 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint); 664 } 665 fCommands.append(command); 666 } 667 } 668 669 void SkJSONCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 670 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { 671 Json::Value encoded; 672 if (flatten(*image, &encoded, fSendBinaries)) { 673 Json::Value command(Json::objectValue); 674 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGERECT); 675 command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded; 676 if (src != nullptr) { 677 command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src); 678 } 679 command[SKJSONCANVAS_ATTRIBUTE_DST] = this->makeRect(dst); 680 if (paint != nullptr) { 681 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint); 682 } 683 if (constraint == SkCanvas::kStrict_SrcRectConstraint) { 684 command[SKJSONCANVAS_ATTRIBUTE_STRICT] = Json::Value(true); 685 } 686 fCommands.append(command); 687 } 688 } 689 690 void SkJSONCanvas::onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, 691 const SkPaint*) { 692 SkDebugf("unsupported: drawImageNine\n"); 693 Json::Value command(Json::objectValue); 694 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGENINE); 695 fCommands.append(command); 696 } 697 698 void SkJSONCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, 699 const SkPaint* paint) { 700 Json::Value encoded; 701 if (flatten(bitmap, &encoded, fSendBinaries)) { 702 Json::Value command(Json::objectValue); 703 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAP); 704 command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded; 705 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(dx, dy); 706 if (paint != nullptr) { 707 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint); 708 } 709 fCommands.append(command); 710 } 711 } 712 713 void SkJSONCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 714 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { 715 Json::Value encoded; 716 if (flatten(bitmap, &encoded, fSendBinaries)) { 717 Json::Value command(Json::objectValue); 718 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAPRECT); 719 command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded; 720 if (src != nullptr) { 721 command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src); 722 } 723 command[SKJSONCANVAS_ATTRIBUTE_DST] = this->makeRect(dst); 724 if (paint != nullptr) { 725 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint); 726 } 727 if (constraint == SkCanvas::kStrict_SrcRectConstraint) { 728 command[SKJSONCANVAS_ATTRIBUTE_STRICT] = Json::Value(true); 729 } 730 fCommands.append(command); 731 } 732 } 733 734 void SkJSONCanvas::onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, 735 const SkPaint*) { 736 SkDebugf("unsupported: drawBitmapNine\n"); 737 Json::Value command(Json::objectValue); 738 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAPNINE); 739 fCommands.append(command); 740 } 741 742 void SkJSONCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, 743 SkScalar y, const SkPaint& paint) { 744 Json::Value command(Json::objectValue); 745 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXT); 746 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text, 747 ((const char*) text) + byteLength); 748 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(x, y); 749 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 750 fCommands.append(command); 751 } 752 753 void SkJSONCanvas::onDrawPosText(const void* text, size_t byteLength, 754 const SkPoint pos[], const SkPaint& paint) { 755 Json::Value command(Json::objectValue); 756 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POSTEXT); 757 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text, 758 ((const char*) text) + byteLength); 759 Json::Value coords(Json::arrayValue); 760 for (size_t i = 0; i < byteLength; i++) { 761 coords.append(this->makePoint(pos[i])); 762 } 763 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = coords; 764 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 765 fCommands.append(command); 766 } 767 768 void SkJSONCanvas::onDrawPosTextH(const void* text, size_t byteLength, 769 const SkScalar xpos[], SkScalar constY, 770 const SkPaint& paint) { 771 SkDebugf("unsupported: drawPosTextH\n"); 772 Json::Value command(Json::objectValue); 773 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POSTEXTH); 774 fCommands.append(command); 775 } 776 777 void SkJSONCanvas::onDrawTextOnPath(const void* text, size_t byteLength, 778 const SkPath& path, const SkMatrix* matrix, 779 const SkPaint& paint) { 780 Json::Value command(Json::objectValue); 781 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXTONPATH); 782 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text, 783 ((const char*) text) + byteLength); 784 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path); 785 if (matrix != nullptr) { 786 command[SKJSONCANVAS_ATTRIBUTE_MATRIX] = this->MakeMatrix(*matrix); 787 } 788 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 789 fCommands.append(command); 790 } 791 792 void SkJSONCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 793 const SkPaint& paint) { 794 Json::Value command(Json::objectValue); 795 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXTBLOB); 796 Json::Value runs(Json::arrayValue); 797 SkTextBlobRunIterator iter(blob); 798 while (!iter.done()) { 799 Json::Value run(Json::objectValue); 800 Json::Value jsonPositions(Json::arrayValue); 801 Json::Value jsonGlyphs(Json::arrayValue); 802 const SkScalar* iterPositions = iter.pos(); 803 const uint16_t* iterGlyphs = iter.glyphs(); 804 for (uint32_t i = 0; i < iter.glyphCount(); i++) { 805 switch (iter.positioning()) { 806 case SkTextBlob::kFull_Positioning: 807 jsonPositions.append(this->makePoint(iterPositions[i * 2], 808 iterPositions[i * 2 + 1])); 809 break; 810 case SkTextBlob::kHorizontal_Positioning: 811 jsonPositions.append(Json::Value(iterPositions[i])); 812 break; 813 case SkTextBlob::kDefault_Positioning: 814 break; 815 } 816 jsonGlyphs.append(Json::Value(iterGlyphs[i])); 817 } 818 if (iter.positioning() != SkTextBlob::kDefault_Positioning) { 819 run[SKJSONCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions; 820 } 821 run[SKJSONCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs; 822 SkPaint fontPaint; 823 iter.applyFontToPaint(&fontPaint); 824 run[SKJSONCANVAS_ATTRIBUTE_FONT] = this->makePaint(fontPaint); 825 run[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(iter.offset()); 826 runs.append(run); 827 iter.next(); 828 } 829 command[SKJSONCANVAS_ATTRIBUTE_RUNS] = runs; 830 command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(x); 831 command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(y); 832 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); 833 fCommands.append(command); 834 } 835 836 void SkJSONCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 837 const SkPoint texCoords[4], SkXfermode* xmode, 838 const SkPaint& paint) { 839 SkDebugf("unsupported: drawPatch\n"); 840 Json::Value command(Json::objectValue); 841 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PATCH); 842 fCommands.append(command); 843 } 844 845 void SkJSONCanvas::onDrawDrawable(SkDrawable*, const SkMatrix*) { 846 SkDebugf("unsupported: drawDrawable\n"); 847 Json::Value command(Json::objectValue); 848 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_DRAWABLE); 849 fCommands.append(command); 850 } 851 852 void SkJSONCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 853 Json::Value command(Json::objectValue); 854 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRECT); 855 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect); 856 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); 857 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle); 858 fCommands.append(command); 859 } 860 861 void SkJSONCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 862 Json::Value command(Json::objectValue); 863 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRRECT); 864 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect); 865 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); 866 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle); 867 fCommands.append(command); 868 } 869 870 void SkJSONCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 871 Json::Value command(Json::objectValue); 872 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPPATH); 873 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path); 874 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); 875 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle); 876 fCommands.append(command); 877 } 878 879 void SkJSONCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { 880 Json::Value command(Json::objectValue); 881 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPREGION); 882 command[SKJSONCANVAS_ATTRIBUTE_REGION] = this->makeRegion(deviceRgn); 883 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); 884 fCommands.append(command); 885 } 886 887 void SkJSONCanvas::willSave() { 888 Json::Value command(Json::objectValue); 889 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVE); 890 fCommands.append(command); 891 } 892 893 void SkJSONCanvas::willRestore() { 894 Json::Value command(Json::objectValue); 895 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RESTORE); 896 fCommands.append(command); 897 } 898 899 SkCanvas::SaveLayerStrategy SkJSONCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { 900 Json::Value command(Json::objectValue); 901 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVELAYER); 902 if (rec.fBounds != nullptr) { 903 command[SKJSONCANVAS_ATTRIBUTE_BOUNDS] = this->makeRect(*rec.fBounds); 904 } 905 if (rec.fPaint != nullptr) { 906 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*rec.fPaint); 907 } 908 if (rec.fBackdrop != nullptr) { 909 Json::Value backdrop; 910 flatten(rec.fBackdrop, &backdrop, fSendBinaries); 911 command[SKJSONCANVAS_ATTRIBUTE_BACKDROP] = backdrop; 912 } 913 if (rec.fSaveLayerFlags != 0) { 914 SkDebugf("unsupported: saveLayer flags\n"); 915 } 916 fCommands.append(command); 917 return this->INHERITED::getSaveLayerStrategy(rec); 918 } 919