Home | History | Annotate | Download | only in debugger
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkDrawCommand.h"
     11 #include "SkObjectParser.h"
     12 
     13 // TODO(chudy): Refactor into non subclass model.
     14 
     15 SkDrawCommand::SkDrawCommand(DrawType type)
     16     : fDrawType(type)
     17     , fOffset(0)
     18     , fVisible(true) {
     19 }
     20 
     21 SkDrawCommand::SkDrawCommand() {
     22     fOffset = 0;
     23     fVisible = true;
     24 }
     25 
     26 SkDrawCommand::~SkDrawCommand() {
     27     fInfo.deleteAll();
     28 }
     29 
     30 const char* SkDrawCommand::GetCommandString(DrawType type) {
     31     switch (type) {
     32         case UNUSED: SkDEBUGFAIL("DrawType UNUSED\n"); break;
     33         case DRAW_CLEAR: return "Clear";
     34         case CLIP_PATH: return "Clip Path";
     35         case CLIP_REGION: return "Clip Region";
     36         case CLIP_RECT: return "Clip Rect";
     37         case CLIP_RRECT: return "Clip RRect";
     38         case CONCAT: return "Concat";
     39         case DRAW_BITMAP: return "Draw Bitmap";
     40         case DRAW_BITMAP_MATRIX: return "Draw Bitmap Matrix";
     41         case DRAW_BITMAP_NINE: return "Draw Bitmap Nine";
     42         case DRAW_BITMAP_RECT_TO_RECT: return "Draw Bitmap Rect";
     43         case DRAW_DATA: return "Draw Data";
     44         case DRAW_OVAL: return "Draw Oval";
     45         case DRAW_PAINT: return "Draw Paint";
     46         case DRAW_PATH: return "Draw Path";
     47         case DRAW_PICTURE: return "Draw Picture";
     48         case DRAW_POINTS: return "Draw Points";
     49         case DRAW_POS_TEXT: return "Draw Pos Text";
     50         case DRAW_POS_TEXT_H: return "Draw Pos Text H";
     51         case DRAW_RECT: return "Draw Rect";
     52         case DRAW_RRECT: return "Draw RRect";
     53         case DRAW_SPRITE: return "Draw Sprite";
     54         case DRAW_TEXT: return "Draw Text";
     55         case DRAW_TEXT_ON_PATH: return "Draw Text On Path";
     56         case DRAW_VERTICES: return "Draw Vertices";
     57         case RESTORE: return "Restore";
     58         case ROTATE: return "Rotate";
     59         case SAVE: return "Save";
     60         case SAVE_LAYER: return "Save Layer";
     61         case SCALE: return "Scale";
     62         case SET_MATRIX: return "Set Matrix";
     63         case SKEW: return "Skew";
     64         case TRANSLATE: return "Translate";
     65         case NOOP: return "NoOp";
     66         case BEGIN_COMMENT_GROUP: return "BeginCommentGroup";
     67         case COMMENT: return "Comment";
     68         case END_COMMENT_GROUP: return "EndCommentGroup";
     69         case DRAW_DRRECT: return "Draw DRRect";
     70         case PUSH_CULL: return "PushCull";
     71         case POP_CULL: return "PopCull";
     72         default:
     73             SkDebugf("DrawType error 0x%08x\n", type);
     74             SkASSERT(0);
     75             break;
     76     }
     77     SkDEBUGFAIL("DrawType UNUSED\n");
     78     return NULL;
     79 }
     80 
     81 SkString SkDrawCommand::toString() {
     82     return SkString(GetCommandString(fDrawType));
     83 }
     84 
     85 SkClearCommand::SkClearCommand(SkColor color) : INHERITED(DRAW_CLEAR) {
     86     fColor = color;
     87     fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
     88 }
     89 
     90 void SkClearCommand::execute(SkCanvas* canvas) {
     91     canvas->clear(fColor);
     92 }
     93 
     94 namespace {
     95 
     96 void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
     97     const SkISize& size = canvas->getDeviceSize();
     98 
     99     static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
    100 
    101     canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
    102     if (bounds.width() > bounds.height()) {
    103         canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
    104                       SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
    105     } else {
    106         canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
    107                       SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
    108     }
    109     canvas->translate(-bounds.centerX(), -bounds.centerY());
    110 }
    111 
    112 
    113 void render_path(SkCanvas* canvas, const SkPath& path) {
    114     canvas->clear(0xFFFFFFFF);
    115     canvas->save();
    116 
    117     const SkRect& bounds = path.getBounds();
    118 
    119     xlate_and_scale_to_bounds(canvas, bounds);
    120 
    121     SkPaint p;
    122     p.setColor(SK_ColorBLACK);
    123     p.setStyle(SkPaint::kStroke_Style);
    124 
    125     canvas->drawPath(path, p);
    126     canvas->restore();
    127 }
    128 
    129 void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = NULL) {
    130     const SkISize& size = canvas->getDeviceSize();
    131 
    132     SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
    133     SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
    134 
    135     if (input.width() > input.height()) {
    136         yScale *= input.height() / (float) input.width();
    137     } else {
    138         xScale *= input.width() / (float) input.height();
    139     }
    140 
    141     SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
    142                                   xScale * input.width(),
    143                                   yScale * input.height());
    144 
    145     canvas->clear(0xFFFFFFFF);
    146     canvas->drawBitmapRect(input, NULL, dst);
    147 
    148     if (NULL != srcRect) {
    149         SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
    150                                     srcRect->fTop * yScale + SK_Scalar1,
    151                                     srcRect->fRight * xScale + SK_Scalar1,
    152                                     srcRect->fBottom * yScale + SK_Scalar1);
    153         SkPaint p;
    154         p.setColor(SK_ColorRED);
    155         p.setStyle(SkPaint::kStroke_Style);
    156 
    157         canvas->drawRect(r, p);
    158     }
    159 }
    160 
    161 void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
    162     canvas->clear(0xFFFFFFFF);
    163     canvas->save();
    164 
    165     const SkRect& bounds = rrect.getBounds();
    166 
    167     xlate_and_scale_to_bounds(canvas, bounds);
    168 
    169     SkPaint p;
    170     p.setColor(SK_ColorBLACK);
    171     p.setStyle(SkPaint::kStroke_Style);
    172 
    173     canvas->drawRRect(rrect, p);
    174     canvas->restore();
    175 }
    176 
    177 void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
    178     canvas->clear(0xFFFFFFFF);
    179     canvas->save();
    180 
    181     const SkRect& bounds = outer.getBounds();
    182 
    183     xlate_and_scale_to_bounds(canvas, bounds);
    184 
    185     SkPaint p;
    186     p.setColor(SK_ColorBLACK);
    187     p.setStyle(SkPaint::kStroke_Style);
    188 
    189     canvas->drawDRRect(outer, inner, p);
    190     canvas->restore();
    191 }
    192 
    193 };
    194 
    195 
    196 SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA)
    197     : INHERITED(CLIP_PATH) {
    198     fPath = path;
    199     fOp = op;
    200     fDoAA = doAA;
    201 
    202     fInfo.push(SkObjectParser::PathToString(path));
    203     fInfo.push(SkObjectParser::RegionOpToString(op));
    204     fInfo.push(SkObjectParser::BoolToString(doAA));
    205 }
    206 
    207 void SkClipPathCommand::execute(SkCanvas* canvas) {
    208     canvas->clipPath(fPath, fOp, fDoAA);
    209 }
    210 
    211 bool SkClipPathCommand::render(SkCanvas* canvas) const {
    212     render_path(canvas, fPath);
    213     return true;
    214 }
    215 
    216 SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op)
    217     : INHERITED(CLIP_REGION) {
    218     fRegion = region;
    219     fOp = op;
    220 
    221     fInfo.push(SkObjectParser::RegionToString(region));
    222     fInfo.push(SkObjectParser::RegionOpToString(op));
    223 }
    224 
    225 void SkClipRegionCommand::execute(SkCanvas* canvas) {
    226     canvas->clipRegion(fRegion, fOp);
    227 }
    228 
    229 SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA)
    230     : INHERITED(CLIP_RECT) {
    231     fRect = rect;
    232     fOp = op;
    233     fDoAA = doAA;
    234 
    235     fInfo.push(SkObjectParser::RectToString(rect));
    236     fInfo.push(SkObjectParser::RegionOpToString(op));
    237     fInfo.push(SkObjectParser::BoolToString(doAA));
    238 }
    239 
    240 void SkClipRectCommand::execute(SkCanvas* canvas) {
    241     canvas->clipRect(fRect, fOp, fDoAA);
    242 }
    243 
    244 SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA)
    245     : INHERITED(CLIP_RRECT) {
    246     fRRect = rrect;
    247     fOp = op;
    248     fDoAA = doAA;
    249 
    250     fInfo.push(SkObjectParser::RRectToString(rrect));
    251     fInfo.push(SkObjectParser::RegionOpToString(op));
    252     fInfo.push(SkObjectParser::BoolToString(doAA));
    253 }
    254 
    255 void SkClipRRectCommand::execute(SkCanvas* canvas) {
    256     canvas->clipRRect(fRRect, fOp, fDoAA);
    257 }
    258 
    259 bool SkClipRRectCommand::render(SkCanvas* canvas) const {
    260     render_rrect(canvas, fRRect);
    261     return true;
    262 }
    263 
    264 SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
    265     : INHERITED(CONCAT) {
    266     fMatrix = matrix;
    267 
    268     fInfo.push(SkObjectParser::MatrixToString(matrix));
    269 }
    270 
    271 void SkConcatCommand::execute(SkCanvas* canvas) {
    272     canvas->concat(fMatrix);
    273 }
    274 
    275 SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
    276                        const SkPaint* paint)
    277     : INHERITED(DRAW_BITMAP) {
    278     fBitmap = bitmap;
    279     fLeft = left;
    280     fTop = top;
    281     if (NULL != paint) {
    282         fPaint = *paint;
    283         fPaintPtr = &fPaint;
    284     } else {
    285         fPaintPtr = NULL;
    286     }
    287 
    288     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    289     fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
    290     fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
    291     if (NULL != paint) {
    292         fInfo.push(SkObjectParser::PaintToString(*paint));
    293     }
    294 }
    295 
    296 void SkDrawBitmapCommand::execute(SkCanvas* canvas) {
    297     canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
    298 }
    299 
    300 bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
    301     render_bitmap(canvas, fBitmap);
    302     return true;
    303 }
    304 
    305 SkDrawBitmapMatrixCommand::SkDrawBitmapMatrixCommand(const SkBitmap& bitmap,
    306                                                      const SkMatrix& matrix,
    307                                                      const SkPaint* paint)
    308     : INHERITED(DRAW_BITMAP_MATRIX) {
    309     fBitmap = bitmap;
    310     fMatrix = matrix;
    311     if (NULL != paint) {
    312         fPaint = *paint;
    313         fPaintPtr = &fPaint;
    314     } else {
    315         fPaintPtr = NULL;
    316     }
    317 
    318     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    319     fInfo.push(SkObjectParser::MatrixToString(matrix));
    320     if (NULL != paint) {
    321         fInfo.push(SkObjectParser::PaintToString(*paint));
    322     }
    323 }
    324 
    325 void SkDrawBitmapMatrixCommand::execute(SkCanvas* canvas) {
    326     canvas->drawBitmapMatrix(fBitmap, fMatrix, fPaintPtr);
    327 }
    328 
    329 bool SkDrawBitmapMatrixCommand::render(SkCanvas* canvas) const {
    330     render_bitmap(canvas, fBitmap);
    331     return true;
    332 }
    333 
    334 SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
    335                                                  const SkRect& dst, const SkPaint* paint)
    336     : INHERITED(DRAW_BITMAP_NINE) {
    337     fBitmap = bitmap;
    338     fCenter = center;
    339     fDst = dst;
    340     if (NULL != paint) {
    341         fPaint = *paint;
    342         fPaintPtr = &fPaint;
    343     } else {
    344         fPaintPtr = NULL;
    345     }
    346 
    347     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    348     fInfo.push(SkObjectParser::IRectToString(center));
    349     fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    350     if (NULL != paint) {
    351         fInfo.push(SkObjectParser::PaintToString(*paint));
    352     }
    353 }
    354 
    355 void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) {
    356     canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
    357 }
    358 
    359 bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
    360     render_bitmap(canvas, fBitmap);
    361     return true;
    362 }
    363 
    364 SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
    365                                                  const SkRect& dst, const SkPaint* paint,
    366                                                  SkCanvas::DrawBitmapRectFlags flags)
    367     : INHERITED(DRAW_BITMAP_RECT_TO_RECT) {
    368     fBitmap = bitmap;
    369     if (NULL != src) {
    370         fSrc = *src;
    371     } else {
    372         fSrc.setEmpty();
    373     }
    374     fDst = dst;
    375 
    376     if (NULL != paint) {
    377         fPaint = *paint;
    378         fPaintPtr = &fPaint;
    379     } else {
    380         fPaintPtr = NULL;
    381     }
    382     fFlags = flags;
    383 
    384     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    385     if (NULL != src) {
    386         fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
    387     }
    388     fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    389     if (NULL != paint) {
    390         fInfo.push(SkObjectParser::PaintToString(*paint));
    391     }
    392     fInfo.push(SkObjectParser::IntToString(fFlags, "Flags: "));
    393 }
    394 
    395 void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) {
    396     canvas->drawBitmapRectToRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fFlags);
    397 }
    398 
    399 bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
    400     render_bitmap(canvas, fBitmap, this->srcRect());
    401     return true;
    402 }
    403 
    404 SkDrawDataCommand::SkDrawDataCommand(const void* data, size_t length)
    405     : INHERITED(DRAW_DATA) {
    406     fData = new char[length];
    407     memcpy(fData, data, length);
    408     fLength = length;
    409 
    410     // TODO: add display of actual data?
    411     SkString* str = new SkString;
    412     str->appendf("length: %d", (int) length);
    413     fInfo.push(str);
    414 }
    415 
    416 void SkDrawDataCommand::execute(SkCanvas* canvas) {
    417     canvas->drawData(fData, fLength);
    418 }
    419 
    420 SkBeginCommentGroupCommand::SkBeginCommentGroupCommand(const char* description)
    421     : INHERITED(BEGIN_COMMENT_GROUP)
    422     , fDescription(description) {
    423     SkString* temp = new SkString;
    424     temp->appendf("Description: %s", description);
    425     fInfo.push(temp);
    426 }
    427 
    428 SkCommentCommand::SkCommentCommand(const char* kywd, const char* value)
    429     : INHERITED(COMMENT)
    430     , fKywd(kywd)
    431     , fValue(value) {
    432     SkString* temp = new SkString;
    433     temp->appendf("%s: %s", kywd, value);
    434     fInfo.push(temp);
    435 }
    436 
    437 SkEndCommentGroupCommand::SkEndCommentGroupCommand()
    438     : INHERITED(END_COMMENT_GROUP) {
    439 }
    440 
    441 SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
    442     : INHERITED(DRAW_OVAL) {
    443     fOval = oval;
    444     fPaint = paint;
    445 
    446     fInfo.push(SkObjectParser::RectToString(oval));
    447     fInfo.push(SkObjectParser::PaintToString(paint));
    448 }
    449 
    450 void SkDrawOvalCommand::execute(SkCanvas* canvas) {
    451     canvas->drawOval(fOval, fPaint);
    452 }
    453 
    454 bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
    455     canvas->clear(0xFFFFFFFF);
    456     canvas->save();
    457 
    458     xlate_and_scale_to_bounds(canvas, fOval);
    459 
    460     SkPaint p;
    461     p.setColor(SK_ColorBLACK);
    462     p.setStyle(SkPaint::kStroke_Style);
    463 
    464     canvas->drawOval(fOval, p);
    465     canvas->restore();
    466 
    467     return true;
    468 }
    469 
    470 SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
    471     : INHERITED(DRAW_PAINT) {
    472     fPaint = paint;
    473 
    474     fInfo.push(SkObjectParser::PaintToString(paint));
    475 }
    476 
    477 void SkDrawPaintCommand::execute(SkCanvas* canvas) {
    478     canvas->drawPaint(fPaint);
    479 }
    480 
    481 bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
    482     canvas->clear(0xFFFFFFFF);
    483     canvas->drawPaint(fPaint);
    484     return true;
    485 }
    486 
    487 SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
    488     : INHERITED(DRAW_PATH) {
    489     fPath = path;
    490     fPaint = paint;
    491 
    492     fInfo.push(SkObjectParser::PathToString(path));
    493     fInfo.push(SkObjectParser::PaintToString(paint));
    494 }
    495 
    496 void SkDrawPathCommand::execute(SkCanvas* canvas) {
    497     canvas->drawPath(fPath, fPaint);
    498 }
    499 
    500 bool SkDrawPathCommand::render(SkCanvas* canvas) const {
    501     render_path(canvas, fPath);
    502     return true;
    503 }
    504 
    505 SkDrawPictureCommand::SkDrawPictureCommand(const SkPicture* picture)
    506     : INHERITED(DRAW_PICTURE)
    507     , fPicture(SkRef(picture)) {
    508     SkString* temp = new SkString;
    509     temp->appendf("SkPicture: W: %d H: %d", picture->width(), picture->height());
    510     fInfo.push(temp);
    511 }
    512 
    513 void SkDrawPictureCommand::execute(SkCanvas* canvas) {
    514     canvas->drawPicture(fPicture);
    515 }
    516 
    517 bool SkDrawPictureCommand::render(SkCanvas* canvas) const {
    518     canvas->clear(0xFFFFFFFF);
    519     canvas->save();
    520 
    521     SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
    522                                    SkIntToScalar(fPicture->height()));
    523     xlate_and_scale_to_bounds(canvas, bounds);
    524 
    525     canvas->drawPicture(fPicture.get());
    526 
    527     canvas->restore();
    528 
    529     return true;
    530 }
    531 
    532 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
    533                                          const SkPoint pts[], const SkPaint& paint)
    534     : INHERITED(DRAW_POINTS) {
    535     fMode = mode;
    536     fCount = count;
    537     fPts = new SkPoint[count];
    538     memcpy(fPts, pts, count * sizeof(SkPoint));
    539     fPaint = paint;
    540 
    541     fInfo.push(SkObjectParser::PointsToString(pts, count));
    542     fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
    543                                               "Points: "));
    544     fInfo.push(SkObjectParser::PointModeToString(mode));
    545     fInfo.push(SkObjectParser::PaintToString(paint));
    546 }
    547 
    548 void SkDrawPointsCommand::execute(SkCanvas* canvas) {
    549     canvas->drawPoints(fMode, fCount, fPts, fPaint);
    550 }
    551 
    552 bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
    553     canvas->clear(0xFFFFFFFF);
    554     canvas->save();
    555 
    556     SkRect bounds;
    557 
    558     bounds.setEmpty();
    559     for (unsigned int i = 0; i < fCount; ++i) {
    560         bounds.growToInclude(fPts[i].fX, fPts[i].fY);
    561     }
    562 
    563     xlate_and_scale_to_bounds(canvas, bounds);
    564 
    565     SkPaint p;
    566     p.setColor(SK_ColorBLACK);
    567     p.setStyle(SkPaint::kStroke_Style);
    568 
    569     canvas->drawPoints(fMode, fCount, fPts, p);
    570     canvas->restore();
    571 
    572     return true;
    573 }
    574 
    575 SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
    576                                            const SkPoint pos[], const SkPaint& paint)
    577     : INHERITED(DRAW_POS_TEXT) {
    578     size_t numPts = paint.countText(text, byteLength);
    579 
    580     fText = new char[byteLength];
    581     memcpy(fText, text, byteLength);
    582     fByteLength = byteLength;
    583 
    584     fPos = new SkPoint[numPts];
    585     memcpy(fPos, pos, numPts * sizeof(SkPoint));
    586 
    587     fPaint = paint;
    588 
    589     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    590     // TODO(chudy): Test that this works.
    591     fInfo.push(SkObjectParser::PointsToString(pos, 1));
    592     fInfo.push(SkObjectParser::PaintToString(paint));
    593 }
    594 
    595 void SkDrawPosTextCommand::execute(SkCanvas* canvas) {
    596     canvas->drawPosText(fText, fByteLength, fPos, fPaint);
    597 }
    598 
    599 
    600 SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
    601                                              const SkScalar xpos[], SkScalar constY,
    602                                              const SkPaint& paint)
    603     : INHERITED(DRAW_POS_TEXT_H) {
    604     size_t numPts = paint.countText(text, byteLength);
    605 
    606     fText = new char[byteLength];
    607     memcpy(fText, text, byteLength);
    608     fByteLength = byteLength;
    609 
    610     fXpos = new SkScalar[numPts];
    611     memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
    612 
    613     fConstY = constY;
    614     fPaint = paint;
    615 
    616     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    617     fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
    618     fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
    619     fInfo.push(SkObjectParser::PaintToString(paint));
    620 }
    621 
    622 void SkDrawPosTextHCommand::execute(SkCanvas* canvas) {
    623     canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
    624 }
    625 
    626 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
    627     : INHERITED(DRAW_RECT) {
    628     fRect = rect;
    629     fPaint = paint;
    630 
    631     fInfo.push(SkObjectParser::RectToString(rect));
    632     fInfo.push(SkObjectParser::PaintToString(paint));
    633 }
    634 
    635 void SkDrawRectCommand::execute(SkCanvas* canvas) {
    636     canvas->drawRect(fRect, fPaint);
    637 }
    638 
    639 SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
    640     : INHERITED(DRAW_RRECT) {
    641     fRRect = rrect;
    642     fPaint = paint;
    643 
    644     fInfo.push(SkObjectParser::RRectToString(rrect));
    645     fInfo.push(SkObjectParser::PaintToString(paint));
    646 }
    647 
    648 void SkDrawRRectCommand::execute(SkCanvas* canvas) {
    649     canvas->drawRRect(fRRect, fPaint);
    650 }
    651 
    652 bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
    653     render_rrect(canvas, fRRect);
    654     return true;
    655 }
    656 
    657 SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
    658                                          const SkRRect& inner,
    659                                          const SkPaint& paint)
    660     : INHERITED(DRAW_DRRECT) {
    661     fOuter = outer;
    662     fInner = inner;
    663     fPaint = paint;
    664 
    665     fInfo.push(SkObjectParser::RRectToString(outer));
    666     fInfo.push(SkObjectParser::RRectToString(inner));
    667     fInfo.push(SkObjectParser::PaintToString(paint));
    668 }
    669 
    670 void SkDrawDRRectCommand::execute(SkCanvas* canvas) {
    671     canvas->drawDRRect(fOuter, fInner, fPaint);
    672 }
    673 
    674 bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
    675     render_drrect(canvas, fOuter, fInner);
    676     return true;
    677 }
    678 
    679 SkDrawSpriteCommand::SkDrawSpriteCommand(const SkBitmap& bitmap, int left, int top,
    680                                          const SkPaint* paint)
    681     : INHERITED(DRAW_SPRITE) {
    682     fBitmap = bitmap;
    683     fLeft = left;
    684     fTop = top;
    685     if (NULL != paint) {
    686         fPaint = *paint;
    687         fPaintPtr = &fPaint;
    688     } else {
    689         fPaintPtr = NULL;
    690     }
    691 
    692     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    693     fInfo.push(SkObjectParser::IntToString(left, "Left: "));
    694     fInfo.push(SkObjectParser::IntToString(top, "Top: "));
    695     if (NULL != paint) {
    696         fInfo.push(SkObjectParser::PaintToString(*paint));
    697     }
    698 }
    699 
    700 void SkDrawSpriteCommand::execute(SkCanvas* canvas) {
    701     canvas->drawSprite(fBitmap, fLeft, fTop, fPaintPtr);
    702 }
    703 
    704 bool SkDrawSpriteCommand::render(SkCanvas* canvas) const {
    705     render_bitmap(canvas, fBitmap);
    706     return true;
    707 }
    708 
    709 SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
    710                                      const SkPaint& paint)
    711     : INHERITED(DRAW_TEXT) {
    712     fText = new char[byteLength];
    713     memcpy(fText, text, byteLength);
    714     fByteLength = byteLength;
    715     fX = x;
    716     fY = y;
    717     fPaint = paint;
    718 
    719     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    720     fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
    721     fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
    722     fInfo.push(SkObjectParser::PaintToString(paint));
    723 }
    724 
    725 void SkDrawTextCommand::execute(SkCanvas* canvas) {
    726     canvas->drawText(fText, fByteLength, fX, fY, fPaint);
    727 }
    728 
    729 SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
    730                                                  const SkPath& path, const SkMatrix* matrix,
    731                                                  const SkPaint& paint)
    732     : INHERITED(DRAW_TEXT_ON_PATH) {
    733     fText = new char[byteLength];
    734     memcpy(fText, text, byteLength);
    735     fByteLength = byteLength;
    736     fPath = path;
    737     if (NULL != matrix) {
    738         fMatrix = *matrix;
    739     } else {
    740         fMatrix.setIdentity();
    741     }
    742     fPaint = paint;
    743 
    744     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    745     fInfo.push(SkObjectParser::PathToString(path));
    746     if (NULL != matrix) {
    747         fInfo.push(SkObjectParser::MatrixToString(*matrix));
    748     }
    749     fInfo.push(SkObjectParser::PaintToString(paint));
    750 }
    751 
    752 void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) {
    753     canvas->drawTextOnPath(fText, fByteLength, fPath,
    754                            fMatrix.isIdentity() ? NULL : &fMatrix,
    755                            fPaint);
    756 }
    757 
    758 SkDrawVerticesCommand::SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount,
    759                                              const SkPoint vertices[], const SkPoint texs[],
    760                                              const SkColor colors[], SkXfermode* xfermode,
    761                                              const uint16_t indices[], int indexCount,
    762                                              const SkPaint& paint)
    763     : INHERITED(DRAW_VERTICES) {
    764     fVmode = vmode;
    765 
    766     fVertexCount = vertexCount;
    767 
    768     fVertices = new SkPoint[vertexCount];
    769     memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint));
    770 
    771     if (NULL != texs) {
    772         fTexs = new SkPoint[vertexCount];
    773         memcpy(fTexs, texs, vertexCount * sizeof(SkPoint));
    774     } else {
    775         fTexs = NULL;
    776     }
    777 
    778     if (NULL != colors) {
    779         fColors = new SkColor[vertexCount];
    780         memcpy(fColors, colors, vertexCount * sizeof(SkColor));
    781     } else {
    782         fColors = NULL;
    783     }
    784 
    785     fXfermode = xfermode;
    786     if (NULL != fXfermode) {
    787         fXfermode->ref();
    788     }
    789 
    790     if (indexCount > 0) {
    791         fIndices = new uint16_t[indexCount];
    792         memcpy(fIndices, indices, indexCount * sizeof(uint16_t));
    793     } else {
    794         fIndices = NULL;
    795     }
    796 
    797     fIndexCount = indexCount;
    798     fPaint = paint;
    799 
    800     // TODO(chudy)
    801     fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
    802     fInfo.push(SkObjectParser::PaintToString(paint));
    803 }
    804 
    805 SkDrawVerticesCommand::~SkDrawVerticesCommand() {
    806     delete [] fVertices;
    807     delete [] fTexs;
    808     delete [] fColors;
    809     SkSafeUnref(fXfermode);
    810     delete [] fIndices;
    811 }
    812 
    813 void SkDrawVerticesCommand::execute(SkCanvas* canvas) {
    814     canvas->drawVertices(fVmode, fVertexCount, fVertices,
    815                          fTexs, fColors, fXfermode, fIndices,
    816                          fIndexCount, fPaint);
    817 }
    818 
    819 SkRestoreCommand::SkRestoreCommand()
    820     : INHERITED(RESTORE) {
    821     fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
    822 }
    823 
    824 void SkRestoreCommand::execute(SkCanvas* canvas) {
    825     canvas->restore();
    826 }
    827 
    828 void SkRestoreCommand::trackSaveState(int* state) {
    829     (*state)--;
    830 }
    831 
    832 SkRotateCommand::SkRotateCommand(SkScalar degrees)
    833     : INHERITED(ROTATE) {
    834     fDegrees = degrees;
    835 
    836     fInfo.push(SkObjectParser::ScalarToString(degrees, "SkScalar degrees: "));
    837 }
    838 
    839 void SkRotateCommand::execute(SkCanvas* canvas) {
    840     canvas->rotate(fDegrees);
    841 }
    842 
    843 SkSaveCommand::SkSaveCommand(SkCanvas::SaveFlags flags)
    844     : INHERITED(SAVE) {
    845     fFlags = flags;
    846     fInfo.push(SkObjectParser::SaveFlagsToString(flags));
    847 }
    848 
    849 void SkSaveCommand::execute(SkCanvas* canvas) {
    850     canvas->save(fFlags);
    851 }
    852 
    853 void SkSaveCommand::trackSaveState(int* state) {
    854     (*state)++;
    855 }
    856 
    857 SkSaveLayerCommand::SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
    858                                        SkCanvas::SaveFlags flags)
    859     : INHERITED(SAVE_LAYER) {
    860     if (NULL != bounds) {
    861         fBounds = *bounds;
    862     } else {
    863         fBounds.setEmpty();
    864     }
    865 
    866     if (NULL != paint) {
    867         fPaint = *paint;
    868         fPaintPtr = &fPaint;
    869     } else {
    870         fPaintPtr = NULL;
    871     }
    872     fFlags = flags;
    873 
    874     if (NULL != bounds) {
    875         fInfo.push(SkObjectParser::RectToString(*bounds, "Bounds: "));
    876     }
    877     if (NULL != paint) {
    878         fInfo.push(SkObjectParser::PaintToString(*paint));
    879     }
    880     fInfo.push(SkObjectParser::SaveFlagsToString(flags));
    881 }
    882 
    883 void SkSaveLayerCommand::execute(SkCanvas* canvas) {
    884     canvas->saveLayer(fBounds.isEmpty() ? NULL : &fBounds,
    885                       fPaintPtr,
    886                       fFlags);
    887 }
    888 
    889 void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) {
    890     canvas->save();
    891 }
    892 
    893 void SkSaveLayerCommand::trackSaveState(int* state) {
    894     (*state)++;
    895 }
    896 
    897 SkScaleCommand::SkScaleCommand(SkScalar sx, SkScalar sy)
    898     : INHERITED(SCALE) {
    899     fSx = sx;
    900     fSy = sy;
    901 
    902     fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
    903     fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
    904 }
    905 
    906 void SkScaleCommand::execute(SkCanvas* canvas) {
    907     canvas->scale(fSx, fSy);
    908 }
    909 
    910 SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
    911     : INHERITED(SET_MATRIX) {
    912     fMatrix = matrix;
    913 
    914     fInfo.push(SkObjectParser::MatrixToString(matrix));
    915 }
    916 
    917 void SkSetMatrixCommand::execute(SkCanvas* canvas) {
    918     canvas->setMatrix(fMatrix);
    919 }
    920 
    921 SkSkewCommand::SkSkewCommand(SkScalar sx, SkScalar sy)
    922     : INHERITED(SKEW) {
    923     fSx = sx;
    924     fSy = sy;
    925 
    926     fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
    927     fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
    928 }
    929 
    930 void SkSkewCommand::execute(SkCanvas* canvas) {
    931     canvas->skew(fSx, fSy);
    932 }
    933 
    934 SkTranslateCommand::SkTranslateCommand(SkScalar dx, SkScalar dy)
    935     : INHERITED(TRANSLATE) {
    936     fDx = dx;
    937     fDy = dy;
    938 
    939     fInfo.push(SkObjectParser::ScalarToString(dx, "SkScalar dx: "));
    940     fInfo.push(SkObjectParser::ScalarToString(dy, "SkScalar dy: "));
    941 }
    942 
    943 void SkTranslateCommand::execute(SkCanvas* canvas) {
    944     canvas->translate(fDx, fDy);
    945 }
    946 
    947 SkPushCullCommand::SkPushCullCommand(const SkRect& cullRect)
    948     : INHERITED(PUSH_CULL)
    949     , fCullRect(cullRect) {
    950     fInfo.push(SkObjectParser::RectToString(cullRect));
    951 }
    952 
    953 void SkPushCullCommand::execute(SkCanvas* canvas) {
    954     canvas->pushCull(fCullRect);
    955 }
    956 
    957 void SkPushCullCommand::vizExecute(SkCanvas* canvas) {
    958     canvas->pushCull(fCullRect);
    959 
    960     SkPaint p;
    961     p.setColor(SK_ColorCYAN);
    962     p.setStyle(SkPaint::kStroke_Style);
    963     canvas->drawRect(fCullRect, p);
    964 }
    965 
    966 SkPopCullCommand::SkPopCullCommand() : INHERITED(POP_CULL) { }
    967 
    968 void SkPopCullCommand::execute(SkCanvas* canvas) {
    969     canvas->popCull();
    970 }
    971