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