blob: 4751be7722642a60be9183f0bacf10d3cf533966 [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
chudy@google.com9cda6f72012-08-07 15:08:33 +000026SkDebugCanvas::~SkDebugCanvas() {
chudy@google.com97cee972012-08-07 20:41:37 +000027 commandVector.deleteAll();
chudy@google.com9cda6f72012-08-07 15:08:33 +000028}
chudy@google.com902ebe52012-06-29 14:21:22 +000029
30void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
chudy@google.com97cee972012-08-07 20:41:37 +000031 commandVector.push(command);
chudy@google.com902ebe52012-06-29 14:21:22 +000032}
33
34void SkDebugCanvas::draw(SkCanvas* canvas) {
chudy@google.com97cee972012-08-07 20:41:37 +000035 if(!commandVector.isEmpty()) {
36 for (int i = 0; i < commandVector.count(); i++) {
37 if (commandVector[i]->isVisible()) {
38 commandVector[i]->execute(canvas);
chudy@google.com0ab03392012-07-28 20:16:11 +000039 }
chudy@google.com902ebe52012-06-29 14:21:22 +000040 }
41 }
chudy@google.com97cee972012-08-07 20:41:37 +000042 fIndex = commandVector.count() - 1;
chudy@google.com902ebe52012-06-29 14:21:22 +000043}
44
chudy@google.com830b8792012-08-01 15:57:52 +000045void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
46 canvas->translate(fUserOffset.fX, fUserOffset.fY);
47 if (fUserScale < 0) {
48 canvas->scale((1.0 / -fUserScale), (1.0 / -fUserScale));
49 } else if (fUserScale > 0) {
50 canvas->scale(fUserScale, fUserScale);
51 }
52}
53
54int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000055 SkBitmap bitmap;
56 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
57 bitmap.allocPixels();
chudy@google.com902ebe52012-06-29 14:21:22 +000058
chudy@google.com0b5bbb02012-07-31 19:55:32 +000059 SkCanvas canvas(bitmap);
chudy@google.com830b8792012-08-01 15:57:52 +000060 canvas.translate(-x, -y);
61 applyUserTransform(&canvas);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000062
63 int layer = 0;
chudy@google.com751961d2012-07-31 20:07:42 +000064 SkColor prev = bitmap.getColor(0,0);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000065 for (int i = 0; i < index; i++) {
66 if (commandVector[i]->isVisible()) {
67 commandVector[i]->execute(&canvas);
68 }
69 if (prev != bitmap.getColor(0,0)) {
70 layer = i;
71 }
72 prev = bitmap.getColor(0,0);
73 }
74 return layer;
75}
76
77void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
78 int counter = 0;
chudy@google.com97cee972012-08-07 20:41:37 +000079 SkASSERT(!commandVector.isEmpty());
80 SkASSERT(index < commandVector.count());
chudy@google.com830b8792012-08-01 15:57:52 +000081 int i;
82
83 // This only works assuming the canvas and device are the same ones that
84 // were previously drawn into because they need to preserve all saves
85 // and restores.
86 if (fIndex < index) {
87 i = fIndex + 1;
88 } else {
89 i = 0;
90 canvas->clear(0);
91 canvas->resetMatrix();
chudy@google.com4c7962e2012-08-14 19:38:31 +000092 SkRect rect = SkRect::MakeWH(fWidth, fHeight);
93 canvas->clipRect(rect, SkRegion::kReplace_Op );
chudy@google.com830b8792012-08-01 15:57:52 +000094 applyUserTransform(canvas);
95 }
96
97 for (; i <= index; i++) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000098 if (i == index && fFilter) {
99 SkPaint p;
100 p.setColor(0xAAFFFFFF);
101 canvas->save();
102 canvas->resetMatrix();
103 SkRect mask;
104 mask.set(SkIntToScalar(0), SkIntToScalar(0),
105 SkIntToScalar(fWidth), SkIntToScalar(fHeight));
106 canvas->clipRect(mask, SkRegion::kReplace_Op, false);
107 canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
108 SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
109 canvas->restore();
110 }
111
112 if (commandVector[i]->isVisible()) {
113 commandVector[i]->execute(canvas);
chudy@google.com902ebe52012-06-29 14:21:22 +0000114 }
115 }
chudy@google.coma9e937c2012-08-03 17:32:05 +0000116 fMatrix = canvas->getTotalMatrix();
117 fClip = canvas->getTotalClip().getBounds();
chudy@google.com830b8792012-08-01 15:57:52 +0000118 fIndex = index;
chudy@google.com902ebe52012-06-29 14:21:22 +0000119}
120
121SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
chudy@google.com97cee972012-08-07 20:41:37 +0000122 SkASSERT(index < commandVector.count());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000123 return commandVector[index];
chudy@google.com902ebe52012-06-29 14:21:22 +0000124}
125
chudy@google.com97cee972012-08-07 20:41:37 +0000126SkTDArray<SkString*>* SkDebugCanvas::getCommandInfo(int index) {
127 SkASSERT(index < commandVector.count());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000128 return commandVector[index]->Info();
129}
chudy@google.com902ebe52012-06-29 14:21:22 +0000130
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000131bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
chudy@google.com97cee972012-08-07 20:41:37 +0000132 SkASSERT(index < commandVector.count());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000133 return commandVector[index]->isVisible();
chudy@google.com902ebe52012-06-29 14:21:22 +0000134}
135
chudy@google.com97cee972012-08-07 20:41:37 +0000136SkTDArray <SkDrawCommand*> SkDebugCanvas::getDrawCommands() {
chudy@google.com902ebe52012-06-29 14:21:22 +0000137 return commandVector;
138}
139
140// TODO(chudy): Free command string memory.
chudy@google.com97cee972012-08-07 20:41:37 +0000141SkTDArray<SkString*>* SkDebugCanvas::getDrawCommandsAsStrings() {
142 SkTDArray<SkString*>* commandString = new SkTDArray<SkString*>();
143 if (!commandVector.isEmpty()) {
144 for (int i = 0; i < commandVector.count(); i ++) {
145 commandString->push(new SkString(commandVector[i]->toString()));
chudy@google.com902ebe52012-06-29 14:21:22 +0000146 }
147 }
148 return commandString;
149}
150
151void SkDebugCanvas::toggleFilter(bool toggle) {
152 fFilter = toggle;
153}
154
155void SkDebugCanvas::clear(SkColor color) {
156 addDrawCommand(new Clear(color));
157}
158
159bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
160 addDrawCommand(new ClipPath(path, op, doAA));
161 return true;
162}
163
164bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
165 addDrawCommand(new ClipRect(rect, op, doAA));
166 return true;
167}
168
169bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
170 addDrawCommand(new ClipRegion(region, op));
171 return true;
172}
173
174bool SkDebugCanvas::concat(const SkMatrix& matrix) {
175 addDrawCommand(new Concat(matrix));
176 return true;
177}
178
179void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
180 SkScalar top, const SkPaint* paint = NULL) {
181 addDrawCommand(new DrawBitmap(bitmap, left, top, paint));
182}
183
184void SkDebugCanvas::drawBitmapRect(const SkBitmap& bitmap,
185 const SkIRect* src, const SkRect& dst, const SkPaint* paint) {
186 addDrawCommand(new DrawBitmapRect(bitmap, src, dst, paint));
187}
188
189void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
190 const SkMatrix& matrix, const SkPaint* paint) {
191 addDrawCommand(new DrawBitmapMatrix(bitmap, matrix, paint));
192}
193
194void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
195 const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
196 addDrawCommand(new DrawBitmapNine(bitmap, center, dst, paint));
197}
198
199void SkDebugCanvas::drawData(const void* data, size_t length) {
200 addDrawCommand(new DrawData(data, length));
201}
202
203void SkDebugCanvas::drawPaint(const SkPaint& paint) {
204 addDrawCommand(new DrawPaint(paint));
205}
206
207void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
208 addDrawCommand(new DrawPath(path, paint));
209}
210
211void SkDebugCanvas::drawPicture(SkPicture& picture) {
212 addDrawCommand(new DrawPicture(picture));
213}
214
215void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
216 const SkPoint pts[], const SkPaint& paint) {
217 addDrawCommand(new DrawPoints(mode, count, pts, paint));
218}
219
220void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
221 const SkPoint pos[], const SkPaint& paint) {
222 addDrawCommand(new DrawPosText(text, byteLength, pos, paint));
223}
224
225void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
226 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
227 addDrawCommand(new DrawPosTextH(text, byteLength, xpos, constY, paint));
228}
229
230void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
231 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
232 addDrawCommand(new DrawRectC(rect, paint));
233}
234
235void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
236 const SkPaint* paint = NULL) {
237 addDrawCommand(new DrawSprite(bitmap, left, top, paint));
238}
239
240void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
241 SkScalar y, const SkPaint& paint) {
242 addDrawCommand(new DrawTextC(text, byteLength, x, y, paint));
243}
244
245void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
246 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
247 addDrawCommand(new DrawTextOnPath(text, byteLength, path, matrix, paint));
248}
249
250void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
251 const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
252 SkXfermode*, const uint16_t indices[], int indexCount,
253 const SkPaint& paint) {
254 addDrawCommand(new DrawVertices(vmode, vertexCount, vertices, texs, colors,
255 NULL, indices, indexCount, paint));
256}
257
258void SkDebugCanvas::restore() {
259 addDrawCommand(new Restore());
260}
261
262bool SkDebugCanvas::rotate(SkScalar degrees) {
263 addDrawCommand(new Rotate(degrees));
264 return true;
265}
266
267int SkDebugCanvas::save(SaveFlags flags) {
268 addDrawCommand(new Save(flags));
269 return true;
270}
271
272int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
273 SaveFlags flags) {
274 addDrawCommand(new SaveLayer(bounds, paint, flags));
275 return true;
276}
277
278bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
279 addDrawCommand(new Scale(sx, sy));
280 return true;
281}
282
283void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
284 addDrawCommand(new SetMatrix(matrix));
285}
286
287bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
288 addDrawCommand(new Skew(sx, sy));
289 return true;
290}
291
292bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
293 addDrawCommand(new Translate(dx, dy));
294 return true;
295}
296
chudy@google.com902ebe52012-06-29 14:21:22 +0000297void SkDebugCanvas::toggleCommand(int index, bool toggle) {
chudy@google.com97cee972012-08-07 20:41:37 +0000298 SkASSERT(index < commandVector.count());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000299 commandVector[index]->setVisible(toggle);
chudy@google.com902ebe52012-06-29 14:21:22 +0000300}