SkDebugCanvas.cpp revision 7ce564cccb246ec56427085872b2e1458fe74bd1
1fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
2fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/*
3fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * Copyright 2012 Google Inc.
4fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek *
5fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * Use of this source code is governed by a BSD-style license that can be
6fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * found in the LICENSE file.
7fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek */
8fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
9fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
10fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include "SkColorPriv.h"
11fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include "SkDebugCanvas.h"
12fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include "SkDrawCommand.h"
13fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include "SkDrawFilter.h"
14fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include "SkDevice.h"
157dba8607e59096014b7139ff20ef00870041d518Ted Kremenek#include "SkXfermode.h"
16fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
17fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekstatic SkBitmap make_noconfig_bm(int width, int height) {
18fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkBitmap bm;
19fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    bm.setConfig(SkBitmap::kNo_Config, width, height);
20fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    return bm;
21fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
22fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
237dba8607e59096014b7139ff20ef00870041d518Ted KremenekSkDebugCanvas::SkDebugCanvas(int width, int height)
24fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        : INHERITED(make_noconfig_bm(width, height))
25fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        , fOverdrawViz(false)
26fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        , fOverdrawFilter(NULL)
27fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        , fOverrideTexFiltering(false)
28fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        , fTexOverrideFilter(NULL)
29fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        , fOutstandingSaveCount(0) {
30fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    // TODO(chudy): Free up memory from all draw commands in destructor.
31fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fWidth = width;
32fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fHeight = height;
33fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    // do we need fBm anywhere?
34fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fBm.setConfig(SkBitmap::kNo_Config, fWidth, fHeight);
35fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fFilter = false;
36fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fIndex = 0;
37fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fUserMatrix.reset();
38fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
39fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
40fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted KremenekSkDebugCanvas::~SkDebugCanvas() {
41fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fCommandVector.deleteAll();
42fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkSafeUnref(fOverdrawFilter);
43fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
44fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
45fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekvoid SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
46fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fCommandVector.push(command);
47fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
48fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
49fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekvoid SkDebugCanvas::draw(SkCanvas* canvas) {
50fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    if(!fCommandVector.isEmpty()) {
51fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        for (int i = 0; i < fCommandVector.count(); i++) {
52fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            if (fCommandVector[i]->isVisible()) {
53fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek                fCommandVector[i]->execute(canvas);
54fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            }
55fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
56fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
57fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    fIndex = fCommandVector.count() - 1;
58fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
59fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
60fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekvoid SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
61fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    canvas->concat(fUserMatrix);
62fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
63fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
64fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekint SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
65fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkBitmap bitmap;
66fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
67fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    bitmap.allocPixels();
68fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
69fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkCanvas canvas(bitmap);
70fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y));
71fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    applyUserTransform(&canvas);
72fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
73fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    int layer = 0;
74fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkColor prev = bitmap.getColor(0,0);
75fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    for (int i = 0; i < index; i++) {
76fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        if (fCommandVector[i]->isVisible()) {
77fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            fCommandVector[i]->execute(&canvas);
78fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
79fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        if (prev != bitmap.getColor(0,0)) {
80fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            layer = i;
81fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
82fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        prev = bitmap.getColor(0,0);
83fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
84fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    return layer;
85fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
86fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
87fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekstatic SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) {
88fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    // This table encodes the color progression of the overdraw visualization
89fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    static const SkPMColor gTable[] = {
90fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0x00, 0x00, 0x00, 0x00),
91fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 128, 158, 255),
92fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 170, 185, 212),
93fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 213, 195, 170),
94fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255, 192, 127),
95fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255, 185, 85),
96fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255, 165, 42),
97fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255, 135, 0),
98fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255,  95, 0),
99fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255,  50, 0),
100fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkPackARGB32(0xFF, 255,  0, 0)
101fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    };
102fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
103fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) {
104fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        if (gTable[i] == dst) {
105fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            return gTable[i+1];
106fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
107fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
108fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
109fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    return gTable[SK_ARRAY_COUNT(gTable)-1];
110fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
111fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
112fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// The OverdrawFilter modifies every paint to use an SkProcXfermode which
113fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// in turn invokes OverdrawXferModeProc
114fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekclass SkOverdrawFilter : public SkDrawFilter {
115fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekpublic:
116fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkOverdrawFilter() {
117fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        fXferMode = new SkProcXfermode(OverdrawXferModeProc);
118fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
119fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
120fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    virtual ~SkOverdrawFilter() {
121fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        delete fXferMode;
122fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
123fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
124fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    virtual bool filter(SkPaint* p, Type) SK_OVERRIDE {
125fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        p->setXfermode(fXferMode);
126fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        return true;
127fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
128fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
129fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekprotected:
130fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkXfermode* fXferMode;
131fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
132fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekprivate:
1330cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek    typedef SkDrawFilter INHERITED;
1340cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek};
135fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
136fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// SkTexOverrideFilter modifies every paint to use the specified
137fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// texture filtering mode
138fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekclass SkTexOverrideFilter : public SkDrawFilter {
139fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekpublic:
140fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkTexOverrideFilter() : fFilterLevel(SkPaint::kNone_FilterLevel) {
141fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
142fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
143fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    void setFilterLevel(SkPaint::FilterLevel filterLevel) {
1447dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        fFilterLevel = filterLevel;
1457dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    }
146fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
147fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    virtual bool filter(SkPaint* p, Type) SK_OVERRIDE {
148fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        p->setFilterLevel(fFilterLevel);
149fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        return true;
150fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
151fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
152fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekprotected:
153fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    SkPaint::FilterLevel fFilterLevel;
154fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
155fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekprivate:
156fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    typedef SkDrawFilter INHERITED;
157fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek};
158fa2be43dbd6fdc4414e261db69aaf35dfb21a416Ted Kremenek
159504927ac167053f3b5c2ae38c7ee3fa55bbf3a6cTed Kremenekvoid SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
16019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    SkASSERT(!fCommandVector.isEmpty());
16119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    SkASSERT(index < fCommandVector.count());
162fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    int i;
163fa2be43dbd6fdc4414e261db69aaf35dfb21a416Ted Kremenek
164fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    // This only works assuming the canvas and device are the same ones that
16519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    // were previously drawn into because they need to preserve all saves
166fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    // and restores.
167fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    if (fIndex < index) {
168fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        i = fIndex + 1;
169fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    } else {
170fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        for (int j = 0; j < fOutstandingSaveCount; j++) {
171fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            canvas->restore();
172fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
173fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        i = 0;
17419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek        canvas->clear(SK_ColorTRANSPARENT);
17519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek        canvas->resetMatrix();
176fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth),
17719bb356317952445b03ee341c02f6147083c9eeaTed Kremenek                                     SkIntToScalar(fHeight));
17819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek        canvas->clipRect(rect, SkRegion::kReplace_Op );
17919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek        applyUserTransform(canvas);
18019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek        fOutstandingSaveCount = 0;
181fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
18219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek
18319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    // The setting of the draw filter has to go here (rather than in
18419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    // SkRasterWidget) due to the canvas restores this class performs.
18519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    // Since the draw filter is stored in the layer stack if we
186fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    // call setDrawFilter on anything but the root layer odd things happen.
18719bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    if (fOverdrawViz) {
1887dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        if (NULL == fOverdrawFilter) {
18919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek            fOverdrawFilter = new SkOverdrawFilter;
1907dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        }
1917dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
1927dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        if (fOverdrawFilter != canvas->getDrawFilter()) {
1937dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->setDrawFilter(fOverdrawFilter);
194fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
195fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    } else if (fOverrideTexFiltering) {
196fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        if (NULL == fTexOverrideFilter) {
197504927ac167053f3b5c2ae38c7ee3fa55bbf3a6cTed Kremenek            fTexOverrideFilter = new SkTexOverrideFilter;
198504927ac167053f3b5c2ae38c7ee3fa55bbf3a6cTed Kremenek        }
1997dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2007dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        if (fTexOverrideFilter != canvas->getDrawFilter()) {
2017dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->setDrawFilter(fTexOverrideFilter);
20219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek        }
20319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    } else {
204fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        canvas->setDrawFilter(NULL);
205fa2be43dbd6fdc4414e261db69aaf35dfb21a416Ted Kremenek    }
2067dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2077dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    for (; i <= index; i++) {
2087dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        if (i == index && fFilter) {
2097dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            SkPaint p;
2107dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            p.setColor(0xAAFFFFFF);
2117dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->save();
2127dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->resetMatrix();
2137dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            SkRect mask;
2147dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            mask.set(SkIntToScalar(0), SkIntToScalar(0),
2157dba8607e59096014b7139ff20ef00870041d518Ted Kremenek                    SkIntToScalar(fWidth), SkIntToScalar(fHeight));
2167dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->clipRect(mask, SkRegion::kReplace_Op, false);
2177dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
2187dba8607e59096014b7139ff20ef00870041d518Ted Kremenek                    SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
2197dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            canvas->restore();
2207dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        }
2217dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2227dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        if (fCommandVector[i]->isVisible()) {
2237dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            fCommandVector[i]->execute(canvas);
2247dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            fCommandVector[i]->trackSaveState(&fOutstandingSaveCount);
2257dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        }
2267dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    }
2277dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fMatrix = canvas->getTotalMatrix();
2287dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fClip = canvas->getTotalClip().getBounds();
2297dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fIndex = index;
2307dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2317dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2327dba8607e59096014b7139ff20ef00870041d518Ted Kremenekvoid SkDebugCanvas::deleteDrawCommandAt(int index) {
2337dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    SkASSERT(index < fCommandVector.count());
2347dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    delete fCommandVector[index];
2357dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fCommandVector.remove(index);
2367dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2377dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2387dba8607e59096014b7139ff20ef00870041d518Ted KremenekSkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
2397dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    SkASSERT(index < fCommandVector.count());
2407dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return fCommandVector[index];
2417dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2427dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2437dba8607e59096014b7139ff20ef00870041d518Ted Kremenekvoid SkDebugCanvas::setDrawCommandAt(int index, SkDrawCommand* command) {
2447dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    SkASSERT(index < fCommandVector.count());
2457dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    delete fCommandVector[index];
2467dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fCommandVector[index] = command;
2477dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2487dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2497dba8607e59096014b7139ff20ef00870041d518Ted KremenekSkTDArray<SkString*>* SkDebugCanvas::getCommandInfo(int index) {
2507dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    SkASSERT(index < fCommandVector.count());
2517dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return fCommandVector[index]->Info();
2527dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2537dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2547dba8607e59096014b7139ff20ef00870041d518Ted Kremenekbool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
2557dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    SkASSERT(index < fCommandVector.count());
2567dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return fCommandVector[index]->isVisible();
2577dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2587dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2597dba8607e59096014b7139ff20ef00870041d518Ted Kremenekconst SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const {
2607dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return fCommandVector;
2617dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2627dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2637dba8607e59096014b7139ff20ef00870041d518Ted KremenekSkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() {
2647dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return fCommandVector;
2657dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2667dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2677dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// TODO(chudy): Free command string memory.
2687dba8607e59096014b7139ff20ef00870041d518Ted KremenekSkTArray<SkString>* SkDebugCanvas::getDrawCommandsAsStrings() const {
2697dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    SkTArray<SkString>* commandString = new SkTArray<SkString>(fCommandVector.count());
2707dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    if (!fCommandVector.isEmpty()) {
2717dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        for (int i = 0; i < fCommandVector.count(); i ++) {
2727dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            commandString->push_back() = fCommandVector[i]->toString();
2737dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        }
2747dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    }
2757dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return commandString;
2767dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2777dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2787dba8607e59096014b7139ff20ef00870041d518Ted Kremenekvoid SkDebugCanvas::toggleFilter(bool toggle) {
2797dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fFilter = toggle;
2807dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
2817dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2827dba8607e59096014b7139ff20ef00870041d518Ted Kremenekvoid SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level) {
2837dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    if (NULL == fTexOverrideFilter) {
2847dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        fTexOverrideFilter = new SkTexOverrideFilter;
2857dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    }
2867dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2877dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fOverrideTexFiltering = overrideTexFiltering;
2887dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    fTexOverrideFilter->setFilterLevel(level);
2897dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}
290
291void SkDebugCanvas::clear(SkColor color) {
292    addDrawCommand(new SkClearCommand(color));
293}
294
295bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
296    addDrawCommand(new SkClipPathCommand(path, op, doAA));
297    return true;
298}
299
300bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
301    addDrawCommand(new SkClipRectCommand(rect, op, doAA));
302    return true;
303}
304
305bool SkDebugCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
306    addDrawCommand(new SkClipRRectCommand(rrect, op, doAA));
307    return true;
308}
309
310bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
311    addDrawCommand(new SkClipRegionCommand(region, op));
312    return true;
313}
314
315bool SkDebugCanvas::concat(const SkMatrix& matrix) {
316    addDrawCommand(new SkConcatCommand(matrix));
317    return true;
318}
319
320void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
321                               SkScalar top, const SkPaint* paint = NULL) {
322    addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint));
323}
324
325void SkDebugCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
326                                         const SkRect* src, const SkRect& dst,
327                                         const SkPaint* paint,
328                                         SkCanvas::DrawBitmapRectFlags flags) {
329    addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags));
330}
331
332void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
333                                     const SkMatrix& matrix, const SkPaint* paint) {
334    addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint));
335}
336
337void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
338        const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
339    addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint));
340}
341
342void SkDebugCanvas::drawData(const void* data, size_t length) {
343    addDrawCommand(new SkDrawDataCommand(data, length));
344}
345
346void SkDebugCanvas::beginCommentGroup(const char* description) {
347    addDrawCommand(new SkBeginCommentGroupCommand(description));
348}
349
350void SkDebugCanvas::addComment(const char* kywd, const char* value) {
351    addDrawCommand(new SkCommentCommand(kywd, value));
352}
353
354void SkDebugCanvas::endCommentGroup() {
355    addDrawCommand(new SkEndCommentGroupCommand());
356}
357
358void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
359    addDrawCommand(new SkDrawOvalCommand(oval, paint));
360}
361
362void SkDebugCanvas::drawPaint(const SkPaint& paint) {
363    addDrawCommand(new SkDrawPaintCommand(paint));
364}
365
366void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
367    addDrawCommand(new SkDrawPathCommand(path, paint));
368}
369
370void SkDebugCanvas::drawPicture(SkPicture& picture) {
371    addDrawCommand(new SkDrawPictureCommand(picture));
372}
373
374void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
375                               const SkPoint pts[], const SkPaint& paint) {
376    addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint));
377}
378
379void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
380        const SkPoint pos[], const SkPaint& paint) {
381    addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint));
382}
383
384void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
385        const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
386    addDrawCommand(
387        new SkDrawPosTextHCommand(text, byteLength, xpos, constY, paint));
388}
389
390void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
391    // NOTE(chudy): Messing up when renamed to DrawRect... Why?
392    addDrawCommand(new SkDrawRectCommand(rect, paint));
393}
394
395void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
396    addDrawCommand(new SkDrawRRectCommand(rrect, paint));
397}
398
399void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
400                               const SkPaint* paint = NULL) {
401    addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint));
402}
403
404void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
405        SkScalar y, const SkPaint& paint) {
406    addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint));
407}
408
409void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
410        const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
411    addDrawCommand(
412        new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint));
413}
414
415void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
416        const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
417        SkXfermode*, const uint16_t indices[], int indexCount,
418        const SkPaint& paint) {
419    addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices,
420                   texs, colors, NULL, indices, indexCount, paint));
421}
422
423void SkDebugCanvas::restore() {
424    addDrawCommand(new SkRestoreCommand());
425}
426
427bool SkDebugCanvas::rotate(SkScalar degrees) {
428    addDrawCommand(new SkRotateCommand(degrees));
429    return true;
430}
431
432int SkDebugCanvas::save(SaveFlags flags) {
433    addDrawCommand(new SkSaveCommand(flags));
434    return true;
435}
436
437int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
438        SaveFlags flags) {
439    addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags));
440    return true;
441}
442
443bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
444    addDrawCommand(new SkScaleCommand(sx, sy));
445    return true;
446}
447
448void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
449    addDrawCommand(new SkSetMatrixCommand(matrix));
450}
451
452bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
453    addDrawCommand(new SkSkewCommand(sx, sy));
454    return true;
455}
456
457bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
458    addDrawCommand(new SkTranslateCommand(dx, dy));
459    return true;
460}
461
462void SkDebugCanvas::toggleCommand(int index, bool toggle) {
463    SkASSERT(index < fCommandVector.count());
464    fCommandVector[index]->setVisible(toggle);
465}
466