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