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