SkDebugCanvas.cpp revision 7475811143e190e172bf83d13c4bdba85704b604
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2012 Google Inc.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkColorPriv.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkDebugCanvas.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkDrawCommand.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkDrawFilter.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkDevice.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkXfermode.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SkBitmap make_noconfig_bm(int width, int height) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkBitmap bm;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bm.setConfig(SkBitmap::kNo_Config, width, height);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bm;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkDebugCanvas::SkDebugCanvas(int width, int height)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : INHERITED(make_noconfig_bm(width, height))
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        , fOverdrawViz(false)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        , fOverdrawFilter(NULL)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        , fOutstandingSaveCount(0) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(chudy): Free up memory from all draw commands in destructor.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fWidth = width;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fHeight = height;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // do we need fBm anywhere?
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    fBm.setConfig(SkBitmap::kNo_Config, fWidth, fHeight);
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    fFilter = false;
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    fIndex = 0;
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fUserMatrix.reset();
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SkDebugCanvas::~SkDebugCanvas() {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fCommandVector.deleteAll();
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    SkSafeUnref(fOverdrawFilter);
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fCommandVector.push(command);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::draw(SkCanvas* canvas) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(!fCommandVector.isEmpty()) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < fCommandVector.count(); i++) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (fCommandVector[i]->isVisible()) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                fCommandVector[i]->execute(canvas);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fIndex = fCommandVector.count() - 1;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->concat(fUserMatrix);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkBitmap bitmap;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap.allocPixels();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas canvas(bitmap);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    applyUserTransform(&canvas);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int layer = 0;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColor prev = bitmap.getColor(0,0);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < index; i++) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (fCommandVector[i]->isVisible()) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fCommandVector[i]->execute(&canvas);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (prev != bitmap.getColor(0,0)) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            layer = i;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        prev = bitmap.getColor(0,0);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return layer;
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) {
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // This table encodes the color progression of the overdraw visualization
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    static const SkPMColor gTable[] = {
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        SkPackARGB32(0x00, 0x00, 0x00, 0x00),
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        SkPackARGB32(0xFF, 128, 158, 255),
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SkPackARGB32(0xFF, 170, 185, 212),
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SkPackARGB32(0xFF, 213, 195, 170),
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SkPackARGB32(0xFF, 255, 192, 127),
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SkPackARGB32(0xFF, 255, 185, 85),
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SkPackARGB32(0xFF, 255, 165, 42),
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SkPackARGB32(0xFF, 255, 135, 0),
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SkPackARGB32(0xFF, 255,  95, 0),
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        SkPackARGB32(0xFF, 255,  50, 0),
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        SkPackARGB32(0xFF, 255,  0, 0)
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    };
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) {
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if (gTable[i] == dst) {
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            return gTable[i+1];
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return gTable[SK_ARRAY_COUNT(gTable)-1];
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The OverdrawFilter modifies every paint to use an SkProcXfermode which
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// in turn invokes OverdrawXferModeProc
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass OverdrawFilter : public SkDrawFilter {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OverdrawFilter() {
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fXferMode = new SkProcXfermode(OverdrawXferModeProc);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual ~OverdrawFilter() {
1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        delete fXferMode;
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual bool filter(SkPaint* p, Type) SK_OVERRIDE {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        p->setXfermode(fXferMode);
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return true;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochprotected:
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SkXfermode* fXferMode;
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochprivate:
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    typedef SkDrawFilter INHERITED;
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkASSERT(!fCommandVector.isEmpty());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkASSERT(index < fCommandVector.count());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This only works assuming the canvas and device are the same ones that
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // were previously drawn into because they need to preserve all saves
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and restores.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fIndex < index) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        i = fIndex + 1;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int j = 0; j < fOutstandingSaveCount; j++) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->restore();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        i = 0;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canvas->clear(SK_ColorTRANSPARENT);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canvas->resetMatrix();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SkIntToScalar(fHeight));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canvas->clipRect(rect, SkRegion::kReplace_Op );
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        applyUserTransform(canvas);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fOutstandingSaveCount = 0;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The setting of the draw filter has to go here (rather than in
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SkRasterWidget) due to the canvas restores this class performs.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since the draw filter is stored in the layer stack if we
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // call setDrawFilter on anything but the root layer odd things happen.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fOverdrawViz) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (NULL == fOverdrawFilter) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fOverdrawFilter = new OverdrawFilter;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (fOverdrawFilter != canvas->getDrawFilter()) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->setDrawFilter(fOverdrawFilter);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canvas->setDrawFilter(NULL);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (; i <= index; i++) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (i == index && fFilter) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkPaint p;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            p.setColor(0xAAFFFFFF);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->save();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->resetMatrix();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkRect mask;
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            mask.set(SkIntToScalar(0), SkIntToScalar(0),
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkIntToScalar(fWidth), SkIntToScalar(fHeight));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->clipRect(mask, SkRegion::kReplace_Op, false);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->restore();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (fCommandVector[i]->isVisible()) {
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            fCommandVector[i]->execute(canvas);
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            fCommandVector[i]->trackSaveState(&fOutstandingSaveCount);
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        }
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    fMatrix = canvas->getTotalMatrix();
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    fClip = canvas->getTotalClip().getBounds();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fIndex = index;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::deleteDrawCommandAt(int index) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkASSERT(index < fCommandVector.count());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete fCommandVector[index];
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fCommandVector.remove(index);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkASSERT(index < fCommandVector.count());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fCommandVector[index];
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::setDrawCommandAt(int index, SkDrawCommand* command) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkASSERT(index < fCommandVector.count());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete fCommandVector[index];
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fCommandVector[index] = command;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkTDArray<SkString*>* SkDebugCanvas::getCommandInfo(int index) {
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SkASSERT(index < fCommandVector.count());
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return fCommandVector[index]->Info();
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    SkASSERT(index < fCommandVector.count());
223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return fCommandVector[index]->isVisible();
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const {
2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return fCommandVector;
2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fCommandVector;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(chudy): Free command string memory.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkTArray<SkString>* SkDebugCanvas::getDrawCommandsAsStrings() const {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkTArray<SkString>* commandString = new SkTArray<SkString>(fCommandVector.count());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!fCommandVector.isEmpty()) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < fCommandVector.count(); i ++) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            commandString->push_back() = fCommandVector[i]->toString();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return commandString;
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SkDebugCanvas::toggleFilter(bool toggle) {
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    fFilter = toggle;
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::clear(SkColor color) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addDrawCommand(new SkClearCommand(color));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addDrawCommand(new SkClipPathCommand(path, op, doAA));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addDrawCommand(new SkClipRectCommand(rect, op, doAA));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkDebugCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addDrawCommand(new SkClipRRectCommand(rrect, op, doAA));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addDrawCommand(new SkClipRegionCommand(region, op));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkDebugCanvas::concat(const SkMatrix& matrix) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addDrawCommand(new SkConcatCommand(matrix));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SkScalar top, const SkPaint* paint = NULL) {
280    addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint));
281}
282
283void SkDebugCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
284                                         const SkRect* src, const SkRect& dst,
285                                         const SkPaint* paint,
286                                         SkCanvas::DrawBitmapRectFlags flags) {
287    addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags));
288}
289
290void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
291                                     const SkMatrix& matrix, const SkPaint* paint) {
292    addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint));
293}
294
295void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
296        const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
297    addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint));
298}
299
300void SkDebugCanvas::drawData(const void* data, size_t length) {
301    addDrawCommand(new SkDrawDataCommand(data, length));
302}
303
304void SkDebugCanvas::beginCommentGroup(const char* description) {
305    addDrawCommand(new SkBeginCommentGroupCommand(description));
306}
307
308void SkDebugCanvas::addComment(const char* kywd, const char* value) {
309    addDrawCommand(new SkCommentCommand(kywd, value));
310}
311
312void SkDebugCanvas::endCommentGroup() {
313    addDrawCommand(new SkEndCommentGroupCommand());
314}
315
316void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
317    addDrawCommand(new SkDrawOvalCommand(oval, paint));
318}
319
320void SkDebugCanvas::drawPaint(const SkPaint& paint) {
321    addDrawCommand(new SkDrawPaintCommand(paint));
322}
323
324void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
325    addDrawCommand(new SkDrawPathCommand(path, paint));
326}
327
328void SkDebugCanvas::drawPicture(SkPicture& picture) {
329    addDrawCommand(new SkDrawPictureCommand(picture));
330}
331
332void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
333                               const SkPoint pts[], const SkPaint& paint) {
334    addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint));
335}
336
337void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
338        const SkPoint pos[], const SkPaint& paint) {
339    addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint));
340}
341
342void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
343        const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
344    addDrawCommand(
345        new SkDrawPosTextHCommand(text, byteLength, xpos, constY, paint));
346}
347
348void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
349    // NOTE(chudy): Messing up when renamed to DrawRect... Why?
350    addDrawCommand(new SkDrawRectCommand(rect, paint));
351}
352
353void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
354    addDrawCommand(new SkDrawRRectCommand(rrect, paint));
355}
356
357void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
358                               const SkPaint* paint = NULL) {
359    addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint));
360}
361
362void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
363        SkScalar y, const SkPaint& paint) {
364    addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint));
365}
366
367void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
368        const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
369    addDrawCommand(
370        new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint));
371}
372
373void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
374        const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
375        SkXfermode*, const uint16_t indices[], int indexCount,
376        const SkPaint& paint) {
377    addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices,
378                   texs, colors, NULL, indices, indexCount, paint));
379}
380
381void SkDebugCanvas::restore() {
382    addDrawCommand(new SkRestoreCommand());
383}
384
385bool SkDebugCanvas::rotate(SkScalar degrees) {
386    addDrawCommand(new SkRotateCommand(degrees));
387    return true;
388}
389
390int SkDebugCanvas::save(SaveFlags flags) {
391    addDrawCommand(new SkSaveCommand(flags));
392    return true;
393}
394
395int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
396        SaveFlags flags) {
397    addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags));
398    return true;
399}
400
401bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
402    addDrawCommand(new SkScaleCommand(sx, sy));
403    return true;
404}
405
406void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
407    addDrawCommand(new SkSetMatrixCommand(matrix));
408}
409
410bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
411    addDrawCommand(new SkSkewCommand(sx, sy));
412    return true;
413}
414
415bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
416    addDrawCommand(new SkTranslateCommand(dx, dy));
417    return true;
418}
419
420void SkDebugCanvas::toggleCommand(int index, bool toggle) {
421    SkASSERT(index < fCommandVector.count());
422    fCommandVector[index]->setVisible(toggle);
423}
424