1 2 /* 3 * Copyright 2012 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkDrawCommand.h" 11 12 #include "SkBlurMaskFilter.h" 13 #include "SkColorFilter.h" 14 #include "SkDashPathEffect.h" 15 #include "SkImageFilter.h" 16 #include "SkMaskFilter.h" 17 #include "SkObjectParser.h" 18 #include "SkPaintDefaults.h" 19 #include "SkPathEffect.h" 20 #include "SkPicture.h" 21 #include "SkTextBlob.h" 22 #include "SkTextBlobRunIterator.h" 23 #include "SkTHash.h" 24 #include "SkTypeface.h" 25 #include "SkValidatingReadBuffer.h" 26 #include "SkWriteBuffer.h" 27 28 #if SK_SUPPORT_GPU 29 #include "GrContext.h" 30 #include "GrRenderTarget.h" 31 #endif 32 33 #define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command" 34 #define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible" 35 #define SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL "auditTrail" 36 #define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix" 37 #define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords" 38 #define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds" 39 #define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint" 40 #define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer" 41 #define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner" 42 #define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode" 43 #define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points" 44 #define SKDEBUGCANVAS_ATTRIBUTE_PATH "path" 45 #define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text" 46 #define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color" 47 #define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha" 48 #define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style" 49 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth" 50 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter" 51 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin" 52 #define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap" 53 #define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias" 54 #define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither" 55 #define SKDEBUGCANVAS_ATTRIBUTE_REGION "region" 56 #define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op" 57 #define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle" 58 #define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion" 59 #define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur" 60 #define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma" 61 #define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality" 62 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign" 63 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize" 64 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX" 65 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX" 66 #define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing" 67 #define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals" 68 #define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase" 69 #define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType" 70 #define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs" 71 #define SKDEBUGCANVAS_ATTRIBUTE_NAME "name" 72 #define SKDEBUGCANVAS_ATTRIBUTE_DATA "data" 73 #define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader" 74 #define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect" 75 #define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter" 76 #define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode" 77 #define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper" 78 #define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop" 79 #define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter" 80 #define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter" 81 #define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image" 82 #define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap" 83 #define SKDEBUGCANVAS_ATTRIBUTE_SRC "src" 84 #define SKDEBUGCANVAS_ATTRIBUTE_DST "dst" 85 #define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center" 86 #define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict" 87 #define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description" 88 #define SKDEBUGCANVAS_ATTRIBUTE_X "x" 89 #define SKDEBUGCANVAS_ATTRIBUTE_Y "y" 90 #define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs" 91 #define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions" 92 #define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs" 93 #define SKDEBUGCANVAS_ATTRIBUTE_FONT "font" 94 #define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface" 95 #define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics" 96 #define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors" 97 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords" 98 #define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality" 99 100 #define SKDEBUGCANVAS_VERB_MOVE "move" 101 #define SKDEBUGCANVAS_VERB_LINE "line" 102 #define SKDEBUGCANVAS_VERB_QUAD "quad" 103 #define SKDEBUGCANVAS_VERB_CUBIC "cubic" 104 #define SKDEBUGCANVAS_VERB_CONIC "conic" 105 #define SKDEBUGCANVAS_VERB_CLOSE "close" 106 107 #define SKDEBUGCANVAS_STYLE_FILL "fill" 108 #define SKDEBUGCANVAS_STYLE_STROKE "stroke" 109 #define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill" 110 111 #define SKDEBUGCANVAS_POINTMODE_POINTS "points" 112 #define SKDEBUGCANVAS_POINTMODE_LINES "lines" 113 #define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon" 114 115 #define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference" 116 #define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect" 117 #define SKDEBUGCANVAS_REGIONOP_UNION "union" 118 #define SKDEBUGCANVAS_REGIONOP_XOR "xor" 119 #define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference" 120 #define SKDEBUGCANVAS_REGIONOP_REPLACE "replace" 121 122 #define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal" 123 #define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid" 124 #define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer" 125 #define SKDEBUGCANVAS_BLURSTYLE_INNER "inner" 126 127 #define SKDEBUGCANVAS_BLURQUALITY_LOW "low" 128 #define SKDEBUGCANVAS_BLURQUALITY_HIGH "high" 129 130 #define SKDEBUGCANVAS_ALIGN_LEFT "left" 131 #define SKDEBUGCANVAS_ALIGN_CENTER "center" 132 #define SKDEBUGCANVAS_ALIGN_RIGHT "right" 133 134 #define SKDEBUGCANVAS_FILLTYPE_WINDING "winding" 135 #define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd" 136 #define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding" 137 #define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd" 138 139 #define SKDEBUGCANVAS_CAP_BUTT "butt" 140 #define SKDEBUGCANVAS_CAP_ROUND "round" 141 #define SKDEBUGCANVAS_CAP_SQUARE "square" 142 143 #define SKDEBUGCANVAS_MITER_JOIN "miter" 144 #define SKDEBUGCANVAS_ROUND_JOIN "round" 145 #define SKDEBUGCANVAS_BEVEL_JOIN "bevel" 146 147 #define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444" 148 #define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888" 149 #define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888" 150 #define SKDEBUGCANVAS_COLORTYPE_565 "565" 151 #define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8" 152 #define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8" 153 #define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8" 154 155 #define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque" 156 #define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul" 157 #define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul" 158 159 #define SKDEBUGCANVAS_FILTERQUALITY_NONE "none" 160 #define SKDEBUGCANVAS_FILTERQUALITY_LOW "low" 161 #define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium" 162 #define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high" 163 164 typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&); 165 166 // TODO(chudy): Refactor into non subclass model. 167 168 SkDrawCommand::SkDrawCommand(OpType type) 169 : fOpType(type) 170 , fVisible(true) { 171 } 172 173 SkDrawCommand::~SkDrawCommand() { 174 fInfo.deleteAll(); 175 } 176 177 const char* SkDrawCommand::GetCommandString(OpType type) { 178 switch (type) { 179 case kBeginDrawPicture_OpType: return "BeginDrawPicture"; 180 case kClipPath_OpType: return "ClipPath"; 181 case kClipRegion_OpType: return "ClipRegion"; 182 case kClipRect_OpType: return "ClipRect"; 183 case kClipRRect_OpType: return "ClipRRect"; 184 case kConcat_OpType: return "Concat"; 185 case kDrawBitmap_OpType: return "DrawBitmap"; 186 case kDrawBitmapNine_OpType: return "DrawBitmapNine"; 187 case kDrawBitmapRect_OpType: return "DrawBitmapRect"; 188 case kDrawClear_OpType: return "DrawClear"; 189 case kDrawDRRect_OpType: return "DrawDRRect"; 190 case kDrawImage_OpType: return "DrawImage"; 191 case kDrawImageRect_OpType: return "DrawImageRect"; 192 case kDrawOval_OpType: return "DrawOval"; 193 case kDrawPaint_OpType: return "DrawPaint"; 194 case kDrawPatch_OpType: return "DrawPatch"; 195 case kDrawPath_OpType: return "DrawPath"; 196 case kDrawPoints_OpType: return "DrawPoints"; 197 case kDrawPosText_OpType: return "DrawPosText"; 198 case kDrawPosTextH_OpType: return "DrawPosTextH"; 199 case kDrawRect_OpType: return "DrawRect"; 200 case kDrawRRect_OpType: return "DrawRRect"; 201 case kDrawText_OpType: return "DrawText"; 202 case kDrawTextBlob_OpType: return "DrawTextBlob"; 203 case kDrawTextOnPath_OpType: return "DrawTextOnPath"; 204 case kDrawVertices_OpType: return "DrawVertices"; 205 case kEndDrawPicture_OpType: return "EndDrawPicture"; 206 case kRestore_OpType: return "Restore"; 207 case kSave_OpType: return "Save"; 208 case kSaveLayer_OpType: return "SaveLayer"; 209 case kSetMatrix_OpType: return "SetMatrix"; 210 default: 211 SkDebugf("OpType error 0x%08x\n", type); 212 SkASSERT(0); 213 break; 214 } 215 SkDEBUGFAIL("DrawType UNUSED\n"); 216 return nullptr; 217 } 218 219 SkString SkDrawCommand::toString() const { 220 return SkString(GetCommandString(fOpType)); 221 } 222 223 Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const { 224 Json::Value result; 225 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType); 226 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible()); 227 return result; 228 } 229 230 Json::Value SkDrawCommand::drawToAndCollectJSON(SkCanvas* canvas, 231 UrlDataManager& urlDataManager) const { 232 Json::Value result = this->toJSON(urlDataManager); 233 234 SkASSERT(canvas); 235 236 #if SK_SUPPORT_GPU 237 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); 238 if (rt) { 239 GrContext* ctx = rt->getContext(); 240 if(ctx) { 241 GrAuditTrail* at = ctx->getAuditTrail(); 242 GrAuditTrail::AutoEnable enable(at); 243 this->execute(canvas); 244 245 // TODO if this is inefficient we could add a method to GrAuditTrail which takes 246 // a Json::Value and is only compiled in this file 247 Json::Value parsedFromString; 248 Json::Reader reader; 249 SkDEBUGCODE(bool parsingSuccessful = )reader.parse(at->toJson().c_str(), 250 parsedFromString); 251 SkASSERT(parsingSuccessful); 252 253 result[SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL] = parsedFromString; 254 at->reset(); 255 } 256 } 257 #endif 258 return result; 259 } 260 261 #define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \ 262 (FROM_JSON) Sk ## name ## Command::fromJSON) 263 SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) { 264 static SkTHashMap<SkString, FROM_JSON> factories; 265 static bool initialized = false; 266 if (!initialized) { 267 initialized = true; 268 INSTALL_FACTORY(Restore); 269 INSTALL_FACTORY(ClipPath); 270 INSTALL_FACTORY(ClipRegion); 271 INSTALL_FACTORY(ClipRect); 272 INSTALL_FACTORY(ClipRRect); 273 INSTALL_FACTORY(Concat); 274 INSTALL_FACTORY(DrawBitmap); 275 INSTALL_FACTORY(DrawBitmapRect); 276 INSTALL_FACTORY(DrawBitmapNine); 277 INSTALL_FACTORY(DrawImage); 278 INSTALL_FACTORY(DrawImageRect); 279 INSTALL_FACTORY(DrawOval); 280 INSTALL_FACTORY(DrawPaint); 281 INSTALL_FACTORY(DrawPath); 282 INSTALL_FACTORY(DrawPoints); 283 INSTALL_FACTORY(DrawText); 284 INSTALL_FACTORY(DrawPosText); 285 INSTALL_FACTORY(DrawTextOnPath); 286 INSTALL_FACTORY(DrawTextBlob); 287 288 INSTALL_FACTORY(DrawRect); 289 INSTALL_FACTORY(DrawRRect); 290 INSTALL_FACTORY(DrawDRRect); 291 INSTALL_FACTORY(DrawPatch); 292 INSTALL_FACTORY(Save); 293 INSTALL_FACTORY(SaveLayer); 294 INSTALL_FACTORY(SetMatrix); 295 } 296 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString()); 297 FROM_JSON* factory = factories.find(name); 298 if (factory == nullptr) { 299 SkDebugf("no JSON factory for '%s'\n", name.c_str()); 300 return nullptr; 301 } 302 return (*factory)(command, urlDataManager); 303 } 304 305 namespace { 306 307 void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) { 308 const SkISize& size = canvas->getDeviceSize(); 309 310 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object 311 312 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f); 313 if (bounds.width() > bounds.height()) { 314 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()), 315 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width())); 316 } else { 317 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()), 318 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height())); 319 } 320 canvas->translate(-bounds.centerX(), -bounds.centerY()); 321 } 322 323 324 void render_path(SkCanvas* canvas, const SkPath& path) { 325 canvas->clear(0xFFFFFFFF); 326 327 const SkRect& bounds = path.getBounds(); 328 if (bounds.isEmpty()) { 329 return; 330 } 331 332 SkAutoCanvasRestore acr(canvas, true); 333 xlate_and_scale_to_bounds(canvas, bounds); 334 335 SkPaint p; 336 p.setColor(SK_ColorBLACK); 337 p.setStyle(SkPaint::kStroke_Style); 338 339 canvas->drawPath(path, p); 340 } 341 342 void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) { 343 const SkISize& size = canvas->getDeviceSize(); 344 345 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width(); 346 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height(); 347 348 if (input.width() > input.height()) { 349 yScale *= input.height() / (float) input.width(); 350 } else { 351 xScale *= input.width() / (float) input.height(); 352 } 353 354 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1, 355 xScale * input.width(), 356 yScale * input.height()); 357 358 static const int kNumBlocks = 8; 359 360 canvas->clear(0xFFFFFFFF); 361 SkISize block = { 362 canvas->imageInfo().width()/kNumBlocks, 363 canvas->imageInfo().height()/kNumBlocks 364 }; 365 for (int y = 0; y < kNumBlocks; ++y) { 366 for (int x = 0; x < kNumBlocks; ++x) { 367 SkPaint paint; 368 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY); 369 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()), 370 SkIntToScalar(y*block.height()), 371 SkIntToScalar(block.width()), 372 SkIntToScalar(block.height())); 373 canvas->drawRect(r, paint); 374 } 375 } 376 377 canvas->drawBitmapRect(input, dst, nullptr); 378 379 if (srcRect) { 380 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1, 381 srcRect->fTop * yScale + SK_Scalar1, 382 srcRect->fRight * xScale + SK_Scalar1, 383 srcRect->fBottom * yScale + SK_Scalar1); 384 SkPaint p; 385 p.setColor(SK_ColorRED); 386 p.setStyle(SkPaint::kStroke_Style); 387 388 canvas->drawRect(r, p); 389 } 390 } 391 392 void render_rrect(SkCanvas* canvas, const SkRRect& rrect) { 393 canvas->clear(0xFFFFFFFF); 394 canvas->save(); 395 396 const SkRect& bounds = rrect.getBounds(); 397 398 xlate_and_scale_to_bounds(canvas, bounds); 399 400 SkPaint p; 401 p.setColor(SK_ColorBLACK); 402 p.setStyle(SkPaint::kStroke_Style); 403 404 canvas->drawRRect(rrect, p); 405 canvas->restore(); 406 } 407 408 void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) { 409 canvas->clear(0xFFFFFFFF); 410 canvas->save(); 411 412 const SkRect& bounds = outer.getBounds(); 413 414 xlate_and_scale_to_bounds(canvas, bounds); 415 416 SkPaint p; 417 p.setColor(SK_ColorBLACK); 418 p.setStyle(SkPaint::kStroke_Style); 419 420 canvas->drawDRRect(outer, inner, p); 421 canvas->restore(); 422 } 423 424 }; 425 426 static Json::Value make_json_color(const SkColor color) { 427 Json::Value result(Json::arrayValue); 428 result.append(Json::Value(SkColorGetA(color))); 429 result.append(Json::Value(SkColorGetR(color))); 430 result.append(Json::Value(SkColorGetG(color))); 431 result.append(Json::Value(SkColorGetB(color))); 432 return result; 433 } 434 435 436 static Json::Value make_json_point(const SkPoint& point) { 437 Json::Value result(Json::arrayValue); 438 result.append(Json::Value(point.x())); 439 result.append(Json::Value(point.y())); 440 return result; 441 } 442 443 static Json::Value make_json_point(SkScalar x, SkScalar y) { 444 Json::Value result(Json::arrayValue); 445 result.append(Json::Value(x)); 446 result.append(Json::Value(y)); 447 return result; 448 } 449 450 static Json::Value make_json_rect(const SkRect& rect) { 451 Json::Value result(Json::arrayValue); 452 result.append(Json::Value(rect.left())); 453 result.append(Json::Value(rect.top())); 454 result.append(Json::Value(rect.right())); 455 result.append(Json::Value(rect.bottom())); 456 return result; 457 } 458 459 static Json::Value make_json_irect(const SkIRect& rect) { 460 Json::Value result(Json::arrayValue); 461 result.append(Json::Value(rect.left())); 462 result.append(Json::Value(rect.top())); 463 result.append(Json::Value(rect.right())); 464 result.append(Json::Value(rect.bottom())); 465 return result; 466 } 467 468 static Json::Value make_json_rrect(const SkRRect& rrect) { 469 Json::Value result(Json::arrayValue); 470 result.append(make_json_rect(rrect.rect())); 471 result.append(make_json_point(rrect.radii(SkRRect::kUpperLeft_Corner))); 472 result.append(make_json_point(rrect.radii(SkRRect::kUpperRight_Corner))); 473 result.append(make_json_point(rrect.radii(SkRRect::kLowerRight_Corner))); 474 result.append(make_json_point(rrect.radii(SkRRect::kLowerLeft_Corner))); 475 return result; 476 } 477 478 static Json::Value make_json_matrix(const SkMatrix& matrix) { 479 Json::Value result(Json::arrayValue); 480 Json::Value row1(Json::arrayValue); 481 row1.append(Json::Value(matrix[0])); 482 row1.append(Json::Value(matrix[1])); 483 row1.append(Json::Value(matrix[2])); 484 result.append(row1); 485 Json::Value row2(Json::arrayValue); 486 row2.append(Json::Value(matrix[3])); 487 row2.append(Json::Value(matrix[4])); 488 row2.append(Json::Value(matrix[5])); 489 result.append(row2); 490 Json::Value row3(Json::arrayValue); 491 row3.append(Json::Value(matrix[6])); 492 row3.append(Json::Value(matrix[7])); 493 row3.append(Json::Value(matrix[8])); 494 result.append(row3); 495 return result; 496 } 497 498 static Json::Value make_json_path(const SkPath& path) { 499 Json::Value result(Json::objectValue); 500 switch (path.getFillType()) { 501 case SkPath::kWinding_FillType: 502 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING; 503 break; 504 case SkPath::kEvenOdd_FillType: 505 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD; 506 break; 507 case SkPath::kInverseWinding_FillType: 508 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING; 509 break; 510 case SkPath::kInverseEvenOdd_FillType: 511 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD; 512 break; 513 } 514 Json::Value verbs(Json::arrayValue); 515 SkPath::Iter iter(path, false); 516 SkPoint pts[4]; 517 SkPath::Verb verb; 518 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 519 switch (verb) { 520 case SkPath::kLine_Verb: { 521 Json::Value line(Json::objectValue); 522 line[SKDEBUGCANVAS_VERB_LINE] = make_json_point(pts[1]); 523 verbs.append(line); 524 break; 525 } 526 case SkPath::kQuad_Verb: { 527 Json::Value quad(Json::objectValue); 528 Json::Value coords(Json::arrayValue); 529 coords.append(make_json_point(pts[1])); 530 coords.append(make_json_point(pts[2])); 531 quad[SKDEBUGCANVAS_VERB_QUAD] = coords; 532 verbs.append(quad); 533 break; 534 } 535 case SkPath::kCubic_Verb: { 536 Json::Value cubic(Json::objectValue); 537 Json::Value coords(Json::arrayValue); 538 coords.append(make_json_point(pts[1])); 539 coords.append(make_json_point(pts[2])); 540 coords.append(make_json_point(pts[3])); 541 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords; 542 verbs.append(cubic); 543 break; 544 } 545 case SkPath::kConic_Verb: { 546 Json::Value conic(Json::objectValue); 547 Json::Value coords(Json::arrayValue); 548 coords.append(make_json_point(pts[1])); 549 coords.append(make_json_point(pts[2])); 550 coords.append(Json::Value(iter.conicWeight())); 551 conic[SKDEBUGCANVAS_VERB_CONIC] = coords; 552 verbs.append(conic); 553 break; 554 } 555 case SkPath::kMove_Verb: { 556 Json::Value move(Json::objectValue); 557 move[SKDEBUGCANVAS_VERB_MOVE] = make_json_point(pts[0]); 558 verbs.append(move); 559 break; 560 } 561 case SkPath::kClose_Verb: 562 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE)); 563 break; 564 case SkPath::kDone_Verb: 565 break; 566 } 567 } 568 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs; 569 return result; 570 } 571 572 static Json::Value make_json_region(const SkRegion& region) { 573 return Json::Value("<unimplemented>"); 574 } 575 576 static Json::Value make_json_regionop(SkRegion::Op op) { 577 switch (op) { 578 case SkRegion::kDifference_Op: 579 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE); 580 case SkRegion::kIntersect_Op: 581 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT); 582 case SkRegion::kUnion_Op: 583 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION); 584 case SkRegion::kXOR_Op: 585 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR); 586 case SkRegion::kReverseDifference_Op: 587 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE); 588 case SkRegion::kReplace_Op: 589 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE); 590 default: 591 SkASSERT(false); 592 return Json::Value("<invalid region op>"); 593 }; 594 } 595 596 static Json::Value make_json_pointmode(SkCanvas::PointMode mode) { 597 switch (mode) { 598 case SkCanvas::kPoints_PointMode: 599 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS); 600 case SkCanvas::kLines_PointMode: 601 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES); 602 case SkCanvas::kPolygon_PointMode: 603 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON); 604 default: 605 SkASSERT(false); 606 return Json::Value("<invalid point mode>"); 607 }; 608 } 609 610 static void store_scalar(Json::Value* target, const char* key, SkScalar value, 611 SkScalar defaultValue) { 612 if (value != defaultValue) { 613 (*target)[key] = Json::Value(value); 614 } 615 } 616 617 static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) { 618 if (value != defaultValue) { 619 (*target)[key] = Json::Value(value); 620 } 621 } 622 623 static void encode_data(const void* bytes, size_t count, const char* contentType, 624 UrlDataManager& urlDataManager, Json::Value* target) { 625 SkAutoTUnref<SkData> data(SkData::NewWithCopy(bytes, count)); 626 SkString url = urlDataManager.addData(data, contentType); 627 *target = Json::Value(url.c_str()); 628 } 629 630 static void flatten(const SkFlattenable* flattenable, Json::Value* target, 631 UrlDataManager& urlDataManager) { 632 SkWriteBuffer buffer; 633 flattenable->flatten(buffer); 634 void* data = sk_malloc_throw(buffer.bytesWritten()); 635 buffer.writeToMemory(data); 636 Json::Value jsonData; 637 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData); 638 Json::Value jsonFlattenable; 639 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName()); 640 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData; 641 (*target) = jsonFlattenable; 642 sk_free(data); 643 } 644 645 static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target, 646 UrlDataManager& urlDataManager) { 647 SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100); 648 if (encoded == nullptr) { 649 // PNG encode doesn't necessarily support all color formats, convert to a different 650 // format 651 size_t rowBytes = 4 * image.width(); 652 void* buffer = sk_malloc_throw(rowBytes * image.height()); 653 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(), 654 kN32_SkColorType, kPremul_SkAlphaType); 655 if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) { 656 SkDebugf("readPixels failed\n"); 657 return false; 658 } 659 SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes); 660 encoded = converted->encode(SkImageEncoder::kPNG_Type, 100); 661 if (encoded == nullptr) { 662 SkDebugf("image encode failed\n"); 663 return false; 664 } 665 sk_free(converted); 666 sk_free(buffer); 667 } 668 Json::Value jsonData; 669 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData); 670 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData; 671 encoded->unref(); 672 return true; 673 } 674 675 static const char* color_type_name(SkColorType colorType) { 676 switch (colorType) { 677 case kARGB_4444_SkColorType: 678 return SKDEBUGCANVAS_COLORTYPE_ARGB4444; 679 case kRGBA_8888_SkColorType: 680 return SKDEBUGCANVAS_COLORTYPE_RGBA8888; 681 case kBGRA_8888_SkColorType: 682 return SKDEBUGCANVAS_COLORTYPE_BGRA8888; 683 case kRGB_565_SkColorType: 684 return SKDEBUGCANVAS_COLORTYPE_565; 685 case kGray_8_SkColorType: 686 return SKDEBUGCANVAS_COLORTYPE_GRAY8; 687 case kIndex_8_SkColorType: 688 return SKDEBUGCANVAS_COLORTYPE_INDEX8; 689 case kAlpha_8_SkColorType: 690 return SKDEBUGCANVAS_COLORTYPE_ALPHA8; 691 default: 692 SkASSERT(false); 693 return SKDEBUGCANVAS_COLORTYPE_RGBA8888; 694 } 695 } 696 697 static const char* alpha_type_name(SkAlphaType alphaType) { 698 switch (alphaType) { 699 case kOpaque_SkAlphaType: 700 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE; 701 case kPremul_SkAlphaType: 702 return SKDEBUGCANVAS_ALPHATYPE_PREMUL; 703 case kUnpremul_SkAlphaType: 704 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL; 705 default: 706 SkASSERT(false); 707 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE; 708 } 709 } 710 711 static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager, 712 const void** target) { 713 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString())); 714 if (urlData == nullptr) { 715 SkASSERT(false); 716 *target = nullptr; 717 return 0; 718 } 719 *target = urlData->fData->data(); 720 // cast should be safe for any reasonably-sized object... 721 return (Json::ArrayIndex) urlData->fData->size(); 722 } 723 724 static SkFlattenable* load_flattenable(Json::Value jsonFlattenable, 725 UrlDataManager& urlDataManager) { 726 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) { 727 return nullptr; 728 } 729 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString(); 730 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name); 731 if (factory == nullptr) { 732 SkDebugf("no factory for loading '%s'\n", name); 733 return nullptr; 734 } 735 const void* data; 736 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data); 737 SkValidatingReadBuffer buffer(data, size); 738 SkFlattenable* result = factory(buffer); 739 if (!buffer.isValid()) { 740 SkDebugf("invalid buffer loading flattenable\n"); 741 return nullptr; 742 } 743 return result; 744 } 745 746 static SkColorType colortype_from_name(const char* name) { 747 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) { 748 return kARGB_4444_SkColorType; 749 } 750 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) { 751 return kRGBA_8888_SkColorType; 752 } 753 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) { 754 return kBGRA_8888_SkColorType; 755 } 756 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) { 757 return kRGB_565_SkColorType; 758 } 759 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) { 760 return kGray_8_SkColorType; 761 } 762 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_INDEX8)) { 763 return kIndex_8_SkColorType; 764 } 765 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) { 766 return kAlpha_8_SkColorType; 767 } 768 SkASSERT(false); 769 return kN32_SkColorType; 770 } 771 772 static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) { 773 if (bitmap->colorType() == colorType ) { 774 return bitmap; 775 } 776 SkBitmap* dst = new SkBitmap(); 777 if (bitmap->copyTo(dst, colorType)) { 778 delete bitmap; 779 return dst; 780 } 781 SkASSERT(false); 782 delete dst; 783 return bitmap; 784 } 785 786 // caller is responsible for freeing return value 787 static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) { 788 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) { 789 SkDebugf("invalid bitmap\n"); 790 return nullptr; 791 } 792 const void* data; 793 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data); 794 SkMemoryStream stream(data, size); 795 SkImageDecoder* decoder = SkImageDecoder::Factory(&stream); 796 SkBitmap* bitmap = new SkBitmap(); 797 SkImageDecoder::Result result = decoder->decode(&stream, bitmap, 798 SkImageDecoder::kDecodePixels_Mode); 799 sk_free(decoder); 800 if (result != SkImageDecoder::kFailure) { 801 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) { 802 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString(); 803 SkColorType ct = colortype_from_name(ctName); 804 if (ct != kIndex_8_SkColorType) { 805 bitmap = convert_colortype(bitmap, ct); 806 } 807 } 808 return bitmap; 809 } 810 SkDebugf("image decode failed\n"); 811 return nullptr; 812 } 813 814 static SkImage* load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) { 815 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager); 816 if (bitmap == nullptr) { 817 return nullptr; 818 } 819 SkImage* result = SkImage::NewFromBitmap(*bitmap); 820 delete bitmap; 821 return result; 822 } 823 824 static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target, 825 UrlDataManager& urlDataManager) { 826 bitmap.lockPixels(); 827 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap)); 828 bitmap.unlockPixels(); 829 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType())); 830 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType())); 831 bool success = flatten(*image, target, urlDataManager); 832 return success; 833 } 834 835 static void apply_paint_color(const SkPaint& paint, Json::Value* target) { 836 SkColor color = paint.getColor(); 837 if (color != SK_ColorBLACK) { 838 Json::Value colorValue(Json::arrayValue); 839 colorValue.append(Json::Value(SkColorGetA(color))); 840 colorValue.append(Json::Value(SkColorGetR(color))); 841 colorValue.append(Json::Value(SkColorGetG(color))); 842 colorValue.append(Json::Value(SkColorGetB(color))); 843 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;; 844 } 845 } 846 847 static void apply_paint_style(const SkPaint& paint, Json::Value* target) { 848 SkPaint::Style style = paint.getStyle(); 849 if (style != SkPaint::kFill_Style) { 850 switch (style) { 851 case SkPaint::kStroke_Style: { 852 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE); 853 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke; 854 break; 855 } 856 case SkPaint::kStrokeAndFill_Style: { 857 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL); 858 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill; 859 break; 860 } 861 default: SkASSERT(false); 862 } 863 } 864 } 865 866 static void apply_paint_cap(const SkPaint& paint, Json::Value* target) { 867 SkPaint::Cap cap = paint.getStrokeCap(); 868 if (cap != SkPaint::kDefault_Cap) { 869 switch (cap) { 870 case SkPaint::kButt_Cap: 871 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT); 872 break; 873 case SkPaint::kRound_Cap: 874 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND); 875 break; 876 case SkPaint::kSquare_Cap: 877 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE); 878 break; 879 default: SkASSERT(false); 880 } 881 } 882 } 883 884 static void apply_paint_join(const SkPaint& paint, Json::Value* target) { 885 SkPaint::Join join = paint.getStrokeJoin(); 886 if (join != SkPaint::kDefault_Join) { 887 switch (join) { 888 case SkPaint::kMiter_Join: 889 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value( 890 SKDEBUGCANVAS_MITER_JOIN); 891 break; 892 case SkPaint::kRound_Join: 893 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value( 894 SKDEBUGCANVAS_ROUND_JOIN); 895 break; 896 case SkPaint::kBevel_Join: 897 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value( 898 SKDEBUGCANVAS_BEVEL_JOIN); 899 break; 900 default: SkASSERT(false); 901 } 902 } 903 } 904 905 static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) { 906 SkFilterQuality quality = paint.getFilterQuality(); 907 switch (quality) { 908 case kNone_SkFilterQuality: 909 break; 910 case kLow_SkFilterQuality: 911 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value( 912 SKDEBUGCANVAS_FILTERQUALITY_LOW); 913 break; 914 case kMedium_SkFilterQuality: 915 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value( 916 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM); 917 break; 918 case kHigh_SkFilterQuality: 919 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value( 920 SKDEBUGCANVAS_FILTERQUALITY_HIGH); 921 break; 922 } 923 } 924 925 static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target, 926 UrlDataManager& urlDataManager) { 927 SkMaskFilter* maskFilter = paint.getMaskFilter(); 928 if (maskFilter != nullptr) { 929 SkMaskFilter::BlurRec blurRec; 930 if (maskFilter->asABlur(&blurRec)) { 931 Json::Value blur(Json::objectValue); 932 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma); 933 switch (blurRec.fStyle) { 934 case SkBlurStyle::kNormal_SkBlurStyle: 935 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value( 936 SKDEBUGCANVAS_BLURSTYLE_NORMAL); 937 break; 938 case SkBlurStyle::kSolid_SkBlurStyle: 939 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value( 940 SKDEBUGCANVAS_BLURSTYLE_SOLID); 941 break; 942 case SkBlurStyle::kOuter_SkBlurStyle: 943 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value( 944 SKDEBUGCANVAS_BLURSTYLE_OUTER); 945 break; 946 case SkBlurStyle::kInner_SkBlurStyle: 947 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value( 948 SKDEBUGCANVAS_BLURSTYLE_INNER); 949 break; 950 default: 951 SkASSERT(false); 952 } 953 switch (blurRec.fQuality) { 954 case SkBlurQuality::kLow_SkBlurQuality: 955 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value( 956 SKDEBUGCANVAS_BLURQUALITY_LOW); 957 break; 958 case SkBlurQuality::kHigh_SkBlurQuality: 959 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value( 960 SKDEBUGCANVAS_BLURQUALITY_HIGH); 961 break; 962 default: 963 SkASSERT(false); 964 } 965 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur; 966 } else { 967 Json::Value jsonMaskFilter; 968 flatten(maskFilter, &jsonMaskFilter, urlDataManager); 969 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter; 970 } 971 } 972 } 973 974 static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target, 975 UrlDataManager& urlDataManager) { 976 SkPathEffect* pathEffect = paint.getPathEffect(); 977 if (pathEffect != nullptr) { 978 SkPathEffect::DashInfo dashInfo; 979 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo); 980 if (dashType == SkPathEffect::kDash_DashType) { 981 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar)); 982 pathEffect->asADash(&dashInfo); 983 Json::Value dashing(Json::objectValue); 984 Json::Value intervals(Json::arrayValue); 985 for (int32_t i = 0; i < dashInfo.fCount; i++) { 986 intervals.append(Json::Value(dashInfo.fIntervals[i])); 987 } 988 sk_free(dashInfo.fIntervals); 989 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals; 990 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase; 991 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing; 992 } else { 993 Json::Value jsonPathEffect; 994 flatten(pathEffect, &jsonPathEffect, urlDataManager); 995 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect; 996 } 997 } 998 } 999 1000 static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) { 1001 SkPaint::Align textAlign = paint.getTextAlign(); 1002 if (textAlign != SkPaint::kLeft_Align) { 1003 switch (textAlign) { 1004 case SkPaint::kCenter_Align: { 1005 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER; 1006 break; 1007 } 1008 case SkPaint::kRight_Align: { 1009 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT; 1010 break; 1011 } 1012 default: SkASSERT(false); 1013 } 1014 } 1015 } 1016 1017 static void apply_paint_typeface(const SkPaint& paint, Json::Value* target, 1018 UrlDataManager& urlDataManager) { 1019 SkTypeface* typeface = paint.getTypeface(); 1020 if (typeface != nullptr) { 1021 Json::Value jsonTypeface; 1022 SkDynamicMemoryWStream buffer; 1023 typeface->serialize(&buffer); 1024 void* data = sk_malloc_throw(buffer.bytesWritten()); 1025 buffer.copyTo(data); 1026 Json::Value jsonData; 1027 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, 1028 &jsonData); 1029 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData; 1030 sk_free(data); 1031 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface; 1032 } 1033 } 1034 1035 static void apply_paint_shader(const SkPaint& paint, Json::Value* target, 1036 UrlDataManager& urlDataManager) { 1037 SkFlattenable* shader = paint.getShader(); 1038 if (shader != nullptr) { 1039 Json::Value jsonShader; 1040 flatten(shader, &jsonShader, urlDataManager); 1041 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader; 1042 } 1043 } 1044 1045 static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, 1046 UrlDataManager& urlDataManager) { 1047 SkFlattenable* xfermode = paint.getXfermode(); 1048 if (xfermode != nullptr) { 1049 Json::Value jsonXfermode; 1050 flatten(xfermode, &jsonXfermode, urlDataManager); 1051 (*target)[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode; 1052 } 1053 } 1054 1055 static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, 1056 UrlDataManager& urlDataManager) { 1057 SkFlattenable* imageFilter = paint.getImageFilter(); 1058 if (imageFilter != nullptr) { 1059 Json::Value jsonImageFilter; 1060 flatten(imageFilter, &jsonImageFilter, urlDataManager); 1061 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter; 1062 } 1063 } 1064 1065 static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target, 1066 UrlDataManager& urlDataManager) { 1067 SkFlattenable* colorFilter = paint.getColorFilter(); 1068 if (colorFilter != nullptr) { 1069 Json::Value jsonColorFilter; 1070 flatten(colorFilter, &jsonColorFilter, urlDataManager); 1071 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter; 1072 } 1073 } 1074 1075 static void apply_paint_looper(const SkPaint& paint, Json::Value* target, 1076 UrlDataManager& urlDataManager) { 1077 SkFlattenable* looper = paint.getLooper(); 1078 if (looper != nullptr) { 1079 Json::Value jsonLooper; 1080 flatten(looper, &jsonLooper, urlDataManager); 1081 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper; 1082 } 1083 } 1084 1085 Json::Value make_json_paint(const SkPaint& paint, UrlDataManager& urlDataManager) { 1086 Json::Value result(Json::objectValue); 1087 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f); 1088 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(), 1089 SkPaintDefaults_MiterLimit); 1090 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false); 1091 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false); 1092 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(), 1093 SkPaintDefaults_TextSize); 1094 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1); 1095 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f); 1096 apply_paint_color(paint, &result); 1097 apply_paint_style(paint, &result); 1098 apply_paint_cap(paint, &result); 1099 apply_paint_join(paint, &result); 1100 apply_paint_filterquality(paint, &result); 1101 apply_paint_textalign(paint, &result); 1102 apply_paint_patheffect(paint, &result, urlDataManager); 1103 apply_paint_maskfilter(paint, &result, urlDataManager); 1104 apply_paint_shader(paint, &result, urlDataManager); 1105 apply_paint_xfermode(paint, &result, urlDataManager); 1106 apply_paint_looper(paint, &result, urlDataManager); 1107 apply_paint_imagefilter(paint, &result, urlDataManager); 1108 apply_paint_colorfilter(paint, &result, urlDataManager); 1109 apply_paint_typeface(paint, &result, urlDataManager); 1110 return result; 1111 } 1112 1113 static SkPoint get_json_point(Json::Value point) { 1114 return SkPoint::Make(point[0].asFloat(), point[1].asFloat()); 1115 } 1116 1117 static SkColor get_json_color(Json::Value color) { 1118 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt()); 1119 } 1120 1121 static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) { 1122 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) { 1123 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR])); 1124 } 1125 } 1126 1127 static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1128 SkPaint* target) { 1129 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) { 1130 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER]; 1131 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager); 1132 if (shader != nullptr) { 1133 target->setShader(shader); 1134 shader->unref(); 1135 } 1136 } 1137 } 1138 1139 static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1140 SkPaint* target) { 1141 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) { 1142 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT]; 1143 SkPathEffect* pathEffect = (SkPathEffect*) load_flattenable(jsonPathEffect, urlDataManager); 1144 if (pathEffect != nullptr) { 1145 target->setPathEffect(pathEffect); 1146 pathEffect->unref(); 1147 } 1148 } 1149 } 1150 1151 static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1152 SkPaint* target) { 1153 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) { 1154 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER]; 1155 SkMaskFilter* maskFilter = (SkMaskFilter*) load_flattenable(jsonMaskFilter, urlDataManager); 1156 if (maskFilter != nullptr) { 1157 target->setMaskFilter(maskFilter); 1158 maskFilter->unref(); 1159 } 1160 } 1161 } 1162 1163 static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1164 SkPaint* target) { 1165 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) { 1166 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER]; 1167 SkColorFilter* colorFilter = (SkColorFilter*) load_flattenable(jsonColorFilter, 1168 urlDataManager); 1169 if (colorFilter != nullptr) { 1170 target->setColorFilter(colorFilter); 1171 colorFilter->unref(); 1172 } 1173 } 1174 } 1175 1176 static void extract_json_paint_xfermode(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1177 SkPaint* target) { 1178 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) { 1179 Json::Value jsonXfermode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE]; 1180 SkXfermode* xfermode = (SkXfermode*) load_flattenable(jsonXfermode, urlDataManager); 1181 if (xfermode != nullptr) { 1182 target->setXfermode(xfermode); 1183 xfermode->unref(); 1184 } 1185 } 1186 } 1187 1188 static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1189 SkPaint* target) { 1190 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) { 1191 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER]; 1192 SkDrawLooper* looper = (SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager); 1193 if (looper != nullptr) { 1194 target->setLooper(looper); 1195 looper->unref(); 1196 } 1197 } 1198 } 1199 1200 static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1201 SkPaint* target) { 1202 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) { 1203 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER]; 1204 SkImageFilter* imageFilter = (SkImageFilter*) load_flattenable(jsonImageFilter, 1205 urlDataManager); 1206 if (imageFilter != nullptr) { 1207 target->setImageFilter(imageFilter); 1208 imageFilter->unref(); 1209 } 1210 } 1211 } 1212 1213 static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager, 1214 SkPaint* target) { 1215 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) { 1216 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE]; 1217 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA]; 1218 const void* data; 1219 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data); 1220 SkMemoryStream buffer(data, length); 1221 SkTypeface* typeface = SkTypeface::Deserialize(&buffer); 1222 target->setTypeface(typeface); 1223 } 1224 } 1225 1226 static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) { 1227 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) { 1228 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString(); 1229 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) { 1230 target->setStyle(SkPaint::kFill_Style); 1231 } 1232 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) { 1233 target->setStyle(SkPaint::kStroke_Style); 1234 } 1235 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) { 1236 target->setStyle(SkPaint::kStrokeAndFill_Style); 1237 } 1238 } 1239 } 1240 1241 static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) { 1242 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) { 1243 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat(); 1244 target->setStrokeWidth(strokeWidth); 1245 } 1246 } 1247 1248 static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) { 1249 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) { 1250 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat(); 1251 target->setStrokeMiter(strokeMiter); 1252 } 1253 } 1254 1255 static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) { 1256 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) { 1257 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString(); 1258 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) { 1259 target->setStrokeJoin(SkPaint::kMiter_Join); 1260 } 1261 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) { 1262 target->setStrokeJoin(SkPaint::kRound_Join); 1263 } 1264 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) { 1265 target->setStrokeJoin(SkPaint::kBevel_Join); 1266 } 1267 else { 1268 SkASSERT(false); 1269 } 1270 } 1271 } 1272 1273 static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) { 1274 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) { 1275 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString(); 1276 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) { 1277 target->setStrokeCap(SkPaint::kButt_Cap); 1278 } 1279 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) { 1280 target->setStrokeCap(SkPaint::kRound_Cap); 1281 } 1282 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) { 1283 target->setStrokeCap(SkPaint::kSquare_Cap); 1284 } 1285 } 1286 } 1287 1288 static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) { 1289 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) { 1290 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString(); 1291 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) { 1292 target->setFilterQuality(kNone_SkFilterQuality); 1293 } 1294 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) { 1295 target->setFilterQuality(kLow_SkFilterQuality); 1296 } 1297 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) { 1298 target->setFilterQuality(kMedium_SkFilterQuality); 1299 } 1300 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) { 1301 target->setFilterQuality(kHigh_SkFilterQuality); 1302 } 1303 } 1304 } 1305 1306 static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) { 1307 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) { 1308 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); 1309 } 1310 } 1311 1312 static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) { 1313 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) { 1314 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool()); 1315 } 1316 } 1317 1318 static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) { 1319 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) { 1320 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR]; 1321 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat(); 1322 SkBlurStyle style; 1323 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString(); 1324 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) { 1325 style = SkBlurStyle::kNormal_SkBlurStyle; 1326 } 1327 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) { 1328 style = SkBlurStyle::kSolid_SkBlurStyle; 1329 } 1330 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) { 1331 style = SkBlurStyle::kOuter_SkBlurStyle; 1332 } 1333 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) { 1334 style = SkBlurStyle::kInner_SkBlurStyle; 1335 } 1336 else { 1337 SkASSERT(false); 1338 style = SkBlurStyle::kNormal_SkBlurStyle; 1339 } 1340 SkBlurMaskFilter::BlurFlags flags; 1341 const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString(); 1342 if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) { 1343 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag; 1344 } 1345 else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) { 1346 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag; 1347 } 1348 else { 1349 SkASSERT(false); 1350 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag; 1351 } 1352 target->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags)); 1353 } 1354 } 1355 1356 static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) { 1357 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) { 1358 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING]; 1359 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS]; 1360 Json::ArrayIndex count = jsonIntervals.size(); 1361 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar)); 1362 for (Json::ArrayIndex i = 0; i < count; i++) { 1363 intervals[i] = jsonIntervals[i].asFloat(); 1364 } 1365 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat(); 1366 target->setPathEffect(SkDashPathEffect::Create(intervals, count, phase)); 1367 sk_free(intervals); 1368 } 1369 } 1370 1371 static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) { 1372 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) { 1373 SkPaint::Align textAlign; 1374 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString(); 1375 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) { 1376 textAlign = SkPaint::kLeft_Align; 1377 } 1378 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) { 1379 textAlign = SkPaint::kCenter_Align; 1380 } 1381 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) { 1382 textAlign = SkPaint::kRight_Align; 1383 } 1384 else { 1385 SkASSERT(false); 1386 textAlign = SkPaint::kLeft_Align; 1387 } 1388 target->setTextAlign(textAlign); 1389 } 1390 } 1391 1392 static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) { 1393 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) { 1394 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat(); 1395 target->setTextSize(textSize); 1396 } 1397 } 1398 1399 static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) { 1400 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) { 1401 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat(); 1402 target->setTextScaleX(textScaleX); 1403 } 1404 } 1405 1406 static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) { 1407 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) { 1408 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat(); 1409 target->setTextSkewX(textSkewX); 1410 } 1411 } 1412 1413 static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager, 1414 SkPaint* result) { 1415 extract_json_paint_color(paint, result); 1416 extract_json_paint_shader(paint, urlDataManager, result); 1417 extract_json_paint_patheffect(paint, urlDataManager, result); 1418 extract_json_paint_maskfilter(paint, urlDataManager, result); 1419 extract_json_paint_colorfilter(paint, urlDataManager, result); 1420 extract_json_paint_xfermode(paint, urlDataManager, result); 1421 extract_json_paint_looper(paint, urlDataManager, result); 1422 extract_json_paint_imagefilter(paint, urlDataManager, result); 1423 extract_json_paint_typeface(paint, urlDataManager, result); 1424 extract_json_paint_style(paint, result); 1425 extract_json_paint_strokewidth(paint, result); 1426 extract_json_paint_strokemiter(paint, result); 1427 extract_json_paint_strokejoin(paint, result); 1428 extract_json_paint_cap(paint, result); 1429 extract_json_paint_filterquality(paint, result); 1430 extract_json_paint_antialias(paint, result); 1431 extract_json_paint_dither(paint, result); 1432 extract_json_paint_blur(paint, result); 1433 extract_json_paint_dashing(paint, result); 1434 extract_json_paint_textalign(paint, result); 1435 extract_json_paint_textsize(paint, result); 1436 extract_json_paint_textscalex(paint, result); 1437 extract_json_paint_textskewx(paint, result); 1438 } 1439 1440 static void extract_json_rect(Json::Value& rect, SkRect* result) { 1441 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat()); 1442 } 1443 1444 static void extract_json_irect(Json::Value& rect, SkIRect* result) { 1445 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt()); 1446 } 1447 1448 static void extract_json_rrect(Json::Value& rrect, SkRRect* result) { 1449 SkVector radii[4] = { 1450 { rrect[1][0].asFloat(), rrect[1][1].asFloat() }, 1451 { rrect[2][0].asFloat(), rrect[2][1].asFloat() }, 1452 { rrect[3][0].asFloat(), rrect[3][1].asFloat() }, 1453 { rrect[4][0].asFloat(), rrect[4][1].asFloat() } 1454 }; 1455 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(), 1456 rrect[0][2].asFloat(), rrect[0][3].asFloat()), 1457 radii); 1458 } 1459 1460 static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) { 1461 SkScalar values[] = { 1462 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(), 1463 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(), 1464 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat() 1465 }; 1466 result->set9(values); 1467 } 1468 1469 static void extract_json_path(Json::Value& path, SkPath* result) { 1470 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString(); 1471 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) { 1472 result->setFillType(SkPath::kWinding_FillType); 1473 } 1474 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) { 1475 result->setFillType(SkPath::kEvenOdd_FillType); 1476 } 1477 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) { 1478 result->setFillType(SkPath::kInverseWinding_FillType); 1479 } 1480 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) { 1481 result->setFillType(SkPath::kInverseEvenOdd_FillType); 1482 } 1483 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS]; 1484 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) { 1485 Json::Value verb = verbs[i]; 1486 if (verb.isString()) { 1487 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE)); 1488 result->close(); 1489 } 1490 else { 1491 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) { 1492 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE]; 1493 result->moveTo(move[0].asFloat(), move[1].asFloat()); 1494 } 1495 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) { 1496 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE]; 1497 result->lineTo(line[0].asFloat(), line[1].asFloat()); 1498 } 1499 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) { 1500 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD]; 1501 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(), 1502 quad[1][0].asFloat(), quad[1][1].asFloat()); 1503 } 1504 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) { 1505 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC]; 1506 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(), 1507 cubic[1][0].asFloat(), cubic[1][1].asFloat(), 1508 cubic[2][0].asFloat(), cubic[2][1].asFloat()); 1509 } 1510 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) { 1511 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC]; 1512 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(), 1513 conic[1][0].asFloat(), conic[1][1].asFloat(), 1514 conic[2].asFloat()); 1515 } 1516 else { 1517 SkASSERT(false); 1518 } 1519 } 1520 } 1521 } 1522 1523 SkRegion::Op get_json_regionop(Json::Value& jsonOp) { 1524 const char* op = jsonOp.asCString(); 1525 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) { 1526 return SkRegion::kDifference_Op; 1527 } 1528 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) { 1529 return SkRegion::kIntersect_Op; 1530 } 1531 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) { 1532 return SkRegion::kUnion_Op; 1533 } 1534 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) { 1535 return SkRegion::kXOR_Op; 1536 } 1537 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) { 1538 return SkRegion::kReverseDifference_Op; 1539 } 1540 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) { 1541 return SkRegion::kReplace_Op; 1542 } 1543 SkASSERT(false); 1544 return SkRegion::kIntersect_Op; 1545 } 1546 1547 SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kDrawClear_OpType) { 1548 fColor = color; 1549 fInfo.push(SkObjectParser::CustomTextToString("No Parameters")); 1550 } 1551 1552 void SkClearCommand::execute(SkCanvas* canvas) const { 1553 canvas->clear(fColor); 1554 } 1555 1556 Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const { 1557 Json::Value result = INHERITED::toJSON(urlDataManager); 1558 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = make_json_color(fColor); 1559 return result; 1560 } 1561 1562 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) { 1563 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR]; 1564 return new SkClearCommand(get_json_color(color)); 1565 } 1566 1567 SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA) 1568 : INHERITED(kClipPath_OpType) { 1569 fPath = path; 1570 fOp = op; 1571 fDoAA = doAA; 1572 1573 fInfo.push(SkObjectParser::PathToString(path)); 1574 fInfo.push(SkObjectParser::RegionOpToString(op)); 1575 fInfo.push(SkObjectParser::BoolToString(doAA)); 1576 } 1577 1578 void SkClipPathCommand::execute(SkCanvas* canvas) const { 1579 canvas->clipPath(fPath, fOp, fDoAA); 1580 } 1581 1582 bool SkClipPathCommand::render(SkCanvas* canvas) const { 1583 render_path(canvas, fPath); 1584 return true; 1585 } 1586 1587 Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const { 1588 Json::Value result = INHERITED::toJSON(urlDataManager); 1589 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath); 1590 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp); 1591 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA; 1592 return result; 1593 } 1594 1595 SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command, 1596 UrlDataManager& urlDataManager) { 1597 SkPath path; 1598 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path); 1599 return new SkClipPathCommand(path, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]), 1600 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); 1601 } 1602 1603 SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op) 1604 : INHERITED(kClipRegion_OpType) { 1605 fRegion = region; 1606 fOp = op; 1607 1608 fInfo.push(SkObjectParser::RegionToString(region)); 1609 fInfo.push(SkObjectParser::RegionOpToString(op)); 1610 } 1611 1612 void SkClipRegionCommand::execute(SkCanvas* canvas) const { 1613 canvas->clipRegion(fRegion, fOp); 1614 } 1615 1616 Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const { 1617 Json::Value result = INHERITED::toJSON(urlDataManager); 1618 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = make_json_region(fRegion); 1619 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp); 1620 return result; 1621 } 1622 1623 SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command, 1624 UrlDataManager& urlDataManager) { 1625 SkASSERT(false); 1626 return nullptr; 1627 } 1628 1629 SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA) 1630 : INHERITED(kClipRect_OpType) { 1631 fRect = rect; 1632 fOp = op; 1633 fDoAA = doAA; 1634 1635 fInfo.push(SkObjectParser::RectToString(rect)); 1636 fInfo.push(SkObjectParser::RegionOpToString(op)); 1637 fInfo.push(SkObjectParser::BoolToString(doAA)); 1638 } 1639 1640 void SkClipRectCommand::execute(SkCanvas* canvas) const { 1641 canvas->clipRect(fRect, fOp, fDoAA); 1642 } 1643 1644 Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const { 1645 Json::Value result = INHERITED::toJSON(urlDataManager); 1646 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect); 1647 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp); 1648 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA); 1649 return result; 1650 } 1651 1652 SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command, 1653 UrlDataManager& urlDataManager) { 1654 SkRect rect; 1655 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect); 1656 return new SkClipRectCommand(rect, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]), 1657 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); 1658 } 1659 1660 SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA) 1661 : INHERITED(kClipRRect_OpType) { 1662 fRRect = rrect; 1663 fOp = op; 1664 fDoAA = doAA; 1665 1666 fInfo.push(SkObjectParser::RRectToString(rrect)); 1667 fInfo.push(SkObjectParser::RegionOpToString(op)); 1668 fInfo.push(SkObjectParser::BoolToString(doAA)); 1669 } 1670 1671 void SkClipRRectCommand::execute(SkCanvas* canvas) const { 1672 canvas->clipRRect(fRRect, fOp, fDoAA); 1673 } 1674 1675 bool SkClipRRectCommand::render(SkCanvas* canvas) const { 1676 render_rrect(canvas, fRRect); 1677 return true; 1678 } 1679 1680 Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const { 1681 Json::Value result = INHERITED::toJSON(urlDataManager); 1682 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect); 1683 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp); 1684 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA); 1685 return result; 1686 } 1687 1688 SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command, 1689 UrlDataManager& urlDataManager) { 1690 SkRRect rrect; 1691 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect); 1692 return new SkClipRRectCommand(rrect, 1693 get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]), 1694 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); 1695 } 1696 1697 SkConcatCommand::SkConcatCommand(const SkMatrix& matrix) 1698 : INHERITED(kConcat_OpType) { 1699 fMatrix = matrix; 1700 1701 fInfo.push(SkObjectParser::MatrixToString(matrix)); 1702 } 1703 1704 void SkConcatCommand::execute(SkCanvas* canvas) const { 1705 canvas->concat(fMatrix); 1706 } 1707 1708 Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const { 1709 Json::Value result = INHERITED::toJSON(urlDataManager); 1710 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix); 1711 return result; 1712 } 1713 1714 SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) { 1715 SkMatrix matrix; 1716 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix); 1717 return new SkConcatCommand(matrix); 1718 } 1719 1720 SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top, 1721 const SkPaint* paint) 1722 : INHERITED(kDrawBitmap_OpType) { 1723 fBitmap = bitmap; 1724 fLeft = left; 1725 fTop = top; 1726 if (paint) { 1727 fPaint = *paint; 1728 fPaintPtr = &fPaint; 1729 } else { 1730 fPaintPtr = nullptr; 1731 } 1732 1733 fInfo.push(SkObjectParser::BitmapToString(bitmap)); 1734 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: ")); 1735 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: ")); 1736 if (paint) { 1737 fInfo.push(SkObjectParser::PaintToString(*paint)); 1738 } 1739 } 1740 1741 void SkDrawBitmapCommand::execute(SkCanvas* canvas) const { 1742 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr); 1743 } 1744 1745 bool SkDrawBitmapCommand::render(SkCanvas* canvas) const { 1746 render_bitmap(canvas, fBitmap); 1747 return true; 1748 } 1749 1750 Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const { 1751 Json::Value result = INHERITED::toJSON(urlDataManager); 1752 Json::Value encoded; 1753 if (flatten(fBitmap, &encoded, urlDataManager)) { 1754 Json::Value command(Json::objectValue); 1755 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded; 1756 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop); 1757 if (fPaintPtr != nullptr) { 1758 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, urlDataManager); 1759 } 1760 } 1761 return result; 1762 } 1763 1764 SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command, 1765 UrlDataManager& urlDataManager) { 1766 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager); 1767 if (bitmap == nullptr) { 1768 return nullptr; 1769 } 1770 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS]; 1771 SkPaint* paintPtr; 1772 SkPaint paint; 1773 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) { 1774 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 1775 paintPtr = &paint; 1776 } 1777 else { 1778 paintPtr = nullptr; 1779 } 1780 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(), 1781 point[1].asFloat(), paintPtr); 1782 delete bitmap; 1783 return result; 1784 } 1785 1786 SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center, 1787 const SkRect& dst, const SkPaint* paint) 1788 : INHERITED(kDrawBitmapNine_OpType) { 1789 fBitmap = bitmap; 1790 fCenter = center; 1791 fDst = dst; 1792 if (paint) { 1793 fPaint = *paint; 1794 fPaintPtr = &fPaint; 1795 } else { 1796 fPaintPtr = nullptr; 1797 } 1798 1799 fInfo.push(SkObjectParser::BitmapToString(bitmap)); 1800 fInfo.push(SkObjectParser::IRectToString(center)); 1801 fInfo.push(SkObjectParser::RectToString(dst, "Dst: ")); 1802 if (paint) { 1803 fInfo.push(SkObjectParser::PaintToString(*paint)); 1804 } 1805 } 1806 1807 void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const { 1808 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr); 1809 } 1810 1811 bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const { 1812 SkRect tmp = SkRect::Make(fCenter); 1813 render_bitmap(canvas, fBitmap, &tmp); 1814 return true; 1815 } 1816 1817 Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const { 1818 Json::Value result = INHERITED::toJSON(urlDataManager); 1819 Json::Value encoded; 1820 if (flatten(fBitmap, &encoded, urlDataManager)) { 1821 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded; 1822 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = make_json_irect(fCenter); 1823 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst); 1824 if (fPaintPtr != nullptr) { 1825 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, urlDataManager); 1826 } 1827 } 1828 return result; 1829 } 1830 1831 SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command, 1832 UrlDataManager& urlDataManager) { 1833 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager); 1834 if (bitmap == nullptr) { 1835 return nullptr; 1836 } 1837 SkIRect center; 1838 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], ¢er); 1839 SkRect dst; 1840 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst); 1841 SkPaint* paintPtr; 1842 SkPaint paint; 1843 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) { 1844 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 1845 paintPtr = &paint; 1846 } 1847 else { 1848 paintPtr = nullptr; 1849 } 1850 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr); 1851 delete bitmap; 1852 return result; 1853 } 1854 1855 SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src, 1856 const SkRect& dst, const SkPaint* paint, 1857 SkCanvas::SrcRectConstraint constraint) 1858 : INHERITED(kDrawBitmapRect_OpType) { 1859 fBitmap = bitmap; 1860 if (src) { 1861 fSrc = *src; 1862 } else { 1863 fSrc.setEmpty(); 1864 } 1865 fDst = dst; 1866 1867 if (paint) { 1868 fPaint = *paint; 1869 fPaintPtr = &fPaint; 1870 } else { 1871 fPaintPtr = nullptr; 1872 } 1873 fConstraint = constraint; 1874 1875 fInfo.push(SkObjectParser::BitmapToString(bitmap)); 1876 if (src) { 1877 fInfo.push(SkObjectParser::RectToString(*src, "Src: ")); 1878 } 1879 fInfo.push(SkObjectParser::RectToString(dst, "Dst: ")); 1880 if (paint) { 1881 fInfo.push(SkObjectParser::PaintToString(*paint)); 1882 } 1883 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: ")); 1884 } 1885 1886 void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const { 1887 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint); 1888 } 1889 1890 bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const { 1891 render_bitmap(canvas, fBitmap, this->srcRect()); 1892 return true; 1893 } 1894 1895 Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const { 1896 Json::Value result = INHERITED::toJSON(urlDataManager); 1897 Json::Value encoded; 1898 if (flatten(fBitmap, &encoded, urlDataManager)) { 1899 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded; 1900 if (!fSrc.isEmpty()) { 1901 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(fSrc); 1902 } 1903 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst); 1904 if (fPaintPtr != nullptr) { 1905 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, urlDataManager); 1906 } 1907 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) { 1908 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true); 1909 } 1910 } 1911 return result; 1912 } 1913 1914 SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command, 1915 UrlDataManager& urlDataManager) { 1916 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager); 1917 if (bitmap == nullptr) { 1918 return nullptr; 1919 } 1920 SkRect dst; 1921 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst); 1922 SkPaint* paintPtr; 1923 SkPaint paint; 1924 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) { 1925 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 1926 paintPtr = &paint; 1927 } 1928 else { 1929 paintPtr = nullptr; 1930 } 1931 SkCanvas::SrcRectConstraint constraint; 1932 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) && 1933 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) { 1934 constraint = SkCanvas::kStrict_SrcRectConstraint; 1935 } 1936 else { 1937 constraint = SkCanvas::kFast_SrcRectConstraint; 1938 } 1939 SkRect* srcPtr; 1940 SkRect src; 1941 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) { 1942 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src); 1943 srcPtr = &src; 1944 } 1945 else { 1946 srcPtr = nullptr; 1947 } 1948 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr, 1949 constraint); 1950 delete bitmap; 1951 return result; 1952 } 1953 1954 SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top, 1955 const SkPaint* paint) 1956 : INHERITED(kDrawImage_OpType) 1957 , fImage(SkRef(image)) 1958 , fLeft(left) 1959 , fTop(top) { 1960 1961 fInfo.push(SkObjectParser::ImageToString(image)); 1962 fInfo.push(SkObjectParser::ScalarToString(left, "Left: ")); 1963 fInfo.push(SkObjectParser::ScalarToString(top, "Top: ")); 1964 1965 if (paint) { 1966 fPaint.set(*paint); 1967 fInfo.push(SkObjectParser::PaintToString(*paint)); 1968 } 1969 } 1970 1971 void SkDrawImageCommand::execute(SkCanvas* canvas) const { 1972 canvas->drawImage(fImage, fLeft, fTop, fPaint.getMaybeNull()); 1973 } 1974 1975 bool SkDrawImageCommand::render(SkCanvas* canvas) const { 1976 SkAutoCanvasRestore acr(canvas, true); 1977 canvas->clear(0xFFFFFFFF); 1978 1979 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop, 1980 SkIntToScalar(fImage->width()), 1981 SkIntToScalar(fImage->height()))); 1982 this->execute(canvas); 1983 return true; 1984 } 1985 1986 Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const { 1987 Json::Value result = INHERITED::toJSON(urlDataManager); 1988 Json::Value encoded; 1989 if (flatten(*fImage, &encoded, urlDataManager)) { 1990 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded; 1991 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop); 1992 if (fPaint.isValid()) { 1993 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(), urlDataManager); 1994 } 1995 } 1996 return result; 1997 } 1998 1999 SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command, 2000 UrlDataManager& urlDataManager) { 2001 SkImage* image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager); 2002 if (image == nullptr) { 2003 return nullptr; 2004 } 2005 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS]; 2006 SkPaint* paintPtr; 2007 SkPaint paint; 2008 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) { 2009 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2010 paintPtr = &paint; 2011 } 2012 else { 2013 paintPtr = nullptr; 2014 } 2015 SkDrawImageCommand* result = new SkDrawImageCommand(image, point[0].asFloat(), 2016 point[1].asFloat(), paintPtr); 2017 image->unref(); 2018 return result; 2019 } 2020 2021 SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src, 2022 const SkRect& dst, const SkPaint* paint, 2023 SkCanvas::SrcRectConstraint constraint) 2024 : INHERITED(kDrawImageRect_OpType) 2025 , fImage(SkRef(image)) 2026 , fDst(dst) 2027 , fConstraint(constraint) { 2028 2029 if (src) { 2030 fSrc.set(*src); 2031 } 2032 2033 if (paint) { 2034 fPaint.set(*paint); 2035 } 2036 2037 fInfo.push(SkObjectParser::ImageToString(image)); 2038 if (src) { 2039 fInfo.push(SkObjectParser::RectToString(*src, "Src: ")); 2040 } 2041 fInfo.push(SkObjectParser::RectToString(dst, "Dst: ")); 2042 if (paint) { 2043 fInfo.push(SkObjectParser::PaintToString(*paint)); 2044 } 2045 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: ")); 2046 } 2047 2048 void SkDrawImageRectCommand::execute(SkCanvas* canvas) const { 2049 canvas->legacy_drawImageRect(fImage, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), 2050 fConstraint); 2051 } 2052 2053 bool SkDrawImageRectCommand::render(SkCanvas* canvas) const { 2054 SkAutoCanvasRestore acr(canvas, true); 2055 canvas->clear(0xFFFFFFFF); 2056 2057 xlate_and_scale_to_bounds(canvas, fDst); 2058 2059 this->execute(canvas); 2060 return true; 2061 } 2062 2063 Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const { 2064 Json::Value result = INHERITED::toJSON(urlDataManager); 2065 Json::Value encoded; 2066 if (flatten(*fImage.get(), &encoded, urlDataManager)) { 2067 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded; 2068 if (fSrc.isValid()) { 2069 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(*fSrc.get()); 2070 } 2071 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst); 2072 if (fPaint.isValid()) { 2073 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(), urlDataManager); 2074 } 2075 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) { 2076 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true); 2077 } 2078 } 2079 return result; 2080 } 2081 2082 SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command, 2083 UrlDataManager& urlDataManager) { 2084 SkImage* image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager); 2085 if (image == nullptr) { 2086 return nullptr; 2087 } 2088 SkRect dst; 2089 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst); 2090 SkPaint* paintPtr; 2091 SkPaint paint; 2092 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) { 2093 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2094 paintPtr = &paint; 2095 } 2096 else { 2097 paintPtr = nullptr; 2098 } 2099 SkCanvas::SrcRectConstraint constraint; 2100 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) && 2101 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) { 2102 constraint = SkCanvas::kStrict_SrcRectConstraint; 2103 } 2104 else { 2105 constraint = SkCanvas::kFast_SrcRectConstraint; 2106 } 2107 SkRect* srcPtr; 2108 SkRect src; 2109 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) { 2110 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src); 2111 srcPtr = &src; 2112 } 2113 else { 2114 srcPtr = nullptr; 2115 } 2116 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image, srcPtr, dst, paintPtr, 2117 constraint); 2118 image->unref(); 2119 return result; 2120 } 2121 2122 SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint) 2123 : INHERITED(kDrawOval_OpType) { 2124 fOval = oval; 2125 fPaint = paint; 2126 2127 fInfo.push(SkObjectParser::RectToString(oval)); 2128 fInfo.push(SkObjectParser::PaintToString(paint)); 2129 } 2130 2131 void SkDrawOvalCommand::execute(SkCanvas* canvas) const { 2132 canvas->drawOval(fOval, fPaint); 2133 } 2134 2135 bool SkDrawOvalCommand::render(SkCanvas* canvas) const { 2136 canvas->clear(0xFFFFFFFF); 2137 canvas->save(); 2138 2139 xlate_and_scale_to_bounds(canvas, fOval); 2140 2141 SkPaint p; 2142 p.setColor(SK_ColorBLACK); 2143 p.setStyle(SkPaint::kStroke_Style); 2144 2145 canvas->drawOval(fOval, p); 2146 canvas->restore(); 2147 2148 return true; 2149 } 2150 2151 Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const { 2152 Json::Value result = INHERITED::toJSON(urlDataManager); 2153 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fOval); 2154 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2155 return result; 2156 } 2157 2158 SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command, 2159 UrlDataManager& urlDataManager) { 2160 SkRect coords; 2161 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords); 2162 SkPaint paint; 2163 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2164 return new SkDrawOvalCommand(coords, paint); 2165 } 2166 2167 SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint) 2168 : INHERITED(kDrawPaint_OpType) { 2169 fPaint = paint; 2170 2171 fInfo.push(SkObjectParser::PaintToString(paint)); 2172 } 2173 2174 void SkDrawPaintCommand::execute(SkCanvas* canvas) const { 2175 canvas->drawPaint(fPaint); 2176 } 2177 2178 bool SkDrawPaintCommand::render(SkCanvas* canvas) const { 2179 canvas->clear(0xFFFFFFFF); 2180 canvas->drawPaint(fPaint); 2181 return true; 2182 } 2183 2184 Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const { 2185 Json::Value result = INHERITED::toJSON(urlDataManager); 2186 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2187 return result; 2188 } 2189 2190 SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command, 2191 UrlDataManager& urlDataManager) { 2192 SkPaint paint; 2193 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2194 return new SkDrawPaintCommand(paint); 2195 } 2196 2197 SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint) 2198 : INHERITED(kDrawPath_OpType) { 2199 fPath = path; 2200 fPaint = paint; 2201 2202 fInfo.push(SkObjectParser::PathToString(path)); 2203 fInfo.push(SkObjectParser::PaintToString(paint)); 2204 } 2205 2206 void SkDrawPathCommand::execute(SkCanvas* canvas) const { 2207 canvas->drawPath(fPath, fPaint); 2208 } 2209 2210 bool SkDrawPathCommand::render(SkCanvas* canvas) const { 2211 render_path(canvas, fPath); 2212 return true; 2213 } 2214 2215 Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const { 2216 Json::Value result = INHERITED::toJSON(urlDataManager); 2217 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath); 2218 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2219 return result; 2220 } 2221 2222 SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command, 2223 UrlDataManager& urlDataManager) { 2224 SkPath path; 2225 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path); 2226 SkPaint paint; 2227 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2228 return new SkDrawPathCommand(path, paint); 2229 } 2230 2231 SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture, 2232 const SkMatrix* matrix, 2233 const SkPaint* paint) 2234 : INHERITED(kBeginDrawPicture_OpType) 2235 , fPicture(SkRef(picture)) { 2236 2237 SkString* str = new SkString; 2238 str->appendf("SkPicture: L: %f T: %f R: %f B: %f", 2239 picture->cullRect().fLeft, picture->cullRect().fTop, 2240 picture->cullRect().fRight, picture->cullRect().fBottom); 2241 fInfo.push(str); 2242 2243 if (matrix) { 2244 fMatrix.set(*matrix); 2245 fInfo.push(SkObjectParser::MatrixToString(*matrix)); 2246 } 2247 2248 if (paint) { 2249 fPaint.set(*paint); 2250 fInfo.push(SkObjectParser::PaintToString(*paint)); 2251 } 2252 2253 } 2254 2255 void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const { 2256 if (fPaint.isValid()) { 2257 SkRect bounds = fPicture->cullRect(); 2258 if (fMatrix.isValid()) { 2259 fMatrix.get()->mapRect(&bounds); 2260 } 2261 canvas->saveLayer(&bounds, fPaint.get()); 2262 } 2263 2264 if (fMatrix.isValid()) { 2265 if (!fPaint.isValid()) { 2266 canvas->save(); 2267 } 2268 canvas->concat(*fMatrix.get()); 2269 } 2270 } 2271 2272 bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const { 2273 canvas->clear(0xFFFFFFFF); 2274 canvas->save(); 2275 2276 xlate_and_scale_to_bounds(canvas, fPicture->cullRect()); 2277 2278 canvas->drawPicture(fPicture.get()); 2279 2280 canvas->restore(); 2281 2282 return true; 2283 } 2284 2285 SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore) 2286 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { } 2287 2288 void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const { 2289 if (fRestore) { 2290 canvas->restore(); 2291 } 2292 } 2293 2294 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count, 2295 const SkPoint pts[], const SkPaint& paint) 2296 : INHERITED(kDrawPoints_OpType) { 2297 fMode = mode; 2298 fCount = count; 2299 fPts = new SkPoint[count]; 2300 memcpy(fPts, pts, count * sizeof(SkPoint)); 2301 fPaint = paint; 2302 2303 fInfo.push(SkObjectParser::PointsToString(pts, count)); 2304 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count), 2305 "Points: ")); 2306 fInfo.push(SkObjectParser::PointModeToString(mode)); 2307 fInfo.push(SkObjectParser::PaintToString(paint)); 2308 } 2309 2310 void SkDrawPointsCommand::execute(SkCanvas* canvas) const { 2311 canvas->drawPoints(fMode, fCount, fPts, fPaint); 2312 } 2313 2314 bool SkDrawPointsCommand::render(SkCanvas* canvas) const { 2315 canvas->clear(0xFFFFFFFF); 2316 canvas->save(); 2317 2318 SkRect bounds; 2319 2320 bounds.setEmpty(); 2321 for (unsigned int i = 0; i < fCount; ++i) { 2322 bounds.growToInclude(fPts[i].fX, fPts[i].fY); 2323 } 2324 2325 xlate_and_scale_to_bounds(canvas, bounds); 2326 2327 SkPaint p; 2328 p.setColor(SK_ColorBLACK); 2329 p.setStyle(SkPaint::kStroke_Style); 2330 2331 canvas->drawPoints(fMode, fCount, fPts, p); 2332 canvas->restore(); 2333 2334 return true; 2335 } 2336 2337 Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const { 2338 Json::Value result = INHERITED::toJSON(urlDataManager); 2339 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode); 2340 Json::Value points(Json::arrayValue); 2341 for (size_t i = 0; i < fCount; i++) { 2342 points.append(make_json_point(fPts[i])); 2343 } 2344 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points; 2345 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2346 return result; 2347 } 2348 2349 SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command, 2350 UrlDataManager& urlDataManager) { 2351 SkCanvas::PointMode mode; 2352 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString(); 2353 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) { 2354 mode = SkCanvas::kPoints_PointMode; 2355 } 2356 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) { 2357 mode = SkCanvas::kLines_PointMode; 2358 } 2359 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) { 2360 mode = SkCanvas::kPolygon_PointMode; 2361 } 2362 else { 2363 SkASSERT(false); 2364 return nullptr; 2365 } 2366 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS]; 2367 int count = (int) jsonPoints.size(); 2368 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); 2369 for (int i = 0; i < count; i++) { 2370 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat()); 2371 } 2372 SkPaint paint; 2373 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2374 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint); 2375 sk_free(points); 2376 return result; 2377 } 2378 2379 SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength, 2380 const SkPoint pos[], const SkPaint& paint) 2381 : INHERITED(kDrawPosText_OpType) { 2382 size_t numPts = paint.countText(text, byteLength); 2383 2384 fText = new char[byteLength]; 2385 memcpy(fText, text, byteLength); 2386 fByteLength = byteLength; 2387 2388 fPos = new SkPoint[numPts]; 2389 memcpy(fPos, pos, numPts * sizeof(SkPoint)); 2390 2391 fPaint = paint; 2392 2393 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding())); 2394 // TODO(chudy): Test that this works. 2395 fInfo.push(SkObjectParser::PointsToString(pos, 1)); 2396 fInfo.push(SkObjectParser::PaintToString(paint)); 2397 } 2398 2399 void SkDrawPosTextCommand::execute(SkCanvas* canvas) const { 2400 canvas->drawPosText(fText, fByteLength, fPos, fPaint); 2401 } 2402 2403 Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const { 2404 Json::Value result = INHERITED::toJSON(urlDataManager); 2405 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText, 2406 ((const char*) fText) + fByteLength); 2407 Json::Value coords(Json::arrayValue); 2408 for (size_t i = 0; i < fByteLength; i++) { 2409 coords.append(make_json_point(fPos[i])); 2410 } 2411 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords; 2412 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2413 return result; 2414 } 2415 2416 SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command, 2417 UrlDataManager& urlDataManager) { 2418 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString(); 2419 SkPaint paint; 2420 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2421 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS]; 2422 int count = (int) coords.size(); 2423 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); 2424 for (int i = 0; i < count; i++) { 2425 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat()); 2426 } 2427 return new SkDrawPosTextCommand(text, strlen(text), points, paint); 2428 } 2429 2430 SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength, 2431 const SkScalar xpos[], SkScalar constY, 2432 const SkPaint& paint) 2433 : INHERITED(kDrawPosTextH_OpType) { 2434 size_t numPts = paint.countText(text, byteLength); 2435 2436 fText = new char[byteLength]; 2437 memcpy(fText, text, byteLength); 2438 fByteLength = byteLength; 2439 2440 fXpos = new SkScalar[numPts]; 2441 memcpy(fXpos, xpos, numPts * sizeof(SkScalar)); 2442 2443 fConstY = constY; 2444 fPaint = paint; 2445 2446 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding())); 2447 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: ")); 2448 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: ")); 2449 fInfo.push(SkObjectParser::PaintToString(paint)); 2450 } 2451 2452 void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const { 2453 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint); 2454 } 2455 2456 static const char* gPositioningLabels[] = { 2457 "kDefault_Positioning", 2458 "kHorizontal_Positioning", 2459 "kFull_Positioning", 2460 }; 2461 2462 SkDrawTextBlobCommand::SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y, 2463 const SkPaint& paint) 2464 : INHERITED(kDrawTextBlob_OpType) 2465 , fBlob(SkRef(blob)) 2466 , fXPos(x) 2467 , fYPos(y) 2468 , fPaint(paint) { 2469 2470 SkAutoTDelete<SkString> runsStr(new SkString); 2471 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: ")); 2472 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: ")); 2473 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: ")); 2474 fInfo.push(runsStr); 2475 fInfo.push(SkObjectParser::PaintToString(paint)); 2476 2477 unsigned runs = 0; 2478 SkPaint runPaint(paint); 2479 SkTextBlobRunIterator iter(blob); 2480 while (!iter.done()) { 2481 SkAutoTDelete<SkString> tmpStr(new SkString); 2482 tmpStr->printf("==== Run [%d] ====", runs++); 2483 fInfo.push(tmpStr.release()); 2484 2485 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: ")); 2486 tmpStr.reset(new SkString("GlyphPositioning: ")); 2487 tmpStr->append(gPositioningLabels[iter.positioning()]); 2488 fInfo.push(tmpStr.release()); 2489 2490 iter.applyFontToPaint(&runPaint); 2491 fInfo.push(SkObjectParser::PaintToString(runPaint)); 2492 2493 iter.next(); 2494 } 2495 2496 runsStr->printf("Runs: %d", runs); 2497 // runStr is owned by fInfo at this point. 2498 runsStr.release(); 2499 } 2500 2501 void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const { 2502 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint); 2503 } 2504 2505 bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const { 2506 canvas->clear(SK_ColorWHITE); 2507 canvas->save(); 2508 2509 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos); 2510 xlate_and_scale_to_bounds(canvas, bounds); 2511 2512 canvas->drawTextBlob(fBlob.get(), fXPos, fYPos, fPaint); 2513 2514 canvas->restore(); 2515 2516 return true; 2517 } 2518 2519 Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const { 2520 Json::Value result = INHERITED::toJSON(urlDataManager); 2521 Json::Value runs(Json::arrayValue); 2522 SkTextBlobRunIterator iter(fBlob.get()); 2523 while (!iter.done()) { 2524 Json::Value run(Json::objectValue); 2525 Json::Value jsonPositions(Json::arrayValue); 2526 Json::Value jsonGlyphs(Json::arrayValue); 2527 const SkScalar* iterPositions = iter.pos(); 2528 const uint16_t* iterGlyphs = iter.glyphs(); 2529 for (uint32_t i = 0; i < iter.glyphCount(); i++) { 2530 switch (iter.positioning()) { 2531 case SkTextBlob::kFull_Positioning: 2532 jsonPositions.append(make_json_point(iterPositions[i * 2], 2533 iterPositions[i * 2 + 1])); 2534 break; 2535 case SkTextBlob::kHorizontal_Positioning: 2536 jsonPositions.append(Json::Value(iterPositions[i])); 2537 break; 2538 case SkTextBlob::kDefault_Positioning: 2539 break; 2540 } 2541 jsonGlyphs.append(Json::Value(iterGlyphs[i])); 2542 } 2543 if (iter.positioning() != SkTextBlob::kDefault_Positioning) { 2544 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions; 2545 } 2546 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs; 2547 SkPaint fontPaint; 2548 iter.applyFontToPaint(&fontPaint); 2549 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = make_json_paint(fontPaint, urlDataManager); 2550 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(iter.offset()); 2551 runs.append(run); 2552 iter.next(); 2553 } 2554 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs; 2555 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos); 2556 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos); 2557 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2558 return result; 2559 } 2560 2561 SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command, 2562 UrlDataManager& urlDataManager) { 2563 SkTextBlobBuilder builder; 2564 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS]; 2565 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) { 2566 Json::Value run = runs[i]; 2567 SkPaint font; 2568 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 2569 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font); 2570 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS]; 2571 int count = glyphs.size(); 2572 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS]; 2573 SkScalar x = coords[0].asFloat(); 2574 SkScalar y = coords[1].asFloat(); 2575 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) { 2576 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS]; 2577 if (positions.size() > 0 && positions[0].isNumeric()) { 2578 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y); 2579 for (int j = 0; j < count; j++) { 2580 buffer.glyphs[j] = glyphs[j].asUInt(); 2581 buffer.pos[j] = positions[j].asFloat(); 2582 } 2583 } 2584 else { 2585 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count); 2586 for (int j = 0; j < count; j++) { 2587 buffer.glyphs[j] = glyphs[j].asUInt(); 2588 buffer.pos[j * 2] = positions[j][0].asFloat(); 2589 buffer.pos[j * 2 + 1] = positions[j][1].asFloat(); 2590 } 2591 } 2592 } 2593 else { 2594 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y); 2595 for (int j = 0; j < count; j++) { 2596 buffer.glyphs[j] = glyphs[j].asUInt(); 2597 } 2598 } 2599 } 2600 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat(); 2601 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat(); 2602 SkPaint paint; 2603 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2604 return new SkDrawTextBlobCommand(builder.build(), x, y, paint); 2605 } 2606 2607 SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4], 2608 const SkPoint texCoords[4], SkXfermode* xfermode, 2609 const SkPaint& paint) 2610 : INHERITED(kDrawPatch_OpType) { 2611 memcpy(fCubics, cubics, sizeof(fCubics)); 2612 if (colors != nullptr) { 2613 memcpy(fColors, colors, sizeof(fColors)); 2614 fColorsPtr = fColors; 2615 } else { 2616 fColorsPtr = nullptr; 2617 } 2618 if (texCoords != nullptr) { 2619 memcpy(fTexCoords, texCoords, sizeof(fTexCoords)); 2620 fTexCoordsPtr = fTexCoords; 2621 } else { 2622 fTexCoordsPtr = nullptr; 2623 } 2624 if (xfermode != nullptr) { 2625 fXfermode.reset(SkRef(xfermode)); 2626 } 2627 fPaint = paint; 2628 2629 fInfo.push(SkObjectParser::PaintToString(paint)); 2630 } 2631 2632 void SkDrawPatchCommand::execute(SkCanvas* canvas) const { 2633 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fXfermode, fPaint); 2634 } 2635 2636 Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const { 2637 Json::Value result = INHERITED::toJSON(urlDataManager); 2638 Json::Value cubics = Json::Value(Json::arrayValue); 2639 for (int i = 0; i < 12; i++) { 2640 cubics.append(make_json_point(fCubics[i])); 2641 } 2642 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics; 2643 if (fColorsPtr != nullptr) { 2644 Json::Value colors = Json::Value(Json::arrayValue); 2645 for (int i = 0; i < 4; i++) { 2646 colors.append(make_json_color(fColorsPtr[i])); 2647 } 2648 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors; 2649 } 2650 if (fTexCoordsPtr != nullptr) { 2651 Json::Value texCoords = Json::Value(Json::arrayValue); 2652 for (int i = 0; i < 4; i++) { 2653 texCoords.append(make_json_point(fTexCoords[i])); 2654 } 2655 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords; 2656 } 2657 if (fXfermode.get() != nullptr) { 2658 Json::Value jsonXfermode; 2659 flatten(fXfermode, &jsonXfermode, urlDataManager); 2660 result[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode; 2661 } 2662 return result; 2663 } 2664 2665 SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command, 2666 UrlDataManager& urlDataManager) { 2667 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS]; 2668 SkPoint cubics[12]; 2669 for (int i = 0; i < 12; i++) { 2670 cubics[i] = get_json_point(jsonCubics[i]); 2671 } 2672 SkColor* colorsPtr; 2673 SkColor colors[4]; 2674 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) { 2675 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS]; 2676 for (int i = 0; i < 4; i++) { 2677 colors[i] = get_json_color(jsonColors[i]); 2678 } 2679 colorsPtr = colors; 2680 } 2681 else { 2682 colorsPtr = nullptr; 2683 } 2684 SkPoint* texCoordsPtr; 2685 SkPoint texCoords[4]; 2686 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) { 2687 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS]; 2688 for (int i = 0; i < 4; i++) { 2689 texCoords[i] = get_json_point(jsonTexCoords[i]); 2690 } 2691 texCoordsPtr = texCoords; 2692 } 2693 else { 2694 texCoordsPtr = nullptr; 2695 } 2696 SkAutoTUnref<SkXfermode> xfermode; 2697 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) { 2698 Json::Value jsonXfermode = command[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE]; 2699 xfermode.reset((SkXfermode*) load_flattenable(jsonXfermode, urlDataManager)); 2700 } 2701 SkPaint paint; 2702 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2703 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, xfermode, paint); 2704 } 2705 2706 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint) 2707 : INHERITED(kDrawRect_OpType) { 2708 fRect = rect; 2709 fPaint = paint; 2710 2711 fInfo.push(SkObjectParser::RectToString(rect)); 2712 fInfo.push(SkObjectParser::PaintToString(paint)); 2713 } 2714 2715 void SkDrawRectCommand::execute(SkCanvas* canvas) const { 2716 canvas->drawRect(fRect, fPaint); 2717 } 2718 2719 Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const { 2720 Json::Value result = INHERITED::toJSON(urlDataManager); 2721 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect); 2722 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2723 return result; 2724 } 2725 2726 SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command, 2727 UrlDataManager& urlDataManager) { 2728 SkRect coords; 2729 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords); 2730 SkPaint paint; 2731 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2732 return new SkDrawRectCommand(coords, paint); 2733 } 2734 2735 SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint) 2736 : INHERITED(kDrawRRect_OpType) { 2737 fRRect = rrect; 2738 fPaint = paint; 2739 2740 fInfo.push(SkObjectParser::RRectToString(rrect)); 2741 fInfo.push(SkObjectParser::PaintToString(paint)); 2742 } 2743 2744 void SkDrawRRectCommand::execute(SkCanvas* canvas) const { 2745 canvas->drawRRect(fRRect, fPaint); 2746 } 2747 2748 bool SkDrawRRectCommand::render(SkCanvas* canvas) const { 2749 render_rrect(canvas, fRRect); 2750 return true; 2751 } 2752 2753 Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const { 2754 Json::Value result = INHERITED::toJSON(urlDataManager); 2755 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect); 2756 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2757 return result; 2758 } 2759 2760 SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command, 2761 UrlDataManager& urlDataManager) { 2762 SkRRect coords; 2763 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords); 2764 SkPaint paint; 2765 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2766 return new SkDrawRRectCommand(coords, paint); 2767 } 2768 2769 SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer, 2770 const SkRRect& inner, 2771 const SkPaint& paint) 2772 : INHERITED(kDrawDRRect_OpType) { 2773 fOuter = outer; 2774 fInner = inner; 2775 fPaint = paint; 2776 2777 fInfo.push(SkObjectParser::RRectToString(outer)); 2778 fInfo.push(SkObjectParser::RRectToString(inner)); 2779 fInfo.push(SkObjectParser::PaintToString(paint)); 2780 } 2781 2782 void SkDrawDRRectCommand::execute(SkCanvas* canvas) const { 2783 canvas->drawDRRect(fOuter, fInner, fPaint); 2784 } 2785 2786 bool SkDrawDRRectCommand::render(SkCanvas* canvas) const { 2787 render_drrect(canvas, fOuter, fInner); 2788 return true; 2789 } 2790 2791 Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const { 2792 Json::Value result = INHERITED::toJSON(urlDataManager); 2793 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter); 2794 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner); 2795 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2796 return result; 2797 } 2798 2799 SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command, 2800 UrlDataManager& urlDataManager) { 2801 SkRRect outer; 2802 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer); 2803 SkRRect inner; 2804 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner); 2805 SkPaint paint; 2806 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2807 return new SkDrawDRRectCommand(outer, inner, paint); 2808 } 2809 2810 SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2811 const SkPaint& paint) 2812 : INHERITED(kDrawText_OpType) { 2813 fText = new char[byteLength]; 2814 memcpy(fText, text, byteLength); 2815 fByteLength = byteLength; 2816 fX = x; 2817 fY = y; 2818 fPaint = paint; 2819 2820 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding())); 2821 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: ")); 2822 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: ")); 2823 fInfo.push(SkObjectParser::PaintToString(paint)); 2824 } 2825 2826 void SkDrawTextCommand::execute(SkCanvas* canvas) const { 2827 canvas->drawText(fText, fByteLength, fX, fY, fPaint); 2828 } 2829 2830 Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const { 2831 Json::Value result = INHERITED::toJSON(urlDataManager); 2832 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText, 2833 ((const char*) fText) + fByteLength); 2834 Json::Value coords(Json::arrayValue); 2835 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fX, fY); 2836 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2837 return result; 2838 } 2839 2840 SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command, 2841 UrlDataManager& urlDataManager) { 2842 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString(); 2843 SkPaint paint; 2844 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2845 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS]; 2846 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(), 2847 paint); 2848 } 2849 2850 SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength, 2851 const SkPath& path, const SkMatrix* matrix, 2852 const SkPaint& paint) 2853 : INHERITED(kDrawTextOnPath_OpType) { 2854 fText = new char[byteLength]; 2855 memcpy(fText, text, byteLength); 2856 fByteLength = byteLength; 2857 fPath = path; 2858 if (matrix) { 2859 fMatrix = *matrix; 2860 } else { 2861 fMatrix.setIdentity(); 2862 } 2863 fPaint = paint; 2864 2865 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding())); 2866 fInfo.push(SkObjectParser::PathToString(path)); 2867 if (matrix) { 2868 fInfo.push(SkObjectParser::MatrixToString(*matrix)); 2869 } 2870 fInfo.push(SkObjectParser::PaintToString(paint)); 2871 } 2872 2873 void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const { 2874 canvas->drawTextOnPath(fText, fByteLength, fPath, 2875 fMatrix.isIdentity() ? nullptr : &fMatrix, 2876 fPaint); 2877 } 2878 2879 Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const { 2880 Json::Value result = INHERITED::toJSON(urlDataManager); 2881 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText, 2882 ((const char*) fText) + fByteLength); 2883 Json::Value coords(Json::arrayValue); 2884 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath); 2885 if (!fMatrix.isIdentity()) { 2886 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix); 2887 } 2888 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager); 2889 return result; 2890 } 2891 2892 SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command, 2893 UrlDataManager& urlDataManager) { 2894 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString(); 2895 SkPaint paint; 2896 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 2897 SkPath path; 2898 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path); 2899 SkMatrix* matrixPtr; 2900 SkMatrix matrix; 2901 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) { 2902 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix); 2903 matrixPtr = &matrix; 2904 } 2905 else { 2906 matrixPtr = nullptr; 2907 } 2908 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint); 2909 } 2910 2911 SkDrawVerticesCommand::SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount, 2912 const SkPoint vertices[], const SkPoint texs[], 2913 const SkColor colors[], SkXfermode* xfermode, 2914 const uint16_t indices[], int indexCount, 2915 const SkPaint& paint) 2916 : INHERITED(kDrawVertices_OpType) { 2917 fVmode = vmode; 2918 2919 fVertexCount = vertexCount; 2920 2921 fVertices = new SkPoint[vertexCount]; 2922 memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint)); 2923 2924 if (texs) { 2925 fTexs = new SkPoint[vertexCount]; 2926 memcpy(fTexs, texs, vertexCount * sizeof(SkPoint)); 2927 } else { 2928 fTexs = nullptr; 2929 } 2930 2931 if (colors) { 2932 fColors = new SkColor[vertexCount]; 2933 memcpy(fColors, colors, vertexCount * sizeof(SkColor)); 2934 } else { 2935 fColors = nullptr; 2936 } 2937 2938 fXfermode = xfermode; 2939 if (fXfermode) { 2940 fXfermode->ref(); 2941 } 2942 2943 if (indexCount > 0) { 2944 fIndices = new uint16_t[indexCount]; 2945 memcpy(fIndices, indices, indexCount * sizeof(uint16_t)); 2946 } else { 2947 fIndices = nullptr; 2948 } 2949 2950 fIndexCount = indexCount; 2951 fPaint = paint; 2952 2953 // TODO(chudy) 2954 fInfo.push(SkObjectParser::CustomTextToString("To be implemented.")); 2955 fInfo.push(SkObjectParser::PaintToString(paint)); 2956 } 2957 2958 SkDrawVerticesCommand::~SkDrawVerticesCommand() { 2959 delete [] fVertices; 2960 delete [] fTexs; 2961 delete [] fColors; 2962 SkSafeUnref(fXfermode); 2963 delete [] fIndices; 2964 } 2965 2966 void SkDrawVerticesCommand::execute(SkCanvas* canvas) const { 2967 canvas->drawVertices(fVmode, fVertexCount, fVertices, 2968 fTexs, fColors, fXfermode, fIndices, 2969 fIndexCount, fPaint); 2970 } 2971 2972 SkRestoreCommand::SkRestoreCommand() 2973 : INHERITED(kRestore_OpType) { 2974 fInfo.push(SkObjectParser::CustomTextToString("No Parameters")); 2975 } 2976 2977 void SkRestoreCommand::execute(SkCanvas* canvas) const { 2978 canvas->restore(); 2979 } 2980 2981 SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) { 2982 return new SkRestoreCommand(); 2983 } 2984 2985 SkSaveCommand::SkSaveCommand() 2986 : INHERITED(kSave_OpType) { 2987 } 2988 2989 void SkSaveCommand::execute(SkCanvas* canvas) const { 2990 canvas->save(); 2991 } 2992 2993 SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) { 2994 return new SkSaveCommand(); 2995 } 2996 2997 SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec) 2998 : INHERITED(kSaveLayer_OpType) { 2999 if (rec.fBounds) { 3000 fBounds = *rec.fBounds; 3001 } else { 3002 fBounds.setEmpty(); 3003 } 3004 3005 if (rec.fPaint) { 3006 fPaint = *rec.fPaint; 3007 fPaintPtr = &fPaint; 3008 } else { 3009 fPaintPtr = nullptr; 3010 } 3011 fSaveLayerFlags = rec.fSaveLayerFlags; 3012 3013 if (rec.fBackdrop) { 3014 fBackdrop = rec.fBackdrop; 3015 fBackdrop->ref(); 3016 } else { 3017 fBackdrop = nullptr; 3018 } 3019 3020 if (rec.fBounds) { 3021 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: ")); 3022 } 3023 if (rec.fPaint) { 3024 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint)); 3025 } 3026 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags)); 3027 } 3028 3029 SkSaveLayerCommand::~SkSaveLayerCommand() { 3030 if (fBackdrop != nullptr) { 3031 fBackdrop->unref(); 3032 } 3033 } 3034 3035 void SkSaveLayerCommand::execute(SkCanvas* canvas) const { 3036 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds, 3037 fPaintPtr, 3038 fSaveLayerFlags)); 3039 } 3040 3041 void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const { 3042 canvas->save(); 3043 } 3044 3045 Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const { 3046 Json::Value result = INHERITED::toJSON(urlDataManager); 3047 if (!fBounds.isEmpty()) { 3048 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = make_json_rect(fBounds); 3049 } 3050 if (fPaintPtr != nullptr) { 3051 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, 3052 urlDataManager); 3053 } 3054 if (fBackdrop != nullptr) { 3055 Json::Value jsonBackdrop; 3056 flatten(fBackdrop, &jsonBackdrop, urlDataManager); 3057 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop; 3058 } 3059 if (fSaveLayerFlags != 0) { 3060 SkDebugf("unsupported: saveLayer flags\n"); 3061 SkASSERT(false); 3062 } 3063 return result; 3064 } 3065 3066 SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command, 3067 UrlDataManager& urlDataManager) { 3068 SkCanvas::SaveLayerRec rec; 3069 SkRect bounds; 3070 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) { 3071 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds); 3072 rec.fBounds = &bounds; 3073 } 3074 SkPaint paint; 3075 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) { 3076 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); 3077 rec.fPaint = &paint; 3078 } 3079 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) { 3080 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP]; 3081 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager); 3082 } 3083 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec); 3084 if (rec.fBackdrop != nullptr) { 3085 rec.fBackdrop->unref(); 3086 } 3087 return result; 3088 } 3089 3090 SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix) 3091 : INHERITED(kSetMatrix_OpType) { 3092 fUserMatrix.reset(); 3093 fMatrix = matrix; 3094 fInfo.push(SkObjectParser::MatrixToString(matrix)); 3095 } 3096 3097 void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) { 3098 fUserMatrix = userMatrix; 3099 } 3100 3101 void SkSetMatrixCommand::execute(SkCanvas* canvas) const { 3102 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix); 3103 canvas->setMatrix(temp); 3104 } 3105 3106 Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const { 3107 Json::Value result = INHERITED::toJSON(urlDataManager); 3108 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix); 3109 return result; 3110 } 3111 3112 SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command, 3113 UrlDataManager& urlDataManager) { 3114 SkMatrix matrix; 3115 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix); 3116 return new SkSetMatrixCommand(matrix); 3117 } 3118