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