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                                                  SkCanvas::DrawBitmapRectFlags flags) {
    347     fBitmap = bitmap;
    348     if (NULL != src) {
    349         fSrc = *src;
    350     } else {
    351         fSrc.setEmpty();
    352     }
    353     fDst = dst;
    354 
    355     if (NULL != paint) {
    356         fPaint = *paint;
    357         fPaintPtr = &fPaint;
    358     } else {
    359         fPaintPtr = NULL;
    360     }
    361     fFlags = flags;
    362 
    363     fDrawType = DRAW_BITMAP_RECT_TO_RECT;
    364 
    365     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    366     if (NULL != src) {
    367         fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
    368     }
    369     fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    370     if (NULL != paint) {
    371         fInfo.push(SkObjectParser::PaintToString(*paint));
    372     }
    373     fInfo.push(SkObjectParser::IntToString(fFlags, "Flags: "));
    374 }
    375 
    376 void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) {
    377     canvas->drawBitmapRectToRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fFlags);
    378 }
    379 
    380 bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
    381     render_bitmap(canvas, fBitmap, this->srcRect());
    382     return true;
    383 }
    384 
    385 SkDrawDataCommand::SkDrawDataCommand(const void* data, size_t length) {
    386     fData = new char[length];
    387     memcpy(fData, data, length);
    388     fLength = length;
    389     fDrawType = DRAW_DATA;
    390 
    391     // TODO: add display of actual data?
    392     SkString* str = new SkString;
    393     str->appendf("length: %d", (int) length);
    394     fInfo.push(str);
    395 }
    396 
    397 void SkDrawDataCommand::execute(SkCanvas* canvas) {
    398     canvas->drawData(fData, fLength);
    399 }
    400 
    401 SkBeginCommentGroupCommand::SkBeginCommentGroupCommand(const char* description)
    402     : INHERITED(BEGIN_COMMENT_GROUP)
    403     , fDescription(description) {
    404     SkString* temp = new SkString;
    405     temp->appendf("Description: %s", description);
    406     fInfo.push(temp);
    407 }
    408 
    409 SkCommentCommand::SkCommentCommand(const char* kywd, const char* value)
    410     : INHERITED(COMMENT)
    411     , fKywd(kywd)
    412     , fValue(value) {
    413     SkString* temp = new SkString;
    414     temp->appendf("%s: %s", kywd, value);
    415     fInfo.push(temp);
    416 }
    417 
    418 SkEndCommentGroupCommand::SkEndCommentGroupCommand() : INHERITED(END_COMMENT_GROUP) {
    419 }
    420 
    421 SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint) {
    422     fOval = oval;
    423     fPaint = paint;
    424     fDrawType = DRAW_OVAL;
    425 
    426     fInfo.push(SkObjectParser::RectToString(oval));
    427     fInfo.push(SkObjectParser::PaintToString(paint));
    428 }
    429 
    430 void SkDrawOvalCommand::execute(SkCanvas* canvas) {
    431     canvas->drawOval(fOval, fPaint);
    432 }
    433 
    434 bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
    435     canvas->clear(0xFFFFFFFF);
    436     canvas->save();
    437 
    438     xlate_and_scale_to_bounds(canvas, fOval);
    439 
    440     SkPaint p;
    441     p.setColor(SK_ColorBLACK);
    442     p.setStyle(SkPaint::kStroke_Style);
    443 
    444     canvas->drawOval(fOval, p);
    445     canvas->restore();
    446 
    447     return true;
    448 }
    449 
    450 SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint) {
    451     fPaint = paint;
    452     fDrawType = DRAW_PAINT;
    453 
    454     fInfo.push(SkObjectParser::PaintToString(paint));
    455 }
    456 
    457 void SkDrawPaintCommand::execute(SkCanvas* canvas) {
    458     canvas->drawPaint(fPaint);
    459 }
    460 
    461 bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
    462     canvas->clear(0xFFFFFFFF);
    463     canvas->drawPaint(fPaint);
    464     return true;
    465 }
    466 
    467 SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint) {
    468     fPath = path;
    469     fPaint = paint;
    470     fDrawType = DRAW_PATH;
    471 
    472     fInfo.push(SkObjectParser::PathToString(path));
    473     fInfo.push(SkObjectParser::PaintToString(paint));
    474 }
    475 
    476 void SkDrawPathCommand::execute(SkCanvas* canvas) {
    477     canvas->drawPath(fPath, fPaint);
    478 }
    479 
    480 bool SkDrawPathCommand::render(SkCanvas* canvas) const {
    481     render_path(canvas, fPath);
    482     return true;
    483 }
    484 
    485 SkDrawPictureCommand::SkDrawPictureCommand(SkPicture& picture) :
    486     fPicture(picture) {
    487     fDrawType = DRAW_PICTURE;
    488     SkString* temp = new SkString;
    489     temp->appendf("SkPicture: W: %d H: %d", picture.width(), picture.height());
    490     fInfo.push(temp);
    491 }
    492 
    493 void SkDrawPictureCommand::execute(SkCanvas* canvas) {
    494     canvas->drawPicture(fPicture);
    495 }
    496 
    497 bool SkDrawPictureCommand::render(SkCanvas* canvas) const {
    498     canvas->clear(0xFFFFFFFF);
    499     canvas->save();
    500 
    501     SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture.width()),
    502                                    SkIntToScalar(fPicture.height()));
    503     xlate_and_scale_to_bounds(canvas, bounds);
    504 
    505     canvas->drawPicture(const_cast<SkPicture&>(fPicture));
    506 
    507     canvas->restore();
    508 
    509     return true;
    510 }
    511 
    512 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
    513                                          const SkPoint pts[], const SkPaint& paint) {
    514     fMode = mode;
    515     fCount = count;
    516     fPts = new SkPoint[count];
    517     memcpy(fPts, pts, count * sizeof(SkPoint));
    518     fPaint = paint;
    519     fDrawType = DRAW_POINTS;
    520 
    521     fInfo.push(SkObjectParser::PointsToString(pts, count));
    522     fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
    523                                               "Points: "));
    524     fInfo.push(SkObjectParser::PointModeToString(mode));
    525     fInfo.push(SkObjectParser::PaintToString(paint));
    526 }
    527 
    528 void SkDrawPointsCommand::execute(SkCanvas* canvas) {
    529     canvas->drawPoints(fMode, fCount, fPts, fPaint);
    530 }
    531 
    532 bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
    533     canvas->clear(0xFFFFFFFF);
    534     canvas->save();
    535 
    536     SkRect bounds;
    537 
    538     bounds.setEmpty();
    539     for (unsigned int i = 0; i < fCount; ++i) {
    540         bounds.growToInclude(fPts[i].fX, fPts[i].fY);
    541     }
    542 
    543     xlate_and_scale_to_bounds(canvas, bounds);
    544 
    545     SkPaint p;
    546     p.setColor(SK_ColorBLACK);
    547     p.setStyle(SkPaint::kStroke_Style);
    548 
    549     canvas->drawPoints(fMode, fCount, fPts, p);
    550     canvas->restore();
    551 
    552     return true;
    553 }
    554 
    555 SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
    556                                            const SkPoint pos[], const SkPaint& paint) {
    557     size_t numPts = paint.countText(text, byteLength);
    558 
    559     fText = new char[byteLength];
    560     memcpy(fText, text, byteLength);
    561     fByteLength = byteLength;
    562 
    563     fPos = new SkPoint[numPts];
    564     memcpy(fPos, pos, numPts * sizeof(SkPoint));
    565 
    566     fPaint = paint;
    567     fDrawType = DRAW_POS_TEXT;
    568 
    569     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    570     // TODO(chudy): Test that this works.
    571     fInfo.push(SkObjectParser::PointsToString(pos, 1));
    572     fInfo.push(SkObjectParser::PaintToString(paint));
    573 }
    574 
    575 void SkDrawPosTextCommand::execute(SkCanvas* canvas) {
    576     canvas->drawPosText(fText, fByteLength, fPos, fPaint);
    577 }
    578 
    579 
    580 SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
    581                                              const SkScalar xpos[], SkScalar constY,
    582                                              const SkPaint& paint) {
    583     size_t numPts = paint.countText(text, byteLength);
    584 
    585     fText = new char[byteLength];
    586     memcpy(fText, text, byteLength);
    587     fByteLength = byteLength;
    588 
    589     fXpos = new SkScalar[numPts];
    590     memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
    591 
    592     fConstY = constY;
    593     fPaint = paint;
    594     fDrawType = DRAW_POS_TEXT_H;
    595 
    596     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    597     fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
    598     fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
    599     fInfo.push(SkObjectParser::PaintToString(paint));
    600 }
    601 
    602 void SkDrawPosTextHCommand::execute(SkCanvas* canvas) {
    603     canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
    604 }
    605 
    606 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint) {
    607     fRect = rect;
    608     fPaint = paint;
    609     fDrawType = DRAW_RECT;
    610 
    611     fInfo.push(SkObjectParser::RectToString(rect));
    612     fInfo.push(SkObjectParser::PaintToString(paint));
    613 }
    614 
    615 void SkDrawRectCommand::execute(SkCanvas* canvas) {
    616     canvas->drawRect(fRect, fPaint);
    617 }
    618 
    619 SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint) {
    620     fRRect = rrect;
    621     fPaint = paint;
    622     fDrawType = DRAW_RRECT;
    623 
    624     fInfo.push(SkObjectParser::RRectToString(rrect));
    625     fInfo.push(SkObjectParser::PaintToString(paint));
    626 }
    627 
    628 void SkDrawRRectCommand::execute(SkCanvas* canvas) {
    629     canvas->drawRRect(fRRect, fPaint);
    630 }
    631 
    632 bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
    633     render_rrect(canvas, fRRect);
    634     return true;
    635 }
    636 
    637 SkDrawSpriteCommand::SkDrawSpriteCommand(const SkBitmap& bitmap, int left, int top,
    638                                          const SkPaint* paint) {
    639     fBitmap = bitmap;
    640     fLeft = left;
    641     fTop = top;
    642     if (NULL != paint) {
    643         fPaint = *paint;
    644         fPaintPtr = &fPaint;
    645     } else {
    646         fPaintPtr = NULL;
    647     }
    648     fDrawType = DRAW_SPRITE;
    649 
    650     fInfo.push(SkObjectParser::BitmapToString(bitmap));
    651     fInfo.push(SkObjectParser::IntToString(left, "Left: "));
    652     fInfo.push(SkObjectParser::IntToString(top, "Top: "));
    653     if (NULL != paint) {
    654         fInfo.push(SkObjectParser::PaintToString(*paint));
    655     }
    656 }
    657 
    658 void SkDrawSpriteCommand::execute(SkCanvas* canvas) {
    659     canvas->drawSprite(fBitmap, fLeft, fTop, fPaintPtr);
    660 }
    661 
    662 bool SkDrawSpriteCommand::render(SkCanvas* canvas) const {
    663     render_bitmap(canvas, fBitmap);
    664     return true;
    665 }
    666 
    667 SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
    668                                      const SkPaint& paint) {
    669     fText = new char[byteLength];
    670     memcpy(fText, text, byteLength);
    671     fByteLength = byteLength;
    672     fX = x;
    673     fY = y;
    674     fPaint = paint;
    675     fDrawType = DRAW_TEXT;
    676 
    677     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    678     fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
    679     fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
    680     fInfo.push(SkObjectParser::PaintToString(paint));
    681 }
    682 
    683 void SkDrawTextCommand::execute(SkCanvas* canvas) {
    684     canvas->drawText(fText, fByteLength, fX, fY, fPaint);
    685 }
    686 
    687 SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
    688                                                  const SkPath& path, const SkMatrix* matrix,
    689                                                  const SkPaint& paint) {
    690     fText = new char[byteLength];
    691     memcpy(fText, text, byteLength);
    692     fByteLength = byteLength;
    693     fPath = path;
    694     if (NULL != matrix) {
    695         fMatrix = *matrix;
    696     } else {
    697         fMatrix.setIdentity();
    698     }
    699     fPaint = paint;
    700     fDrawType = DRAW_TEXT_ON_PATH;
    701 
    702     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
    703     fInfo.push(SkObjectParser::PathToString(path));
    704     if (NULL != matrix) {
    705         fInfo.push(SkObjectParser::MatrixToString(*matrix));
    706     }
    707     fInfo.push(SkObjectParser::PaintToString(paint));
    708 }
    709 
    710 void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) {
    711     canvas->drawTextOnPath(fText, fByteLength, fPath,
    712                            fMatrix.isIdentity() ? NULL : &fMatrix,
    713                            fPaint);
    714 }
    715 
    716 SkDrawVerticesCommand::SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount,
    717                                              const SkPoint vertices[], const SkPoint texs[],
    718                                              const SkColor colors[], SkXfermode* xfermode,
    719                                              const uint16_t indices[], int indexCount,
    720                                              const SkPaint& paint) {
    721     fVmode = vmode;
    722 
    723     fVertexCount = vertexCount;
    724 
    725     fVertices = new SkPoint[vertexCount];
    726     memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint));
    727 
    728     if (NULL != texs) {
    729         fTexs = new SkPoint[vertexCount];
    730         memcpy(fTexs, texs, vertexCount * sizeof(SkPoint));
    731     } else {
    732         fTexs = NULL;
    733     }
    734 
    735     if (NULL != colors) {
    736         fColors = new SkColor[vertexCount];
    737         memcpy(fColors, colors, vertexCount * sizeof(SkColor));
    738     } else {
    739         fColors = NULL;
    740     }
    741 
    742     fXfermode = xfermode;
    743     if (NULL != fXfermode) {
    744         fXfermode->ref();
    745     }
    746 
    747     if (indexCount > 0) {
    748         fIndices = new uint16_t[indexCount];
    749         memcpy(fIndices, indices, indexCount * sizeof(uint16_t));
    750     } else {
    751         fIndices = NULL;
    752     }
    753 
    754     fIndexCount = indexCount;
    755     fPaint = paint;
    756     fDrawType = DRAW_VERTICES;
    757 
    758     // TODO(chudy)
    759     fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
    760     fInfo.push(SkObjectParser::PaintToString(paint));
    761 }
    762 
    763 SkDrawVerticesCommand::~SkDrawVerticesCommand() {
    764     delete [] fVertices;
    765     delete [] fTexs;
    766     delete [] fColors;
    767     SkSafeUnref(fXfermode);
    768     delete [] fIndices;
    769 }
    770 
    771 void SkDrawVerticesCommand::execute(SkCanvas* canvas) {
    772     canvas->drawVertices(fVmode, fVertexCount, fVertices,
    773                          fTexs, fColors, fXfermode, fIndices,
    774                          fIndexCount, fPaint);
    775 }
    776 
    777 SkRestoreCommand::SkRestoreCommand() {
    778     fDrawType = RESTORE;
    779     fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
    780 }
    781 
    782 void SkRestoreCommand::execute(SkCanvas* canvas) {
    783     canvas->restore();
    784 }
    785 
    786 void SkRestoreCommand::trackSaveState(int* state) {
    787     (*state)--;
    788 }
    789 
    790 SkRotateCommand::SkRotateCommand(SkScalar degrees) {
    791     fDegrees = degrees;
    792     fDrawType = ROTATE;
    793 
    794     fInfo.push(SkObjectParser::ScalarToString(degrees, "SkScalar degrees: "));
    795 }
    796 
    797 void SkRotateCommand::execute(SkCanvas* canvas) {
    798     canvas->rotate(fDegrees);
    799 }
    800 
    801 SkSaveCommand::SkSaveCommand(SkCanvas::SaveFlags flags) {
    802     fFlags = flags;
    803     fDrawType = SAVE;
    804     fInfo.push(SkObjectParser::SaveFlagsToString(flags));
    805 }
    806 
    807 void SkSaveCommand::execute(SkCanvas* canvas) {
    808     canvas->save(fFlags);
    809 }
    810 
    811 void SkSaveCommand::trackSaveState(int* state) {
    812     (*state)++;
    813 }
    814 
    815 SkSaveLayerCommand::SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
    816                                        SkCanvas::SaveFlags flags) {
    817     if (NULL != bounds) {
    818         fBounds = *bounds;
    819     } else {
    820         fBounds.setEmpty();
    821     }
    822 
    823     if (NULL != paint) {
    824         fPaint = *paint;
    825         fPaintPtr = &fPaint;
    826     } else {
    827         fPaintPtr = NULL;
    828     }
    829     fFlags = flags;
    830     fDrawType = SAVE_LAYER;
    831 
    832     if (NULL != bounds) {
    833         fInfo.push(SkObjectParser::RectToString(*bounds, "Bounds: "));
    834     }
    835     if (NULL != paint) {
    836         fInfo.push(SkObjectParser::PaintToString(*paint));
    837     }
    838     fInfo.push(SkObjectParser::SaveFlagsToString(flags));
    839 }
    840 
    841 void SkSaveLayerCommand::execute(SkCanvas* canvas) {
    842     canvas->saveLayer(fBounds.isEmpty() ? NULL : &fBounds,
    843                       fPaintPtr,
    844                       fFlags);
    845 }
    846 
    847 void SkSaveLayerCommand::trackSaveState(int* state) {
    848     (*state)++;
    849 }
    850 
    851 SkScaleCommand::SkScaleCommand(SkScalar sx, SkScalar sy) {
    852     fSx = sx;
    853     fSy = sy;
    854     fDrawType = SCALE;
    855 
    856     fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
    857     fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
    858 }
    859 
    860 void SkScaleCommand::execute(SkCanvas* canvas) {
    861     canvas->scale(fSx, fSy);
    862 }
    863 
    864 SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix) {
    865     fMatrix = matrix;
    866     fDrawType = SET_MATRIX;
    867 
    868     fInfo.push(SkObjectParser::MatrixToString(matrix));
    869 }
    870 
    871 void SkSetMatrixCommand::execute(SkCanvas* canvas) {
    872     canvas->setMatrix(fMatrix);
    873 }
    874 
    875 SkSkewCommand::SkSkewCommand(SkScalar sx, SkScalar sy) {
    876     fSx = sx;
    877     fSy = sy;
    878     fDrawType = SKEW;
    879 
    880     fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
    881     fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
    882 }
    883 
    884 void SkSkewCommand::execute(SkCanvas* canvas) {
    885     canvas->skew(fSx, fSy);
    886 }
    887 
    888 SkTranslateCommand::SkTranslateCommand(SkScalar dx, SkScalar dy) {
    889     fDx = dx;
    890     fDy = dy;
    891     fDrawType = TRANSLATE;
    892 
    893     fInfo.push(SkObjectParser::ScalarToString(dx, "SkScalar dx: "));
    894     fInfo.push(SkObjectParser::ScalarToString(dy, "SkScalar dy: "));
    895 }
    896 
    897 void SkTranslateCommand::execute(SkCanvas* canvas) {
    898     canvas->translate(fDx, fDy);
    899 }
    900