blob: 47734b1bd933ff6e7d82b0d1d5b2214d163a83eb [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.coma9e937c2012-08-03 17:32:05 +0000112 fMatrix = canvas->getTotalMatrix();
113 fClip = canvas->getTotalClip().getBounds();
chudy@google.com830b8792012-08-01 15:57:52 +0000114 fIndex = index;
chudy@google.com902ebe52012-06-29 14:21:22 +0000115}
116
117SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000118 SkASSERT(index < (int)commandVector.size());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000119 return commandVector[index];
chudy@google.com902ebe52012-06-29 14:21:22 +0000120}
121
122std::vector<std::string>* SkDebugCanvas::getCommandInfoAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000123 SkASSERT(index < (int)commandVector.size());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000124 return commandVector[index]->Info();
125}
chudy@google.com902ebe52012-06-29 14:21:22 +0000126
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000127bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000128 SkASSERT(index < (int)commandVector.size());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000129 return commandVector[index]->isVisible();
chudy@google.com902ebe52012-06-29 14:21:22 +0000130}
131
132std::vector<SkDrawCommand*> SkDebugCanvas::getDrawCommands() {
133 return commandVector;
134}
135
136// TODO(chudy): Free command string memory.
137std::vector<std::string>* SkDebugCanvas::getDrawCommandsAsStrings() {
138 std::vector<std::string>* commandString = new std::vector<std::string>();
139 if (!commandVector.empty()) {
140 for(it = commandVector.begin(); it != commandVector.end(); ++it) {
141 commandString->push_back((*it)->toString());
142 }
143 }
144 return commandString;
145}
146
147void SkDebugCanvas::toggleFilter(bool toggle) {
148 fFilter = toggle;
149}
150
151void SkDebugCanvas::clear(SkColor color) {
152 addDrawCommand(new Clear(color));
153}
154
155bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
156 addDrawCommand(new ClipPath(path, op, doAA));
157 return true;
158}
159
160bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
161 addDrawCommand(new ClipRect(rect, op, doAA));
162 return true;
163}
164
165bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
166 addDrawCommand(new ClipRegion(region, op));
167 return true;
168}
169
170bool SkDebugCanvas::concat(const SkMatrix& matrix) {
171 addDrawCommand(new Concat(matrix));
172 return true;
173}
174
175void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
176 SkScalar top, const SkPaint* paint = NULL) {
177 addDrawCommand(new DrawBitmap(bitmap, left, top, paint));
178}
179
180void SkDebugCanvas::drawBitmapRect(const SkBitmap& bitmap,
181 const SkIRect* src, const SkRect& dst, const SkPaint* paint) {
182 addDrawCommand(new DrawBitmapRect(bitmap, src, dst, paint));
183}
184
185void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
186 const SkMatrix& matrix, const SkPaint* paint) {
187 addDrawCommand(new DrawBitmapMatrix(bitmap, matrix, paint));
188}
189
190void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
191 const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
192 addDrawCommand(new DrawBitmapNine(bitmap, center, dst, paint));
193}
194
195void SkDebugCanvas::drawData(const void* data, size_t length) {
196 addDrawCommand(new DrawData(data, length));
197}
198
199void SkDebugCanvas::drawPaint(const SkPaint& paint) {
200 addDrawCommand(new DrawPaint(paint));
201}
202
203void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
204 addDrawCommand(new DrawPath(path, paint));
205}
206
207void SkDebugCanvas::drawPicture(SkPicture& picture) {
208 addDrawCommand(new DrawPicture(picture));
209}
210
211void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
212 const SkPoint pts[], const SkPaint& paint) {
213 addDrawCommand(new DrawPoints(mode, count, pts, paint));
214}
215
216void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
217 const SkPoint pos[], const SkPaint& paint) {
218 addDrawCommand(new DrawPosText(text, byteLength, pos, paint));
219}
220
221void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
222 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
223 addDrawCommand(new DrawPosTextH(text, byteLength, xpos, constY, paint));
224}
225
226void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
227 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
228 addDrawCommand(new DrawRectC(rect, paint));
229}
230
231void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
232 const SkPaint* paint = NULL) {
233 addDrawCommand(new DrawSprite(bitmap, left, top, paint));
234}
235
236void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
237 SkScalar y, const SkPaint& paint) {
238 addDrawCommand(new DrawTextC(text, byteLength, x, y, paint));
239}
240
241void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
242 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
243 addDrawCommand(new DrawTextOnPath(text, byteLength, path, matrix, paint));
244}
245
246void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
247 const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
248 SkXfermode*, const uint16_t indices[], int indexCount,
249 const SkPaint& paint) {
250 addDrawCommand(new DrawVertices(vmode, vertexCount, vertices, texs, colors,
251 NULL, indices, indexCount, paint));
252}
253
254void SkDebugCanvas::restore() {
255 addDrawCommand(new Restore());
256}
257
258bool SkDebugCanvas::rotate(SkScalar degrees) {
259 addDrawCommand(new Rotate(degrees));
260 return true;
261}
262
263int SkDebugCanvas::save(SaveFlags flags) {
264 addDrawCommand(new Save(flags));
265 return true;
266}
267
268int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
269 SaveFlags flags) {
270 addDrawCommand(new SaveLayer(bounds, paint, flags));
271 return true;
272}
273
274bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
275 addDrawCommand(new Scale(sx, sy));
276 return true;
277}
278
279void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
280 addDrawCommand(new SetMatrix(matrix));
281}
282
283bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
284 addDrawCommand(new Skew(sx, sy));
285 return true;
286}
287
288bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
289 addDrawCommand(new Translate(dx, dy));
290 return true;
291}
292
chudy@google.com902ebe52012-06-29 14:21:22 +0000293void SkDebugCanvas::toggleCommand(int index, bool toggle) {
chudy@google.com751961d2012-07-31 20:07:42 +0000294 SkASSERT(index < (int)commandVector.size());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000295 commandVector[index]->setVisible(toggle);
chudy@google.com902ebe52012-06-29 14:21:22 +0000296}