blob: 6070867ebc75ae3ddc938b2aa2e2c6861869cae1 [file] [log] [blame]
chudy@google.com902ebe52012-06-29 14:21:22 +00001
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 <iostream>
11#include "SkDebugCanvas.h"
12#include "SkDrawCommand.h"
13
chudy@google.com80a4a602012-07-30 18:54:07 +000014SkDebugCanvas::SkDebugCanvas(int width, int height) {
chudy@google.com902ebe52012-06-29 14:21:22 +000015 // TODO(chudy): Free up memory from all draw commands in destructor.
chudy@google.com80a4a602012-07-30 18:54:07 +000016 fWidth = width;
17 fHeight = height;
chudy@google.comb9ddd4e2012-07-10 14:14:50 +000018 fBm.setConfig(SkBitmap::kNo_Config, fWidth, fHeight);
chudy@google.com902ebe52012-06-29 14:21:22 +000019 this->setBitmapDevice(fBm);
20 fFilter = false;
chudy@google.com830b8792012-08-01 15:57:52 +000021 fIndex = 0;
22 fUserOffset.set(0,0);
23 fUserScale = 1.0;
chudy@google.com902ebe52012-06-29 14:21:22 +000024}
25
26SkDebugCanvas::~SkDebugCanvas() {}
27
28void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
29 commandVector.push_back(command);
30}
31
32void SkDebugCanvas::draw(SkCanvas* canvas) {
33 if(!commandVector.empty()) {
34 for(it = commandVector.begin(); it != commandVector.end(); ++it) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000035 if ((*it)->isVisible()) {
chudy@google.com0ab03392012-07-28 20:16:11 +000036 (*it)->execute(canvas);
37 }
chudy@google.com902ebe52012-06-29 14:21:22 +000038 }
39 }
chudy@google.com830b8792012-08-01 15:57:52 +000040 fIndex = commandVector.size() - 1;
chudy@google.com902ebe52012-06-29 14:21:22 +000041}
42
chudy@google.com830b8792012-08-01 15:57:52 +000043void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
44 canvas->translate(fUserOffset.fX, fUserOffset.fY);
45 if (fUserScale < 0) {
46 canvas->scale((1.0 / -fUserScale), (1.0 / -fUserScale));
47 } else if (fUserScale > 0) {
48 canvas->scale(fUserScale, fUserScale);
49 }
50}
51
52int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000053 SkBitmap bitmap;
54 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
55 bitmap.allocPixels();
chudy@google.com902ebe52012-06-29 14:21:22 +000056
chudy@google.com0b5bbb02012-07-31 19:55:32 +000057 SkCanvas canvas(bitmap);
chudy@google.com830b8792012-08-01 15:57:52 +000058 canvas.translate(-x, -y);
59 applyUserTransform(&canvas);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000060
61 int layer = 0;
chudy@google.com751961d2012-07-31 20:07:42 +000062 SkColor prev = bitmap.getColor(0,0);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000063 for (int i = 0; i < index; i++) {
64 if (commandVector[i]->isVisible()) {
65 commandVector[i]->execute(&canvas);
66 }
67 if (prev != bitmap.getColor(0,0)) {
68 layer = i;
69 }
70 prev = bitmap.getColor(0,0);
71 }
72 return layer;
73}
74
75void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
76 int counter = 0;
77 SkASSERT(!commandVector.empty());
chudy@google.com751961d2012-07-31 20:07:42 +000078 SkASSERT(index < (int)commandVector.size());
chudy@google.com830b8792012-08-01 15:57:52 +000079 int i;
80
81 // This only works assuming the canvas and device are the same ones that
82 // were previously drawn into because they need to preserve all saves
83 // and restores.
84 if (fIndex < index) {
85 i = fIndex + 1;
86 } else {
87 i = 0;
88 canvas->clear(0);
89 canvas->resetMatrix();
90 applyUserTransform(canvas);
91 }
92
93 for (; i <= index; i++) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000094 if (i == index && fFilter) {
95 SkPaint p;
96 p.setColor(0xAAFFFFFF);
97 canvas->save();
98 canvas->resetMatrix();
99 SkRect mask;
100 mask.set(SkIntToScalar(0), SkIntToScalar(0),
101 SkIntToScalar(fWidth), SkIntToScalar(fHeight));
102 canvas->clipRect(mask, SkRegion::kReplace_Op, false);
103 canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
104 SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
105 canvas->restore();
106 }
107
108 if (commandVector[i]->isVisible()) {
109 commandVector[i]->execute(canvas);
chudy@google.com902ebe52012-06-29 14:21:22 +0000110 }
111 }
chudy@google.com830b8792012-08-01 15:57:52 +0000112
113 fIndex = index;
chudy@google.com902ebe52012-06-29 14:21:22 +0000114}
115
116SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000117 SkASSERT(index < (int)commandVector.size());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000118 return commandVector[index];
chudy@google.com902ebe52012-06-29 14:21:22 +0000119}
120
121std::vector<std::string>* SkDebugCanvas::getCommandInfoAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000122 SkASSERT(index < (int)commandVector.size());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000123 return commandVector[index]->Info();
124}
chudy@google.com902ebe52012-06-29 14:21:22 +0000125
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000126bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000127 SkASSERT(index < (int)commandVector.size());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000128 return commandVector[index]->isVisible();
chudy@google.com902ebe52012-06-29 14:21:22 +0000129}
130
131std::vector<SkDrawCommand*> SkDebugCanvas::getDrawCommands() {
132 return commandVector;
133}
134
135// TODO(chudy): Free command string memory.
136std::vector<std::string>* SkDebugCanvas::getDrawCommandsAsStrings() {
137 std::vector<std::string>* commandString = new std::vector<std::string>();
138 if (!commandVector.empty()) {
139 for(it = commandVector.begin(); it != commandVector.end(); ++it) {
140 commandString->push_back((*it)->toString());
141 }
142 }
143 return commandString;
144}
145
146void SkDebugCanvas::toggleFilter(bool toggle) {
147 fFilter = toggle;
148}
149
150void SkDebugCanvas::clear(SkColor color) {
151 addDrawCommand(new Clear(color));
152}
153
154bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
155 addDrawCommand(new ClipPath(path, op, doAA));
156 return true;
157}
158
159bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
160 addDrawCommand(new ClipRect(rect, op, doAA));
161 return true;
162}
163
164bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
165 addDrawCommand(new ClipRegion(region, op));
166 return true;
167}
168
169bool SkDebugCanvas::concat(const SkMatrix& matrix) {
170 addDrawCommand(new Concat(matrix));
171 return true;
172}
173
174void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
175 SkScalar top, const SkPaint* paint = NULL) {
176 addDrawCommand(new DrawBitmap(bitmap, left, top, paint));
177}
178
179void SkDebugCanvas::drawBitmapRect(const SkBitmap& bitmap,
180 const SkIRect* src, const SkRect& dst, const SkPaint* paint) {
181 addDrawCommand(new DrawBitmapRect(bitmap, src, dst, paint));
182}
183
184void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
185 const SkMatrix& matrix, const SkPaint* paint) {
186 addDrawCommand(new DrawBitmapMatrix(bitmap, matrix, paint));
187}
188
189void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
190 const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
191 addDrawCommand(new DrawBitmapNine(bitmap, center, dst, paint));
192}
193
194void SkDebugCanvas::drawData(const void* data, size_t length) {
195 addDrawCommand(new DrawData(data, length));
196}
197
198void SkDebugCanvas::drawPaint(const SkPaint& paint) {
199 addDrawCommand(new DrawPaint(paint));
200}
201
202void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
203 addDrawCommand(new DrawPath(path, paint));
204}
205
206void SkDebugCanvas::drawPicture(SkPicture& picture) {
207 addDrawCommand(new DrawPicture(picture));
208}
209
210void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
211 const SkPoint pts[], const SkPaint& paint) {
212 addDrawCommand(new DrawPoints(mode, count, pts, paint));
213}
214
215void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
216 const SkPoint pos[], const SkPaint& paint) {
217 addDrawCommand(new DrawPosText(text, byteLength, pos, paint));
218}
219
220void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
221 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
222 addDrawCommand(new DrawPosTextH(text, byteLength, xpos, constY, paint));
223}
224
225void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
226 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
227 addDrawCommand(new DrawRectC(rect, paint));
228}
229
230void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
231 const SkPaint* paint = NULL) {
232 addDrawCommand(new DrawSprite(bitmap, left, top, paint));
233}
234
235void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
236 SkScalar y, const SkPaint& paint) {
237 addDrawCommand(new DrawTextC(text, byteLength, x, y, paint));
238}
239
240void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
241 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
242 addDrawCommand(new DrawTextOnPath(text, byteLength, path, matrix, paint));
243}
244
245void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
246 const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
247 SkXfermode*, const uint16_t indices[], int indexCount,
248 const SkPaint& paint) {
249 addDrawCommand(new DrawVertices(vmode, vertexCount, vertices, texs, colors,
250 NULL, indices, indexCount, paint));
251}
252
253void SkDebugCanvas::restore() {
254 addDrawCommand(new Restore());
255}
256
257bool SkDebugCanvas::rotate(SkScalar degrees) {
258 addDrawCommand(new Rotate(degrees));
259 return true;
260}
261
262int SkDebugCanvas::save(SaveFlags flags) {
263 addDrawCommand(new Save(flags));
264 return true;
265}
266
267int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
268 SaveFlags flags) {
269 addDrawCommand(new SaveLayer(bounds, paint, flags));
270 return true;
271}
272
273bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
274 addDrawCommand(new Scale(sx, sy));
275 return true;
276}
277
278void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
279 addDrawCommand(new SetMatrix(matrix));
280}
281
282bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
283 addDrawCommand(new Skew(sx, sy));
284 return true;
285}
286
287bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
288 addDrawCommand(new Translate(dx, dy));
289 return true;
290}
291
chudy@google.com902ebe52012-06-29 14:21:22 +0000292void SkDebugCanvas::toggleCommand(int index, bool toggle) {
chudy@google.com751961d2012-07-31 20:07:42 +0000293 SkASSERT(index < (int)commandVector.size());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000294 commandVector[index]->setVisible(toggle);
chudy@google.com902ebe52012-06-29 14:21:22 +0000295}