/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkDrawCommand.h"

#include "SkBlurMaskFilter.h"
#include "SkColorFilter.h"
#include "SkDashPathEffect.h"
#include "SkImageFilter.h"
#include "SkJsonWriteBuffer.h"
#include "SkMaskFilter.h"
#include "SkObjectParser.h"
#include "SkPaintDefaults.h"
#include "SkPathEffect.h"
#include "SkPicture.h"
#include "SkTextBlob.h"
#include "SkTextBlobRunIterator.h"
#include "SkTHash.h"
#include "SkTypeface.h"
#include "SkValidatingReadBuffer.h"
#include "SkWriteBuffer.h"

#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND           "command"
#define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE           "visible"
#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX            "matrix"
#define SKDEBUGCANVAS_ATTRIBUTE_COORDS            "coords"
#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS            "bounds"
#define SKDEBUGCANVAS_ATTRIBUTE_PAINT             "paint"
#define SKDEBUGCANVAS_ATTRIBUTE_OUTER             "outer"
#define SKDEBUGCANVAS_ATTRIBUTE_INNER             "inner"
#define SKDEBUGCANVAS_ATTRIBUTE_MODE              "mode"
#define SKDEBUGCANVAS_ATTRIBUTE_POINTS            "points"
#define SKDEBUGCANVAS_ATTRIBUTE_PATH              "path"
#define SKDEBUGCANVAS_ATTRIBUTE_TEXT              "text"
#define SKDEBUGCANVAS_ATTRIBUTE_COLOR             "color"
#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA             "alpha"
#define SKDEBUGCANVAS_ATTRIBUTE_STYLE             "style"
#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH       "strokeWidth"
#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER       "strokeMiter"
#define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN        "strokeJoin"
#define SKDEBUGCANVAS_ATTRIBUTE_CAP               "cap"
#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS         "antiAlias"
#define SKDEBUGCANVAS_ATTRIBUTE_DITHER            "dither"
#define SKDEBUGCANVAS_ATTRIBUTE_REGION            "region"
#define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP          "op"
#define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE         "edgeStyle"
#define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION      "deviceRegion"
#define SKDEBUGCANVAS_ATTRIBUTE_BLUR              "blur"
#define SKDEBUGCANVAS_ATTRIBUTE_SIGMA             "sigma"
#define SKDEBUGCANVAS_ATTRIBUTE_QUALITY           "quality"
#define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN         "textAlign"
#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE          "textSize"
#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX        "textScaleX"
#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX         "textSkewX"
#define SKDEBUGCANVAS_ATTRIBUTE_DASHING           "dashing"
#define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS         "intervals"
#define SKDEBUGCANVAS_ATTRIBUTE_PHASE             "phase"
#define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE          "fillType"
#define SKDEBUGCANVAS_ATTRIBUTE_VERBS             "verbs"
#define SKDEBUGCANVAS_ATTRIBUTE_NAME              "name"
#define SKDEBUGCANVAS_ATTRIBUTE_DATA              "data"
#define SKDEBUGCANVAS_ATTRIBUTE_VALUES            "values"
#define SKDEBUGCANVAS_ATTRIBUTE_SHADER            "shader"
#define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT        "pathEffect"
#define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER        "maskFilter"
#define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE          "xfermode"
#define SKDEBUGCANVAS_ATTRIBUTE_LOOPER            "looper"
#define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP          "backdrop"
#define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER       "colorfilter"
#define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER       "imagefilter"
#define SKDEBUGCANVAS_ATTRIBUTE_IMAGE             "image"
#define SKDEBUGCANVAS_ATTRIBUTE_BITMAP            "bitmap"
#define SKDEBUGCANVAS_ATTRIBUTE_SRC               "src"
#define SKDEBUGCANVAS_ATTRIBUTE_DST               "dst"
#define SKDEBUGCANVAS_ATTRIBUTE_CENTER            "center"
#define SKDEBUGCANVAS_ATTRIBUTE_STRICT            "strict"
#define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION       "description"
#define SKDEBUGCANVAS_ATTRIBUTE_X                 "x"
#define SKDEBUGCANVAS_ATTRIBUTE_Y                 "y"
#define SKDEBUGCANVAS_ATTRIBUTE_RUNS              "runs"
#define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS         "positions"
#define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS            "glyphs"
#define SKDEBUGCANVAS_ATTRIBUTE_FONT              "font"
#define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE          "typeface"
#define SKDEBUGCANVAS_ATTRIBUTE_CUBICS            "cubics"
#define SKDEBUGCANVAS_ATTRIBUTE_COLORS            "colors"
#define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS     "textureCoords"
#define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY     "filterQuality"

#define SKDEBUGCANVAS_VERB_MOVE                   "move"
#define SKDEBUGCANVAS_VERB_LINE                   "line"
#define SKDEBUGCANVAS_VERB_QUAD                   "quad"
#define SKDEBUGCANVAS_VERB_CUBIC                  "cubic"
#define SKDEBUGCANVAS_VERB_CONIC                  "conic"
#define SKDEBUGCANVAS_VERB_CLOSE                  "close"

#define SKDEBUGCANVAS_STYLE_FILL                  "fill"
#define SKDEBUGCANVAS_STYLE_STROKE                "stroke"
#define SKDEBUGCANVAS_STYLE_STROKEANDFILL         "strokeAndFill"

#define SKDEBUGCANVAS_POINTMODE_POINTS            "points"
#define SKDEBUGCANVAS_POINTMODE_LINES             "lines"
#define SKDEBUGCANVAS_POINTMODE_POLYGON           "polygon"

#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE         "difference"
#define SKDEBUGCANVAS_REGIONOP_INTERSECT          "intersect"
#define SKDEBUGCANVAS_REGIONOP_UNION              "union"
#define SKDEBUGCANVAS_REGIONOP_XOR                "xor"
#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
#define SKDEBUGCANVAS_REGIONOP_REPLACE            "replace"

#define SKDEBUGCANVAS_BLURSTYLE_NORMAL            "normal"
#define SKDEBUGCANVAS_BLURSTYLE_SOLID             "solid"
#define SKDEBUGCANVAS_BLURSTYLE_OUTER             "outer"
#define SKDEBUGCANVAS_BLURSTYLE_INNER             "inner"

#define SKDEBUGCANVAS_BLURQUALITY_LOW             "low"
#define SKDEBUGCANVAS_BLURQUALITY_HIGH            "high"

#define SKDEBUGCANVAS_ALIGN_LEFT                  "left"
#define SKDEBUGCANVAS_ALIGN_CENTER                "center"
#define SKDEBUGCANVAS_ALIGN_RIGHT                 "right"

#define SKDEBUGCANVAS_FILLTYPE_WINDING            "winding"
#define SKDEBUGCANVAS_FILLTYPE_EVENODD            "evenOdd"
#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING     "inverseWinding"
#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD     "inverseEvenOdd"

#define SKDEBUGCANVAS_CAP_BUTT                    "butt"
#define SKDEBUGCANVAS_CAP_ROUND                   "round"
#define SKDEBUGCANVAS_CAP_SQUARE                  "square"

#define SKDEBUGCANVAS_MITER_JOIN                  "miter"
#define SKDEBUGCANVAS_ROUND_JOIN                  "round"
#define SKDEBUGCANVAS_BEVEL_JOIN                  "bevel"

#define SKDEBUGCANVAS_COLORTYPE_ARGB4444          "ARGB4444"
#define SKDEBUGCANVAS_COLORTYPE_RGBA8888          "RGBA8888"
#define SKDEBUGCANVAS_COLORTYPE_BGRA8888          "BGRA8888"
#define SKDEBUGCANVAS_COLORTYPE_565               "565"
#define SKDEBUGCANVAS_COLORTYPE_GRAY8             "Gray8"
#define SKDEBUGCANVAS_COLORTYPE_INDEX8            "Index8"
#define SKDEBUGCANVAS_COLORTYPE_ALPHA8            "Alpha8"

#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE            "opaque"
#define SKDEBUGCANVAS_ALPHATYPE_PREMUL            "premul"
#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL          "unpremul"

#define SKDEBUGCANVAS_FILTERQUALITY_NONE          "none"
#define SKDEBUGCANVAS_FILTERQUALITY_LOW           "low"
#define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM        "medium"
#define SKDEBUGCANVAS_FILTERQUALITY_HIGH          "high"

typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&);

// TODO(chudy): Refactor into non subclass model.

SkDrawCommand::SkDrawCommand(OpType type)
    : fOpType(type)
    , fVisible(true) {
}

SkDrawCommand::~SkDrawCommand() {
    fInfo.deleteAll();
}

const char* SkDrawCommand::GetCommandString(OpType type) {
    switch (type) {
        case kBeginDrawPicture_OpType: return "BeginDrawPicture";
        case kClipPath_OpType: return "ClipPath";
        case kClipRegion_OpType: return "ClipRegion";
        case kClipRect_OpType: return "ClipRect";
        case kClipRRect_OpType: return "ClipRRect";
        case kConcat_OpType: return "Concat";
        case kDrawBitmap_OpType: return "DrawBitmap";
        case kDrawBitmapNine_OpType: return "DrawBitmapNine";
        case kDrawBitmapRect_OpType: return "DrawBitmapRect";
        case kDrawClear_OpType: return "DrawClear";
        case kDrawDRRect_OpType: return "DrawDRRect";
        case kDrawImage_OpType: return "DrawImage";
        case kDrawImageRect_OpType: return "DrawImageRect";
        case kDrawOval_OpType: return "DrawOval";
        case kDrawPaint_OpType: return "DrawPaint";
        case kDrawPatch_OpType: return "DrawPatch";
        case kDrawPath_OpType: return "DrawPath";
        case kDrawPoints_OpType: return "DrawPoints";
        case kDrawPosText_OpType: return "DrawPosText";
        case kDrawPosTextH_OpType: return "DrawPosTextH";
        case kDrawRect_OpType: return "DrawRect";
        case kDrawRRect_OpType: return "DrawRRect";
        case kDrawText_OpType: return "DrawText";
        case kDrawTextBlob_OpType: return "DrawTextBlob";
        case kDrawTextOnPath_OpType: return "DrawTextOnPath";
        case kDrawVertices_OpType: return "DrawVertices";
        case kEndDrawPicture_OpType: return "EndDrawPicture";
        case kRestore_OpType: return "Restore";
        case kSave_OpType: return "Save";
        case kSaveLayer_OpType: return "SaveLayer";
        case kSetMatrix_OpType: return "SetMatrix";
        default:
            SkDebugf("OpType error 0x%08x\n", type);
            SkASSERT(0);
            break;
    }
    SkDEBUGFAIL("DrawType UNUSED\n");
    return nullptr;
}

SkString SkDrawCommand::toString() const {
    return SkString(GetCommandString(fOpType));
}

Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result;
    result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
    result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
    return result;
}

#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
                                            (FROM_JSON) Sk ## name ## Command::fromJSON)
SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
    static SkTHashMap<SkString, FROM_JSON> factories;
    static bool initialized = false;
    if (!initialized) {
        initialized = true;
        INSTALL_FACTORY(Restore);
        INSTALL_FACTORY(ClipPath);
        INSTALL_FACTORY(ClipRegion);
        INSTALL_FACTORY(ClipRect);
        INSTALL_FACTORY(ClipRRect);
        INSTALL_FACTORY(Concat);
        INSTALL_FACTORY(DrawBitmap);
        INSTALL_FACTORY(DrawBitmapRect);
        INSTALL_FACTORY(DrawBitmapNine);
        INSTALL_FACTORY(DrawImage);
        INSTALL_FACTORY(DrawImageRect);
        INSTALL_FACTORY(DrawOval);
        INSTALL_FACTORY(DrawPaint);
        INSTALL_FACTORY(DrawPath);
        INSTALL_FACTORY(DrawPoints);
        INSTALL_FACTORY(DrawText);
        INSTALL_FACTORY(DrawPosText);
        INSTALL_FACTORY(DrawPosTextH);
        INSTALL_FACTORY(DrawTextOnPath);
        INSTALL_FACTORY(DrawTextBlob);

        INSTALL_FACTORY(DrawRect);
        INSTALL_FACTORY(DrawRRect);
        INSTALL_FACTORY(DrawDRRect);
        INSTALL_FACTORY(DrawPatch);
        INSTALL_FACTORY(Save);
        INSTALL_FACTORY(SaveLayer);
        INSTALL_FACTORY(SetMatrix);
    }
    SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
    FROM_JSON* factory = factories.find(name);
    if (factory == nullptr) {
        SkDebugf("no JSON factory for '%s'\n", name.c_str());
        return nullptr;
    }
    return (*factory)(command, urlDataManager);
}

namespace {

void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
    const SkISize& size = canvas->getDeviceSize();

    static const SkScalar kInsetFrac = 0.9f; // Leave a border around object

    canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
    if (bounds.width() > bounds.height()) {
        canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
                      SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
    } else {
        canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
                      SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
    }
    canvas->translate(-bounds.centerX(), -bounds.centerY());
}


void render_path(SkCanvas* canvas, const SkPath& path) {
    canvas->clear(0xFFFFFFFF);

    const SkRect& bounds = path.getBounds();
    if (bounds.isEmpty()) {
        return;
    }

    SkAutoCanvasRestore acr(canvas, true);
    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawPath(path, p);
}

void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
    const SkISize& size = canvas->getDeviceSize();

    SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
    SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();

    if (input.width() > input.height()) {
        yScale *= input.height() / (float) input.width();
    } else {
        xScale *= input.width() / (float) input.height();
    }

    SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
                                  xScale * input.width(),
                                  yScale * input.height());

    static const int kNumBlocks = 8;

    canvas->clear(0xFFFFFFFF);
    SkISize block = {
        canvas->imageInfo().width()/kNumBlocks,
        canvas->imageInfo().height()/kNumBlocks
    };
    for (int y = 0; y < kNumBlocks; ++y) {
        for (int x = 0; x < kNumBlocks; ++x) {
            SkPaint paint;
            paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
            SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
                                        SkIntToScalar(y*block.height()),
                                        SkIntToScalar(block.width()),
                                        SkIntToScalar(block.height()));
            canvas->drawRect(r, paint);
        }
    }

    canvas->drawBitmapRect(input, dst, nullptr);

    if (srcRect) {
        SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
                                    srcRect->fTop * yScale + SK_Scalar1,
                                    srcRect->fRight * xScale + SK_Scalar1,
                                    srcRect->fBottom * yScale + SK_Scalar1);
        SkPaint p;
        p.setColor(SK_ColorRED);
        p.setStyle(SkPaint::kStroke_Style);

        canvas->drawRect(r, p);
    }
}

void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    const SkRect& bounds = rrect.getBounds();

    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawRRect(rrect, p);
    canvas->restore();
}

void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    const SkRect& bounds = outer.getBounds();

    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawDRRect(outer, inner, p);
    canvas->restore();
}

};

Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
    Json::Value result(Json::arrayValue);
    result.append(Json::Value(SkColorGetA(color)));
    result.append(Json::Value(SkColorGetR(color)));
    result.append(Json::Value(SkColorGetG(color)));
    result.append(Json::Value(SkColorGetB(color)));
    return result;
}

Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
    Json::Value result(Json::arrayValue);
    result.append(Json::Value(point.x()));
    result.append(Json::Value(point.y()));
    return result;
}

Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
    Json::Value result(Json::arrayValue);
    result.append(Json::Value(x));
    result.append(Json::Value(y));
    return result;
}

Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
    Json::Value result(Json::arrayValue);
    result.append(Json::Value(rect.left()));
    result.append(Json::Value(rect.top()));
    result.append(Json::Value(rect.right()));
    result.append(Json::Value(rect.bottom()));
    return result;
}

Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
    Json::Value result(Json::arrayValue);
    result.append(Json::Value(rect.left()));
    result.append(Json::Value(rect.top()));
    result.append(Json::Value(rect.right()));
    result.append(Json::Value(rect.bottom()));
    return result;
}

static Json::Value make_json_rrect(const SkRRect& rrect) {
    Json::Value result(Json::arrayValue);
    result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
    return result;
}

Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
    Json::Value result(Json::arrayValue);
    Json::Value row1(Json::arrayValue);
    row1.append(Json::Value(matrix[0]));
    row1.append(Json::Value(matrix[1]));
    row1.append(Json::Value(matrix[2]));
    result.append(row1);
    Json::Value row2(Json::arrayValue);
    row2.append(Json::Value(matrix[3]));
    row2.append(Json::Value(matrix[4]));
    row2.append(Json::Value(matrix[5]));
    result.append(row2);
    Json::Value row3(Json::arrayValue);
    row3.append(Json::Value(matrix[6]));
    row3.append(Json::Value(matrix[7]));
    row3.append(Json::Value(matrix[8]));
    result.append(row3);
    return result;
}

Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
    Json::Value result(Json::objectValue);
    switch (path.getFillType()) {
        case SkPath::kWinding_FillType:
            result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
            break;
        case SkPath::kEvenOdd_FillType:
            result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
            break;
        case SkPath::kInverseWinding_FillType:
            result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
            break;
        case SkPath::kInverseEvenOdd_FillType:
            result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
            break;
    }
    Json::Value verbs(Json::arrayValue);
    SkPath::Iter iter(path, false);
    SkPoint pts[4];
    SkPath::Verb verb;
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kLine_Verb: {
                Json::Value line(Json::objectValue);
                line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
                verbs.append(line);
                break;
            }
            case SkPath::kQuad_Verb: {
                Json::Value quad(Json::objectValue);
                Json::Value coords(Json::arrayValue);
                coords.append(MakeJsonPoint(pts[1]));
                coords.append(MakeJsonPoint(pts[2]));
                quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
                verbs.append(quad);
                break;
            }
            case SkPath::kCubic_Verb: {
                Json::Value cubic(Json::objectValue);
                Json::Value coords(Json::arrayValue);
                coords.append(MakeJsonPoint(pts[1]));
                coords.append(MakeJsonPoint(pts[2]));
                coords.append(MakeJsonPoint(pts[3]));
                cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
                verbs.append(cubic);
                break;
            }
            case SkPath::kConic_Verb: {
                Json::Value conic(Json::objectValue);
                Json::Value coords(Json::arrayValue);
                coords.append(MakeJsonPoint(pts[1]));
                coords.append(MakeJsonPoint(pts[2]));
                coords.append(Json::Value(iter.conicWeight()));
                conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
                verbs.append(conic);
                break;
            }
            case SkPath::kMove_Verb: {
                Json::Value move(Json::objectValue);
                move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
                verbs.append(move);
                break;
            }
            case SkPath::kClose_Verb:
                verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
                break;
            case SkPath::kDone_Verb:
                break;
        }
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
    return result;
}

Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
    return Json::Value("<unimplemented>");
}

static Json::Value make_json_regionop(SkRegion::Op op) {
    switch (op) {
        case SkRegion::kDifference_Op:
            return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
        case SkRegion::kIntersect_Op:
            return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
        case SkRegion::kUnion_Op:
            return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
        case SkRegion::kXOR_Op:
            return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
        case SkRegion::kReverseDifference_Op:
            return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
        case SkRegion::kReplace_Op:
            return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
        default:
            SkASSERT(false);
            return Json::Value("<invalid region op>");
    };
}

static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
    switch (mode) {
        case SkCanvas::kPoints_PointMode:
            return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
        case SkCanvas::kLines_PointMode:
            return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
        case SkCanvas::kPolygon_PointMode:
            return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
        default:
            SkASSERT(false);
            return Json::Value("<invalid point mode>");
    };
}

static void store_scalar(Json::Value* target, const char* key, SkScalar value,
                         SkScalar defaultValue) {
    if (value != defaultValue) {
        (*target)[key] = Json::Value(value);
    }
}

static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
    if (value != defaultValue) {
        (*target)[key] = Json::Value(value);
    }
}

static void encode_data(const void* bytes, size_t count, const char* contentType,
                        UrlDataManager& urlDataManager, Json::Value* target) {
    SkAutoTUnref<SkData> data(SkData::NewWithCopy(bytes, count));
    SkString url = urlDataManager.addData(data, contentType);
    *target = Json::Value(url.c_str());
}

void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
                            UrlDataManager& urlDataManager) {
    SkBinaryWriteBuffer buffer;
    flattenable->flatten(buffer);
    void* data = sk_malloc_throw(buffer.bytesWritten());
    buffer.writeToMemory(data);
    Json::Value jsonData;
    encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
    Json::Value jsonFlattenable;
    jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
    jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;

    SkJsonWriteBuffer jsonBuffer(&urlDataManager);
    flattenable->flatten(jsonBuffer);
    jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();

    (*target) = jsonFlattenable;
    sk_free(data);
}

static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
    SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
    out->write(data, length);
}

void SkDrawCommand::WritePNG(const png_bytep rgba, png_uint_32 width, png_uint_32 height,
                             SkWStream& out) {
    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    SkASSERT(png != nullptr);
    png_infop info_ptr = png_create_info_struct(png);
    SkASSERT(info_ptr != nullptr);
    if (setjmp(png_jmpbuf(png))) {
        SkFAIL("png encode error");
    }
    png_set_IHDR(png, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    png_set_compression_level(png, 1);
    png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
    png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 3);
    for (png_size_t y = 0; y < height; ++y) {
        const png_bytep src = rgba + y * width * 4;
        rows[y] = pixels + y * width * 3;
        // convert from RGBA to RGB
        for (png_size_t x = 0; x < width; ++x) {
            rows[y][x * 3] = src[x * 4];
            rows[y][x * 3 + 1] = src[x * 4 + 1];
            rows[y][x * 3 + 2] = src[x * 4 + 2];
        }
    }
    png_set_filter(png, 0, PNG_NO_FILTERS);
    png_set_rows(png, info_ptr, &rows[0]);
    png_set_write_fn(png, &out, write_png_callback, NULL);
    png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
    png_destroy_write_struct(&png, NULL);
    sk_free(rows);
    sk_free(pixels);
}

bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
                            UrlDataManager& urlDataManager) {
    size_t rowBytes = 4 * image.width();
    SkAutoFree buffer(sk_malloc_throw(rowBytes * image.height()));
    SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
                                            kN32_SkColorType, kPremul_SkAlphaType);
    if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
        SkDebugf("readPixels failed\n");
        return false;
    }
    SkDynamicMemoryWStream out;
    SkDrawCommand::WritePNG((png_bytep) buffer.get(), image.width(), image.height(), out);
    SkData* encoded = out.copyToData();
    Json::Value jsonData;
    encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
    (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
    encoded->unref();
    return true;
}

static const char* color_type_name(SkColorType colorType) {
    switch (colorType) {
        case kARGB_4444_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
        case kRGBA_8888_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
        case kBGRA_8888_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
        case kRGB_565_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_565;
        case kGray_8_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_GRAY8;
        case kIndex_8_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_INDEX8;
        case kAlpha_8_SkColorType:
            return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
        default:
            SkASSERT(false);
            return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
    }
}

static const char* alpha_type_name(SkAlphaType alphaType) {
    switch (alphaType) {
        case kOpaque_SkAlphaType:
            return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
        case kPremul_SkAlphaType:
            return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
        case kUnpremul_SkAlphaType:
            return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
        default:
            SkASSERT(false);
            return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
    }
}

static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
                                    const void** target) {
    UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
    if (urlData == nullptr) {
        SkASSERT(false);
        *target = nullptr;
        return 0;
    }
    *target = urlData->fData->data();
    // cast should be safe for any reasonably-sized object...
    return (Json::ArrayIndex) urlData->fData->size();
}

static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
                                       UrlDataManager& urlDataManager) {
    if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
        return nullptr;
    }
    const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
    SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
    if (factory == nullptr) {
        SkDebugf("no factory for loading '%s'\n", name);
        return nullptr;
    }
    const void* data;
    int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
    SkValidatingReadBuffer buffer(data, size);
    sk_sp<SkFlattenable> result = factory(buffer);
    if (!buffer.isValid()) {
        SkDebugf("invalid buffer loading flattenable\n");
        return nullptr;
    }
    return result.release();
}

static SkColorType colortype_from_name(const char* name) {
    if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
        return kARGB_4444_SkColorType;
    }
    else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
        return kRGBA_8888_SkColorType;
    }
    else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
        return kBGRA_8888_SkColorType;
    }
    else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
        return kRGB_565_SkColorType;
    }
    else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
        return kGray_8_SkColorType;
    }
    else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_INDEX8)) {
        return kIndex_8_SkColorType;
    }
    else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
        return kAlpha_8_SkColorType;
    }
    SkASSERT(false);
    return kN32_SkColorType;
}

static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
    if (bitmap->colorType() == colorType  ) {
        return bitmap;
    }
    SkBitmap* dst = new SkBitmap();
    if (bitmap->copyTo(dst, colorType)) {
        delete bitmap;
        return dst;
    }
    SkASSERT(false);
    delete dst;
    return bitmap;
}

// caller is responsible for freeing return value
static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
    if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
        SkDebugf("invalid bitmap\n");
        return nullptr;
    }
    const void* data;
    int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
    sk_sp<SkData> encoded(SkData::NewWithoutCopy(data, size));
    sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));

    SkAutoTDelete<SkBitmap> bitmap(new SkBitmap());
    if (nullptr != image) {
        if (!image->asLegacyBitmap(bitmap, SkImage::kRW_LegacyBitmapMode)) {
            SkDebugf("image decode failed\n");
            return nullptr;
        }

        if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
            const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
            SkColorType ct = colortype_from_name(ctName);
            if (ct != kIndex_8_SkColorType) {
                bitmap.reset(convert_colortype(bitmap.release(), ct));
            }
        }
        return bitmap.release();
    }
    SkDebugf("image decode failed\n");
    return nullptr;
}

static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
    SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
    if (bitmap == nullptr) {
        return nullptr;
    }
    auto result = SkImage::MakeFromBitmap(*bitmap);
    delete bitmap;
    return result;
}

bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
                            UrlDataManager& urlDataManager) {
    bitmap.lockPixels();
    sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
    bitmap.unlockPixels();
    (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
    (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
    bool success = flatten(*image, target, urlDataManager);
    return success;
}

static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
    SkColor color = paint.getColor();
    if (color != SK_ColorBLACK) {
        Json::Value colorValue(Json::arrayValue);
        colorValue.append(Json::Value(SkColorGetA(color)));
        colorValue.append(Json::Value(SkColorGetR(color)));
        colorValue.append(Json::Value(SkColorGetG(color)));
        colorValue.append(Json::Value(SkColorGetB(color)));
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
    }
}

static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
    SkPaint::Style style = paint.getStyle();
    if (style != SkPaint::kFill_Style) {
        switch (style) {
            case SkPaint::kStroke_Style: {
                Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
                break;
            }
            case SkPaint::kStrokeAndFill_Style: {
                Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
                break;
            }
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
    SkPaint::Cap cap = paint.getStrokeCap();
    if (cap != SkPaint::kDefault_Cap) {
        switch (cap) {
            case SkPaint::kButt_Cap:
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
                break;
            case SkPaint::kRound_Cap:
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
                break;
            case SkPaint::kSquare_Cap:
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
                break;
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
    SkPaint::Join join = paint.getStrokeJoin();
    if (join != SkPaint::kDefault_Join) {
        switch (join) {
            case SkPaint::kMiter_Join:
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
                                                                          SKDEBUGCANVAS_MITER_JOIN);
                break;
            case SkPaint::kRound_Join:
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
                                                                          SKDEBUGCANVAS_ROUND_JOIN);
                break;
            case SkPaint::kBevel_Join:
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
                                                                        SKDEBUGCANVAS_BEVEL_JOIN);
                break;
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
    SkFilterQuality quality = paint.getFilterQuality();
    switch (quality) {
        case kNone_SkFilterQuality:
            break;
        case kLow_SkFilterQuality:
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
                                                                   SKDEBUGCANVAS_FILTERQUALITY_LOW);
            break;
        case kMedium_SkFilterQuality:
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
                                                                SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
            break;
        case kHigh_SkFilterQuality:
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
                                                                  SKDEBUGCANVAS_FILTERQUALITY_HIGH);
            break;
    }
}

static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
                                   UrlDataManager& urlDataManager) {
    SkMaskFilter* maskFilter = paint.getMaskFilter();
    if (maskFilter != nullptr) {
        SkMaskFilter::BlurRec blurRec;
        if (maskFilter->asABlur(&blurRec)) {
            Json::Value blur(Json::objectValue);
            blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
            switch (blurRec.fStyle) {
                case SkBlurStyle::kNormal_SkBlurStyle:
                    blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
                                                                    SKDEBUGCANVAS_BLURSTYLE_NORMAL);
                    break;
                case SkBlurStyle::kSolid_SkBlurStyle:
                    blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
                                                                     SKDEBUGCANVAS_BLURSTYLE_SOLID);
                    break;
                case SkBlurStyle::kOuter_SkBlurStyle:
                    blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
                                                                     SKDEBUGCANVAS_BLURSTYLE_OUTER);
                    break;
                case SkBlurStyle::kInner_SkBlurStyle:
                    blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
                                                                     SKDEBUGCANVAS_BLURSTYLE_INNER);
                    break;
                default:
                    SkASSERT(false);
            }
            switch (blurRec.fQuality) {
                case SkBlurQuality::kLow_SkBlurQuality:
                    blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
                                                                     SKDEBUGCANVAS_BLURQUALITY_LOW);
                    break;
                case SkBlurQuality::kHigh_SkBlurQuality:
                    blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
                                                                    SKDEBUGCANVAS_BLURQUALITY_HIGH);
                    break;
                default:
                    SkASSERT(false);
            }
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
        } else {
            Json::Value jsonMaskFilter;
            SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
        }
    }
}

static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
                                   UrlDataManager& urlDataManager) {
    SkPathEffect* pathEffect = paint.getPathEffect();
    if (pathEffect != nullptr) {
        SkPathEffect::DashInfo dashInfo;
        SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
        if (dashType == SkPathEffect::kDash_DashType) {
            dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
            pathEffect->asADash(&dashInfo);
            Json::Value dashing(Json::objectValue);
            Json::Value intervals(Json::arrayValue);
            for (int32_t i = 0; i < dashInfo.fCount; i++) {
                intervals.append(Json::Value(dashInfo.fIntervals[i]));
            }
            sk_free(dashInfo.fIntervals);
            dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
            dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
        } else {
            Json::Value jsonPathEffect;
            SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
            (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
        }
    }
}

static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
    SkPaint::Align textAlign = paint.getTextAlign();
    if (textAlign != SkPaint::kLeft_Align) {
        switch (textAlign) {
            case SkPaint::kCenter_Align: {
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
                break;
            }
            case SkPaint::kRight_Align: {
                (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
                break;
            }
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
                                 UrlDataManager& urlDataManager) {
    SkTypeface* typeface = paint.getTypeface();
    if (typeface != nullptr) {
        Json::Value jsonTypeface;
        SkDynamicMemoryWStream buffer;
        typeface->serialize(&buffer);
        void* data = sk_malloc_throw(buffer.bytesWritten());
        buffer.copyTo(data);
        Json::Value jsonData;
        encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
                    &jsonData);
        jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
        sk_free(data);
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
    }
}

static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
                               UrlDataManager& urlDataManager) {
    SkFlattenable* shader = paint.getShader();
    if (shader != nullptr) {
        Json::Value jsonShader;
        SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
    }
}

static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target,
                                 UrlDataManager& urlDataManager) {
    SkFlattenable* xfermode = paint.getXfermode();
    if (xfermode != nullptr) {
        Json::Value jsonXfermode;
        SkDrawCommand::flatten(xfermode, &jsonXfermode, urlDataManager);
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
    }
}

static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
                                    UrlDataManager& urlDataManager) {
    SkFlattenable* imageFilter = paint.getImageFilter();
    if (imageFilter != nullptr) {
        Json::Value jsonImageFilter;
        SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
    }
}

static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
                                    UrlDataManager& urlDataManager) {
    SkFlattenable* colorFilter = paint.getColorFilter();
    if (colorFilter != nullptr) {
        Json::Value jsonColorFilter;
        SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
    }
}

static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
                               UrlDataManager& urlDataManager) {
    SkFlattenable* looper = paint.getLooper();
    if (looper != nullptr) {
        Json::Value jsonLooper;
        SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
        (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
    }
}

Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
    Json::Value result(Json::objectValue);
    store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
    store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
                 SkPaintDefaults_MiterLimit);
    store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
    store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
    store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
                 SkPaintDefaults_TextSize);
    store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
    store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
    apply_paint_color(paint, &result);
    apply_paint_style(paint, &result);
    apply_paint_cap(paint, &result);
    apply_paint_join(paint, &result);
    apply_paint_filterquality(paint, &result);
    apply_paint_textalign(paint, &result);
    apply_paint_patheffect(paint, &result, urlDataManager);
    apply_paint_maskfilter(paint, &result, urlDataManager);
    apply_paint_shader(paint, &result, urlDataManager);
    apply_paint_xfermode(paint, &result, urlDataManager);
    apply_paint_looper(paint, &result, urlDataManager);
    apply_paint_imagefilter(paint, &result, urlDataManager);
    apply_paint_colorfilter(paint, &result, urlDataManager);
    apply_paint_typeface(paint, &result, urlDataManager);
    return result;
}

static SkPoint get_json_point(Json::Value point) {
    return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
}

static SkColor get_json_color(Json::Value color) {
    return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
}

static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
        target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
    }
}

static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                      SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
        Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
        SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
        if (shader != nullptr) {
            target->setShader(sk_ref_sp(shader));
        }
    }
}

static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                          SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
        Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
        sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
                                                                       urlDataManager));
        if (pathEffect != nullptr) {
            target->setPathEffect(pathEffect);
        }
    }
}

static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                          SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
        Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
        sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
                                                                       urlDataManager));
        if (maskFilter) {
            target->setMaskFilter(std::move(maskFilter));
        }
    }
}

static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                           SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
        Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
        sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
                                                                          urlDataManager));
        if (colorFilter != nullptr) {
            target->setColorFilter(colorFilter);
        }
    }
}

static void extract_json_paint_xfermode(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                        SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) {
        Json::Value jsonXfermode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE];
        sk_sp<SkXfermode> xfermode((SkXfermode*) load_flattenable(jsonXfermode, urlDataManager));
        if (xfermode != nullptr) {
            target->setXfermode(xfermode);
        }
    }
}

static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                      SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
        Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
        sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
        if (looper != nullptr) {
            target->setLooper(std::move(looper));
        }
    }
}

static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                           SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
        Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
        SkImageFilter* imageFilter = (SkImageFilter*) load_flattenable(jsonImageFilter,
                                                                       urlDataManager);
        if (imageFilter != nullptr) {
            target->setImageFilter(imageFilter);
            imageFilter->unref();
        }
    }
}

static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                        SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
        Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
        Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
        const void* data;
        Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
        SkMemoryStream buffer(data, length);
        target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
    }
}

static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
        const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
        if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
            target->setStyle(SkPaint::kFill_Style);
        }
        else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
            target->setStyle(SkPaint::kStroke_Style);
        }
        else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
            target->setStyle(SkPaint::kStrokeAndFill_Style);
        }
    }
}

static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
        float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
        target->setStrokeWidth(strokeWidth);
    }
}

static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
        float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
        target->setStrokeMiter(strokeMiter);
    }
}

static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
        const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
        if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
            target->setStrokeJoin(SkPaint::kMiter_Join);
        }
        else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
            target->setStrokeJoin(SkPaint::kRound_Join);
        }
        else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
            target->setStrokeJoin(SkPaint::kBevel_Join);
        }
        else {
            SkASSERT(false);
        }
    }
}

static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
        const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
        if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
            target->setStrokeCap(SkPaint::kButt_Cap);
        }
        else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
            target->setStrokeCap(SkPaint::kRound_Cap);
        }
        else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
            target->setStrokeCap(SkPaint::kSquare_Cap);
        }
    }
}

static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
        const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
        if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
            target->setFilterQuality(kNone_SkFilterQuality);
        }
        else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
            target->setFilterQuality(kLow_SkFilterQuality);
        }
        else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
            target->setFilterQuality(kMedium_SkFilterQuality);
        }
        else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
            target->setFilterQuality(kHigh_SkFilterQuality);
        }
    }
}

static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
        target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
    }
}

static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
        target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
    }
}

static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
        Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
        SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
        SkBlurStyle style;
        const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
        if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
            style = SkBlurStyle::kNormal_SkBlurStyle;
        }
        else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
            style = SkBlurStyle::kSolid_SkBlurStyle;
        }
        else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
            style = SkBlurStyle::kOuter_SkBlurStyle;
        }
        else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
            style = SkBlurStyle::kInner_SkBlurStyle;
        }
        else {
            SkASSERT(false);
            style = SkBlurStyle::kNormal_SkBlurStyle;
        }
        SkBlurMaskFilter::BlurFlags flags;
        const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString();
        if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) {
            flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
        }
        else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) {
            flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag;
        }
        else {
            SkASSERT(false);
            flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
        }
        target->setMaskFilter(SkBlurMaskFilter::Make(style, sigma, flags));
    }
}

static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
        Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
        Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
        Json::ArrayIndex count = jsonIntervals.size();
        SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
        for (Json::ArrayIndex i = 0; i < count; i++) {
            intervals[i] = jsonIntervals[i].asFloat();
        }
        SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
        target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
        sk_free(intervals);
    }
}

static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
        SkPaint::Align textAlign;
        const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
        if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
            textAlign = SkPaint::kLeft_Align;
        }
        else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
            textAlign = SkPaint::kCenter_Align;
        }
        else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
            textAlign = SkPaint::kRight_Align;
        }
        else {
            SkASSERT(false);
            textAlign = SkPaint::kLeft_Align;
        }
        target->setTextAlign(textAlign);
    }
}

static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
        float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
        target->setTextSize(textSize);
    }
}

static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
        float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
        target->setTextScaleX(textScaleX);
    }
}

static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
        float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
        target->setTextSkewX(textSkewX);
    }
}

static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
                               SkPaint* result) {
    extract_json_paint_color(paint, result);
    extract_json_paint_shader(paint, urlDataManager, result);
    extract_json_paint_patheffect(paint, urlDataManager, result);
    extract_json_paint_maskfilter(paint, urlDataManager, result);
    extract_json_paint_colorfilter(paint, urlDataManager, result);
    extract_json_paint_xfermode(paint, urlDataManager, result);
    extract_json_paint_looper(paint, urlDataManager, result);
    extract_json_paint_imagefilter(paint, urlDataManager, result);
    extract_json_paint_typeface(paint, urlDataManager, result);
    extract_json_paint_style(paint, result);
    extract_json_paint_strokewidth(paint, result);
    extract_json_paint_strokemiter(paint, result);
    extract_json_paint_strokejoin(paint, result);
    extract_json_paint_cap(paint, result);
    extract_json_paint_filterquality(paint, result);
    extract_json_paint_antialias(paint, result);
    extract_json_paint_dither(paint, result);
    extract_json_paint_blur(paint, result);
    extract_json_paint_dashing(paint, result);
    extract_json_paint_textalign(paint, result);
    extract_json_paint_textsize(paint, result);
    extract_json_paint_textscalex(paint, result);
    extract_json_paint_textskewx(paint, result);
}

static void extract_json_rect(Json::Value& rect, SkRect* result) {
    result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
}

static void extract_json_irect(Json::Value& rect, SkIRect* result) {
    result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
}

static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
    SkVector radii[4] = {
                            { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
                            { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
                            { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
                            { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
                        };
    result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
                                          rrect[0][2].asFloat(), rrect[0][3].asFloat()),
                                          radii);
}

static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
    SkScalar values[] = {
        matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
        matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
        matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
    };
    result->set9(values);
}

static void extract_json_path(Json::Value& path, SkPath* result) {
    const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
    if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
        result->setFillType(SkPath::kWinding_FillType);
    }
    else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
        result->setFillType(SkPath::kEvenOdd_FillType);
    }
    else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
        result->setFillType(SkPath::kInverseWinding_FillType);
    }
    else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
        result->setFillType(SkPath::kInverseEvenOdd_FillType);
    }
    Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
    for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
        Json::Value verb = verbs[i];
        if (verb.isString()) {
            SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
            result->close();
        }
        else {
            if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
                Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
                result->moveTo(move[0].asFloat(), move[1].asFloat());
            }
            else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
                Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
                result->lineTo(line[0].asFloat(), line[1].asFloat());
            }
            else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
                Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
                result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
                               quad[1][0].asFloat(), quad[1][1].asFloat());
            }
            else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
                Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
                result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
                                cubic[1][0].asFloat(), cubic[1][1].asFloat(),
                                cubic[2][0].asFloat(), cubic[2][1].asFloat());
            }
            else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
                Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
                result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
                                conic[1][0].asFloat(), conic[1][1].asFloat(),
                                conic[2].asFloat());
            }
            else {
                SkASSERT(false);
            }
        }
    }
}

SkRegion::Op get_json_regionop(Json::Value& jsonOp) {
    const char* op = jsonOp.asCString();
    if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
        return SkRegion::kDifference_Op;
    }
    else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
        return SkRegion::kIntersect_Op;
    }
    else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
        return SkRegion::kUnion_Op;
    }
    else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
        return SkRegion::kXOR_Op;
    }
    else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
        return SkRegion::kReverseDifference_Op;
    }
    else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
        return SkRegion::kReplace_Op;
    }
    SkASSERT(false);
    return SkRegion::kIntersect_Op;
}

SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kDrawClear_OpType) {
    fColor = color;
    fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
}

void SkClearCommand::execute(SkCanvas* canvas) const {
    canvas->clear(fColor);
}

Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
    return result;
}

 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
    Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
    return new SkClearCommand(get_json_color(color));
}

SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA)
    : INHERITED(kClipPath_OpType) {
    fPath = path;
    fOp = op;
    fDoAA = doAA;

    fInfo.push(SkObjectParser::PathToString(path));
    fInfo.push(SkObjectParser::RegionOpToString(op));
    fInfo.push(SkObjectParser::BoolToString(doAA));
}

void SkClipPathCommand::execute(SkCanvas* canvas) const {
    canvas->clipPath(fPath, fOp, fDoAA);
}

bool SkClipPathCommand::render(SkCanvas* canvas) const {
    render_path(canvas, fPath);
    return true;
}

Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
    result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
    result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
    return result;
}

SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
                                               UrlDataManager& urlDataManager) {
    SkPath path;
    extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
    return new SkClipPathCommand(path, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
                                 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
}

SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op)
    : INHERITED(kClipRegion_OpType) {
    fRegion = region;
    fOp = op;

    fInfo.push(SkObjectParser::RegionToString(region));
    fInfo.push(SkObjectParser::RegionOpToString(op));
}

void SkClipRegionCommand::execute(SkCanvas* canvas) const {
    canvas->clipRegion(fRegion, fOp);
}

Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
    result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
    return result;
}

SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
                                                   UrlDataManager& urlDataManager) {
    SkASSERT(false);
    return nullptr;
}

SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA)
    : INHERITED(kClipRect_OpType) {
    fRect = rect;
    fOp = op;
    fDoAA = doAA;

    fInfo.push(SkObjectParser::RectToString(rect));
    fInfo.push(SkObjectParser::RegionOpToString(op));
    fInfo.push(SkObjectParser::BoolToString(doAA));
}

void SkClipRectCommand::execute(SkCanvas* canvas) const {
    canvas->clipRect(fRect, fOp, fDoAA);
}

Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
    result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
    result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
    return result;
}

SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
                                               UrlDataManager& urlDataManager) {
    SkRect rect;
    extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
    return new SkClipRectCommand(rect, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
                                 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
}

SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA)
    : INHERITED(kClipRRect_OpType) {
    fRRect = rrect;
    fOp = op;
    fDoAA = doAA;

    fInfo.push(SkObjectParser::RRectToString(rrect));
    fInfo.push(SkObjectParser::RegionOpToString(op));
    fInfo.push(SkObjectParser::BoolToString(doAA));
}

void SkClipRRectCommand::execute(SkCanvas* canvas) const {
    canvas->clipRRect(fRRect, fOp, fDoAA);
}

bool SkClipRRectCommand::render(SkCanvas* canvas) const {
    render_rrect(canvas, fRRect);
    return true;
}

Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
    result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
    result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
    return result;
}

SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    SkRRect rrect;
    extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
    return new SkClipRRectCommand(rrect,
                                  get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
                                  command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
}

SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
    : INHERITED(kConcat_OpType) {
    fMatrix = matrix;

    fInfo.push(SkObjectParser::MatrixToString(matrix));
}

void SkConcatCommand::execute(SkCanvas* canvas) const {
    canvas->concat(fMatrix);
}

Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
    return result;
}

SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
    SkMatrix matrix;
    extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
    return new SkConcatCommand(matrix);
}

SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
                                         const SkPaint* paint)
    : INHERITED(kDrawBitmap_OpType) {
    fBitmap = bitmap;
    fLeft = left;
    fTop = top;
    if (paint) {
        fPaint = *paint;
        fPaintPtr = &fPaint;
    } else {
        fPaintPtr = nullptr;
    }

    fInfo.push(SkObjectParser::BitmapToString(bitmap));
    fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
    fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
    if (paint) {
        fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
    canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
}

bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
    render_bitmap(canvas, fBitmap);
    return true;
}

Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value encoded;
    if (flatten(fBitmap, &encoded, urlDataManager)) {
        Json::Value command(Json::objectValue);
        result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
        result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
        if (fPaintPtr != nullptr) {
            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
        }
    }
    return result;
}

SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
                                                   UrlDataManager& urlDataManager) {
    SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
    if (bitmap == nullptr) {
        return nullptr;
    }
    Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
    SkPaint* paintPtr;
    SkPaint paint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
        extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
        paintPtr = &paint;
    }
    else {
        paintPtr = nullptr;
    }
    SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
                                                          point[1].asFloat(), paintPtr);
    delete bitmap;
    return result;
}

SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
                                                 const SkRect& dst, const SkPaint* paint)
    : INHERITED(kDrawBitmapNine_OpType) {
    fBitmap = bitmap;
    fCenter = center;
    fDst = dst;
    if (paint) {
        fPaint = *paint;
        fPaintPtr = &fPaint;
    } else {
        fPaintPtr = nullptr;
    }

    fInfo.push(SkObjectParser::BitmapToString(bitmap));
    fInfo.push(SkObjectParser::IRectToString(center));
    fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    if (paint) {
        fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
    canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
}

bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
    SkRect tmp = SkRect::Make(fCenter);
    render_bitmap(canvas, fBitmap, &tmp);
    return true;
}

Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value encoded;
    if (flatten(fBitmap, &encoded, urlDataManager)) {
        result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
        result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
        if (fPaintPtr != nullptr) {
            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
        }
    }
    return result;
}

SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
                                                           UrlDataManager& urlDataManager) {
    SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
    if (bitmap == nullptr) {
        return nullptr;
    }
    SkIRect center;
    extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
    SkRect dst;
    extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
    SkPaint* paintPtr;
    SkPaint paint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
        extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
        paintPtr = &paint;
    }
    else {
        paintPtr = nullptr;
    }
    SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
    delete bitmap;
    return result;
}

SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
                                                 const SkRect& dst, const SkPaint* paint,
                                                 SkCanvas::SrcRectConstraint constraint)
    : INHERITED(kDrawBitmapRect_OpType) {
    fBitmap = bitmap;
    if (src) {
        fSrc = *src;
    } else {
        fSrc.setEmpty();
    }
    fDst = dst;

    if (paint) {
        fPaint = *paint;
        fPaintPtr = &fPaint;
    } else {
        fPaintPtr = nullptr;
    }
    fConstraint = constraint;

    fInfo.push(SkObjectParser::BitmapToString(bitmap));
    if (src) {
        fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
    }
    fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    if (paint) {
        fInfo.push(SkObjectParser::PaintToString(*paint));
    }
    fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
}

void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
    canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
}

bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
    render_bitmap(canvas, fBitmap, this->srcRect());
    return true;
}

Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value encoded;
    if (flatten(fBitmap, &encoded, urlDataManager)) {
        result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
        if (!fSrc.isEmpty()) {
            result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
        }
        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
        if (fPaintPtr != nullptr) {
            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
        }
        if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
            result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
        }
    }
    return result;
}

SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
                                                           UrlDataManager& urlDataManager) {
    SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
    if (bitmap == nullptr) {
        return nullptr;
    }
    SkRect dst;
    extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
    SkPaint* paintPtr;
    SkPaint paint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
        extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
        paintPtr = &paint;
    }
    else {
        paintPtr = nullptr;
    }
    SkCanvas::SrcRectConstraint constraint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
        command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
        constraint = SkCanvas::kStrict_SrcRectConstraint;
    }
    else {
        constraint = SkCanvas::kFast_SrcRectConstraint;
    }
    SkRect* srcPtr;
    SkRect src;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
        extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
        srcPtr = &src;
    }
    else {
        srcPtr = nullptr;
    }
    SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
                                                                  constraint);
    delete bitmap;
    return result;
}

SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
                                       const SkPaint* paint)
    : INHERITED(kDrawImage_OpType)
    , fImage(SkRef(image))
    , fLeft(left)
    , fTop(top) {

    fInfo.push(SkObjectParser::ImageToString(image));
    fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
    fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));

    if (paint) {
        fPaint.set(*paint);
        fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void SkDrawImageCommand::execute(SkCanvas* canvas) const {
    canvas->drawImage(fImage, fLeft, fTop, fPaint.getMaybeNull());
}

bool SkDrawImageCommand::render(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->clear(0xFFFFFFFF);

    xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
                                                       SkIntToScalar(fImage->width()),
                                                       SkIntToScalar(fImage->height())));
    this->execute(canvas);
    return true;
}

Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value encoded;
    if (flatten(*fImage, &encoded, urlDataManager)) {
        result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
        result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
        if (fPaint.isValid()) {
            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
        }
    }
    return result;
}

SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
    if (image == nullptr) {
        return nullptr;
    }
    Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
    SkPaint* paintPtr;
    SkPaint paint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
        extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
        paintPtr = &paint;
    }
    else {
        paintPtr = nullptr;
    }
    SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
                                                        point[1].asFloat(), paintPtr);
    return result;
}

SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
                                               const SkRect& dst, const SkPaint* paint,
                                               SkCanvas::SrcRectConstraint constraint)
    : INHERITED(kDrawImageRect_OpType)
    , fImage(SkRef(image))
    , fDst(dst)
    , fConstraint(constraint) {

    if (src) {
        fSrc.set(*src);
    }

    if (paint) {
        fPaint.set(*paint);
    }

    fInfo.push(SkObjectParser::ImageToString(image));
    if (src) {
        fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
    }
    fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    if (paint) {
        fInfo.push(SkObjectParser::PaintToString(*paint));
    }
    fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
}

void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
    canvas->legacy_drawImageRect(fImage, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(),
                                 fConstraint);
}

bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->clear(0xFFFFFFFF);

    xlate_and_scale_to_bounds(canvas, fDst);

    this->execute(canvas);
    return true;
}

Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value encoded;
    if (flatten(*fImage.get(), &encoded, urlDataManager)) {
        result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
        if (fSrc.isValid()) {
            result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
        }
        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
        if (fPaint.isValid()) {
            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
        }
        if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
            result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
        }
    }
    return result;
}

SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
                                                         UrlDataManager& urlDataManager) {
    sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
    if (image == nullptr) {
        return nullptr;
    }
    SkRect dst;
    extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
    SkPaint* paintPtr;
    SkPaint paint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
        extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
        paintPtr = &paint;
    }
    else {
        paintPtr = nullptr;
    }
    SkCanvas::SrcRectConstraint constraint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
        command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
        constraint = SkCanvas::kStrict_SrcRectConstraint;
    }
    else {
        constraint = SkCanvas::kFast_SrcRectConstraint;
    }
    SkRect* srcPtr;
    SkRect src;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
        extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
        srcPtr = &src;
    }
    else {
        srcPtr = nullptr;
    }
    SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
                                                                constraint);
    return result;
}

SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
    : INHERITED(kDrawOval_OpType) {
    fOval = oval;
    fPaint = paint;

    fInfo.push(SkObjectParser::RectToString(oval));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
    canvas->drawOval(fOval, fPaint);
}

bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    xlate_and_scale_to_bounds(canvas, fOval);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawOval(fOval, p);
    canvas->restore();

    return true;
}

Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
                                               UrlDataManager& urlDataManager) {
    SkRect coords;
    extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawOvalCommand(coords, paint);
}

SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
    : INHERITED(kDrawPaint_OpType) {
    fPaint = paint;

    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
    canvas->drawPaint(fPaint);
}

bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->drawPaint(fPaint);
    return true;
}

Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawPaintCommand(paint);
}

SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
    : INHERITED(kDrawPath_OpType) {
    fPath = path;
    fPaint = paint;

    fInfo.push(SkObjectParser::PathToString(path));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawPathCommand::execute(SkCanvas* canvas) const {
    canvas->drawPath(fPath, fPaint);
}

bool SkDrawPathCommand::render(SkCanvas* canvas) const {
    render_path(canvas, fPath);
    return true;
}

Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
                                               UrlDataManager& urlDataManager) {
    SkPath path;
    extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawPathCommand(path, paint);
}

SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
                                                     const SkMatrix* matrix,
                                                     const SkPaint* paint)
    : INHERITED(kBeginDrawPicture_OpType)
    , fPicture(SkRef(picture)) {

    SkString* str = new SkString;
    str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
                 picture->cullRect().fLeft, picture->cullRect().fTop,
                 picture->cullRect().fRight, picture->cullRect().fBottom);
    fInfo.push(str);

    if (matrix) {
        fMatrix.set(*matrix);
        fInfo.push(SkObjectParser::MatrixToString(*matrix));
    }

    if (paint) {
        fPaint.set(*paint);
        fInfo.push(SkObjectParser::PaintToString(*paint));
    }

}

void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
    if (fPaint.isValid()) {
        SkRect bounds = fPicture->cullRect();
        if (fMatrix.isValid()) {
            fMatrix.get()->mapRect(&bounds);
        }
        canvas->saveLayer(&bounds, fPaint.get());
    }

    if (fMatrix.isValid()) {
        if (!fPaint.isValid()) {
            canvas->save();
        }
        canvas->concat(*fMatrix.get());
    }
}

bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    xlate_and_scale_to_bounds(canvas, fPicture->cullRect());

    canvas->drawPicture(fPicture.get());

    canvas->restore();

    return true;
}

SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
    : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }

void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
    if (fRestore) {
        canvas->restore();
    }
}

SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
                                         const SkPoint pts[], const SkPaint& paint)
    : INHERITED(kDrawPoints_OpType) {
    fMode = mode;
    fCount = count;
    fPts = new SkPoint[count];
    memcpy(fPts, pts, count * sizeof(SkPoint));
    fPaint = paint;

    fInfo.push(SkObjectParser::PointsToString(pts, count));
    fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
                                              "Points: "));
    fInfo.push(SkObjectParser::PointModeToString(mode));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
    canvas->drawPoints(fMode, fCount, fPts, fPaint);
}

bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    SkRect bounds;

    bounds.setEmpty();
    for (unsigned int i = 0; i < fCount; ++i) {
        bounds.growToInclude(fPts[i].fX, fPts[i].fY);
    }

    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawPoints(fMode, fCount, fPts, p);
    canvas->restore();

    return true;
}

Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
    Json::Value points(Json::arrayValue);
    for (size_t i = 0; i < fCount; i++) {
        points.append(MakeJsonPoint(fPts[i]));
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
                                                   UrlDataManager& urlDataManager) {
    SkCanvas::PointMode mode;
    const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
    if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
        mode = SkCanvas::kPoints_PointMode;
    }
    else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
        mode = SkCanvas::kLines_PointMode;
    }
    else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
        mode = SkCanvas::kPolygon_PointMode;
    }
    else {
        SkASSERT(false);
        return nullptr;
    }
    Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
    int count = (int) jsonPoints.size();
    SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
    for (int i = 0; i < count; i++) {
        points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
    }
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
    sk_free(points);
    return result;
}

SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
                                           const SkPoint pos[], const SkPaint& paint)
    : INHERITED(kDrawPosText_OpType) {
    size_t numPts = paint.countText(text, byteLength);

    fText = new char[byteLength];
    memcpy(fText, text, byteLength);
    fByteLength = byteLength;

    fPos = new SkPoint[numPts];
    memcpy(fPos, pos, numPts * sizeof(SkPoint));

    fPaint = paint;

    fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    // TODO(chudy): Test that this works.
    fInfo.push(SkObjectParser::PointsToString(pos, 1));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
    canvas->drawPosText(fText, fByteLength, fPos, fPaint);
}

Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
                                                       ((const char*) fText) + fByteLength);
    Json::Value coords(Json::arrayValue);
    size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
    for (size_t i = 0; i < numCoords; i++) {
        coords.append(MakeJsonPoint(fPos[i]));
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
                                                     UrlDataManager& urlDataManager) {
    const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
    int count = (int) coords.size();
    SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
    for (int i = 0; i < count; i++) {
        points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
    }
    return new SkDrawPosTextCommand(text, strlen(text), points, paint);
}

SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
                                             const SkScalar xpos[], SkScalar constY,
                                             const SkPaint& paint)
    : INHERITED(kDrawPosTextH_OpType) {
    size_t numPts = paint.countText(text, byteLength);

    fText = new char[byteLength];
    memcpy(fText, text, byteLength);
    fByteLength = byteLength;

    fXpos = new SkScalar[numPts];
    memcpy(fXpos, xpos, numPts * sizeof(SkScalar));

    fConstY = constY;
    fPaint = paint;

    fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
    fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
    canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
}

Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
                                                       ((const char*) fText) + fByteLength);
    result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
    Json::Value xpos(Json::arrayValue);
    size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
    for (size_t i = 0; i < numXpos; i++) {
        xpos.append(Json::Value(fXpos[i]));
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
                                                       UrlDataManager& urlDataManager) {
    const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
    int count = (int) jsonXpos.size();
    SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
    for (int i = 0; i < count; i++) {
        xpos[i] = jsonXpos[i].asFloat();
    }
    SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
    return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
}

static const char* gPositioningLabels[] = {
    "kDefault_Positioning",
    "kHorizontal_Positioning",
    "kFull_Positioning",
};

SkDrawTextBlobCommand::SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                             const SkPaint& paint)
    : INHERITED(kDrawTextBlob_OpType)
    , fBlob(SkRef(blob))
    , fXPos(x)
    , fYPos(y)
    , fPaint(paint) {

    SkAutoTDelete<SkString> runsStr(new SkString);
    fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
    fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
    fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
    fInfo.push(runsStr);
    fInfo.push(SkObjectParser::PaintToString(paint));

    unsigned runs = 0;
    SkPaint runPaint(paint);
    SkTextBlobRunIterator iter(blob);
    while (!iter.done()) {
        SkAutoTDelete<SkString> tmpStr(new SkString);
        tmpStr->printf("==== Run [%d] ====", runs++);
        fInfo.push(tmpStr.release());

        fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
        tmpStr.reset(new SkString("GlyphPositioning: "));
        tmpStr->append(gPositioningLabels[iter.positioning()]);
        fInfo.push(tmpStr.release());

        iter.applyFontToPaint(&runPaint);
        fInfo.push(SkObjectParser::PaintToString(runPaint));

        iter.next();
    }

    runsStr->printf("Runs: %d", runs);
    // runStr is owned by fInfo at this point.
    runsStr.release();
}

void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
    canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
}

bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
    canvas->clear(SK_ColorWHITE);
    canvas->save();

    SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
    xlate_and_scale_to_bounds(canvas, bounds);

    canvas->drawTextBlob(fBlob.get(), fXPos, fYPos, fPaint);

    canvas->restore();

    return true;
}

Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value runs(Json::arrayValue);
    SkTextBlobRunIterator iter(fBlob.get());
    while (!iter.done()) {
        Json::Value run(Json::objectValue);
        Json::Value jsonPositions(Json::arrayValue);
        Json::Value jsonGlyphs(Json::arrayValue);
        const SkScalar* iterPositions = iter.pos();
        const uint16_t* iterGlyphs = iter.glyphs();
        for (uint32_t i = 0; i < iter.glyphCount(); i++) {
            switch (iter.positioning()) {
                case SkTextBlob::kFull_Positioning:
                    jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
                                                       iterPositions[i * 2 + 1]));
                    break;
                case SkTextBlob::kHorizontal_Positioning:
                    jsonPositions.append(Json::Value(iterPositions[i]));
                    break;
                case SkTextBlob::kDefault_Positioning:
                    break;
            }
            jsonGlyphs.append(Json::Value(iterGlyphs[i]));
        }
        if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
            run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
        }
        run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
        SkPaint fontPaint;
        iter.applyFontToPaint(&fontPaint);
        run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
        run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
        runs.append(run);
        iter.next();
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
    result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
    result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
                                                       UrlDataManager& urlDataManager) {
    SkTextBlobBuilder builder;
    Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
    for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
        Json::Value run = runs[i];
        SkPaint font;
        font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
        extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
        Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
        int count = glyphs.size();
        Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
        SkScalar x = coords[0].asFloat();
        SkScalar y = coords[1].asFloat();
        if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
            Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
            if (positions.size() > 0 && positions[0].isNumeric()) {
                SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y);
                for (int j = 0; j < count; j++) {
                    buffer.glyphs[j] = glyphs[j].asUInt();
                    buffer.pos[j] = positions[j].asFloat();
                }
            }
            else {
                SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count);
                for (int j = 0; j < count; j++) {
                    buffer.glyphs[j] = glyphs[j].asUInt();
                    buffer.pos[j * 2] = positions[j][0].asFloat();
                    buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
                }
            }
        }
        else {
            SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y);
            for (int j = 0; j < count; j++) {
                buffer.glyphs[j] = glyphs[j].asUInt();
            }
        }
    }
    SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
    SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawTextBlobCommand(builder.build(), x, y, paint);
}

SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
                                       const SkPoint texCoords[4], SkXfermode* xfermode,
                                       const SkPaint& paint)
    : INHERITED(kDrawPatch_OpType) {
    memcpy(fCubics, cubics, sizeof(fCubics));
    if (colors != nullptr) {
        memcpy(fColors, colors, sizeof(fColors));
        fColorsPtr = fColors;
    } else {
        fColorsPtr = nullptr;
    }
    if (texCoords != nullptr) {
        memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
        fTexCoordsPtr = fTexCoords;
    } else {
        fTexCoordsPtr = nullptr;
    }
    if (xfermode != nullptr) {
        fXfermode.reset(SkRef(xfermode));
    }
    fPaint = paint;

    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
    canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fXfermode, fPaint);
}

Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    Json::Value cubics = Json::Value(Json::arrayValue);
    for (int i = 0; i < 12; i++) {
        cubics.append(MakeJsonPoint(fCubics[i]));
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
    if (fColorsPtr != nullptr) {
        Json::Value colors = Json::Value(Json::arrayValue);
        for (int i = 0; i < 4; i++) {
            colors.append(MakeJsonColor(fColorsPtr[i]));
        }
        result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
    }
    if (fTexCoordsPtr != nullptr) {
        Json::Value texCoords = Json::Value(Json::arrayValue);
        for (int i = 0; i < 4; i++) {
            texCoords.append(MakeJsonPoint(fTexCoords[i]));
        }
        result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
    }
    if (fXfermode.get() != nullptr) {
        Json::Value jsonXfermode;
        flatten(fXfermode, &jsonXfermode, urlDataManager);
        result[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
    }
    return result;
}

SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
    SkPoint cubics[12];
    for (int i = 0; i < 12; i++) {
        cubics[i] = get_json_point(jsonCubics[i]);
    }
    SkColor* colorsPtr;
    SkColor colors[4];
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
        Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
        for (int i = 0; i < 4; i++) {
            colors[i] = get_json_color(jsonColors[i]);
        }
        colorsPtr = colors;
    }
    else {
        colorsPtr = nullptr;
    }
    SkPoint* texCoordsPtr;
    SkPoint texCoords[4];
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
        Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
        for (int i = 0; i < 4; i++) {
            texCoords[i] = get_json_point(jsonTexCoords[i]);
        }
        texCoordsPtr = texCoords;
    }
    else {
        texCoordsPtr = nullptr;
    }
    SkAutoTUnref<SkXfermode> xfermode;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) {
        Json::Value jsonXfermode = command[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE];
        xfermode.reset((SkXfermode*) load_flattenable(jsonXfermode, urlDataManager));
    }
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, xfermode, paint);
}

SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
    : INHERITED(kDrawRect_OpType) {
    fRect = rect;
    fPaint = paint;

    fInfo.push(SkObjectParser::RectToString(rect));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawRectCommand::execute(SkCanvas* canvas) const {
    canvas->drawRect(fRect, fPaint);
}

Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
                                               UrlDataManager& urlDataManager) {
    SkRect coords;
    extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawRectCommand(coords, paint);
}

SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
    : INHERITED(kDrawRRect_OpType) {
    fRRect = rrect;
    fPaint = paint;

    fInfo.push(SkObjectParser::RRectToString(rrect));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
    canvas->drawRRect(fRRect, fPaint);
}

bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
    render_rrect(canvas, fRRect);
    return true;
}

Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    SkRRect coords;
    extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawRRectCommand(coords, paint);
}

SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
                                         const SkRRect& inner,
                                         const SkPaint& paint)
    : INHERITED(kDrawDRRect_OpType) {
    fOuter = outer;
    fInner = inner;
    fPaint = paint;

    fInfo.push(SkObjectParser::RRectToString(outer));
    fInfo.push(SkObjectParser::RRectToString(inner));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
    canvas->drawDRRect(fOuter, fInner, fPaint);
}

bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
    render_drrect(canvas, fOuter, fInner);
    return true;
}

Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
    result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
                                                   UrlDataManager& urlDataManager) {
    SkRRect outer;
    extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
    SkRRect inner;
    extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    return new SkDrawDRRectCommand(outer, inner, paint);
}

SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
                                     const SkPaint& paint)
    : INHERITED(kDrawText_OpType) {
    fText = new char[byteLength];
    memcpy(fText, text, byteLength);
    fByteLength = byteLength;
    fX = x;
    fY = y;
    fPaint = paint;

    fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
    fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawTextCommand::execute(SkCanvas* canvas) const {
    canvas->drawText(fText, fByteLength, fX, fY, fPaint);
}

Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
                                                       ((const char*) fText) + fByteLength);
    Json::Value coords(Json::arrayValue);
    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
                                               UrlDataManager& urlDataManager) {
    const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
    return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
                                 paint);
}

SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
                                                 const SkPath& path, const SkMatrix* matrix,
                                                 const SkPaint& paint)
    : INHERITED(kDrawTextOnPath_OpType) {
    fText = new char[byteLength];
    memcpy(fText, text, byteLength);
    fByteLength = byteLength;
    fPath = path;
    if (matrix) {
        fMatrix = *matrix;
    } else {
        fMatrix.setIdentity();
    }
    fPaint = paint;

    fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    fInfo.push(SkObjectParser::PathToString(path));
    if (matrix) {
        fInfo.push(SkObjectParser::MatrixToString(*matrix));
    }
    fInfo.push(SkObjectParser::PaintToString(paint));
}

void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
    canvas->drawTextOnPath(fText, fByteLength, fPath,
                           fMatrix.isIdentity() ? nullptr : &fMatrix,
                           fPaint);
}

Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
                                                       ((const char*) fText) + fByteLength);
    Json::Value coords(Json::arrayValue);
    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
    if (!fMatrix.isIdentity()) {
        result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
    }
    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
    return result;
}

SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
                                                           UrlDataManager& urlDataManager) {
    const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
    SkPaint paint;
    extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
    SkPath path;
    extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
    SkMatrix* matrixPtr;
    SkMatrix matrix;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
        extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
        matrixPtr = &matrix;
    }
    else {
        matrixPtr = nullptr;
    }
    return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
}

SkDrawVerticesCommand::SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount,
                                             const SkPoint vertices[], const SkPoint texs[],
                                             const SkColor colors[], SkXfermode* xfermode,
                                             const uint16_t indices[], int indexCount,
                                             const SkPaint& paint)
    : INHERITED(kDrawVertices_OpType) {
    fVmode = vmode;

    fVertexCount = vertexCount;

    fVertices = new SkPoint[vertexCount];
    memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint));

    if (texs) {
        fTexs = new SkPoint[vertexCount];
        memcpy(fTexs, texs, vertexCount * sizeof(SkPoint));
    } else {
        fTexs = nullptr;
    }

    if (colors) {
        fColors = new SkColor[vertexCount];
        memcpy(fColors, colors, vertexCount * sizeof(SkColor));
    } else {
        fColors = nullptr;
    }

    fXfermode = xfermode;
    if (fXfermode) {
        fXfermode->ref();
    }

    if (indexCount > 0) {
        fIndices = new uint16_t[indexCount];
        memcpy(fIndices, indices, indexCount * sizeof(uint16_t));
    } else {
        fIndices = nullptr;
    }

    fIndexCount = indexCount;
    fPaint = paint;

    // TODO(chudy)
    fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
    fInfo.push(SkObjectParser::PaintToString(paint));
}

SkDrawVerticesCommand::~SkDrawVerticesCommand() {
    delete [] fVertices;
    delete [] fTexs;
    delete [] fColors;
    SkSafeUnref(fXfermode);
    delete [] fIndices;
}

void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
    canvas->drawVertices(fVmode, fVertexCount, fVertices,
                         fTexs, fColors, fXfermode, fIndices,
                         fIndexCount, fPaint);
}

SkRestoreCommand::SkRestoreCommand()
    : INHERITED(kRestore_OpType) {
    fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
}

void SkRestoreCommand::execute(SkCanvas* canvas) const {
    canvas->restore();
}

SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
    return new SkRestoreCommand();
}

SkSaveCommand::SkSaveCommand()
    : INHERITED(kSave_OpType) {
}

void SkSaveCommand::execute(SkCanvas* canvas) const {
    canvas->save();
}

SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
    return new SkSaveCommand();
}

SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
    : INHERITED(kSaveLayer_OpType) {
    if (rec.fBounds) {
        fBounds = *rec.fBounds;
    } else {
        fBounds.setEmpty();
    }

    if (rec.fPaint) {
        fPaint = *rec.fPaint;
        fPaintPtr = &fPaint;
    } else {
        fPaintPtr = nullptr;
    }
    fSaveLayerFlags = rec.fSaveLayerFlags;

    if (rec.fBackdrop) {
        fBackdrop = rec.fBackdrop;
        fBackdrop->ref();
    } else {
        fBackdrop = nullptr;
    }

    if (rec.fBounds) {
        fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
    }
    if (rec.fPaint) {
        fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
    }
    fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
}

SkSaveLayerCommand::~SkSaveLayerCommand() {
    if (fBackdrop != nullptr) {
        fBackdrop->unref();
    }
}

void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
    canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
                                             fPaintPtr,
                                             fSaveLayerFlags));
}

void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
    canvas->save();
}

Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    if (!fBounds.isEmpty()) {
        result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
    }
    if (fPaintPtr != nullptr) {
        result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
                                                                urlDataManager);
    }
    if (fBackdrop != nullptr) {
        Json::Value jsonBackdrop;
        flatten(fBackdrop, &jsonBackdrop, urlDataManager);
        result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
    }
    if (fSaveLayerFlags != 0) {
        SkDebugf("unsupported: saveLayer flags\n");
        SkASSERT(false);
    }
    return result;
}

SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    SkCanvas::SaveLayerRec rec;
    SkRect bounds;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
        extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
        rec.fBounds = &bounds;
    }
    SkPaint paint;
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
        extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
        rec.fPaint = &paint;
    }
    if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
        Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
        rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
    }
    SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
    if (rec.fBackdrop != nullptr) {
        rec.fBackdrop->unref();
    }
    return result;
}

SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
    : INHERITED(kSetMatrix_OpType) {
    fUserMatrix.reset();
    fMatrix = matrix;
    fInfo.push(SkObjectParser::MatrixToString(matrix));
}

void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
    fUserMatrix = userMatrix;
}

void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
    SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
    canvas->setMatrix(temp);
}

Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
    Json::Value result = INHERITED::toJSON(urlDataManager);
    result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
    return result;
}

SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
                                                 UrlDataManager& urlDataManager) {
    SkMatrix matrix;
    extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
    return new SkSetMatrixCommand(matrix);
}
