1
2/*
3 * Copyright 2011 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#include "SkNWayCanvas.h"
9
10SkNWayCanvas::SkNWayCanvas(int width, int height)
11        : INHERITED(width, height) {}
12
13SkNWayCanvas::~SkNWayCanvas() {
14    this->removeAll();
15}
16
17void SkNWayCanvas::addCanvas(SkCanvas* canvas) {
18    if (canvas) {
19        canvas->ref();
20        *fList.append() = canvas;
21    }
22}
23
24void SkNWayCanvas::removeCanvas(SkCanvas* canvas) {
25    int index = fList.find(canvas);
26    if (index >= 0) {
27        canvas->unref();
28        fList.removeShuffle(index);
29    }
30}
31
32void SkNWayCanvas::removeAll() {
33    fList.unrefAll();
34    fList.reset();
35}
36
37///////////////////////////////////////////////////////////////////////////
38// These are forwarded to the N canvases we're referencing
39
40class SkNWayCanvas::Iter {
41public:
42    Iter(const SkTDArray<SkCanvas*>& list) : fList(list) {
43        fIndex = 0;
44    }
45    bool next() {
46        if (fIndex < fList.count()) {
47            fCanvas = fList[fIndex++];
48            return true;
49        }
50        return false;
51    }
52    SkCanvas* operator->() { return fCanvas; }
53
54private:
55    const SkTDArray<SkCanvas*>& fList;
56    int fIndex;
57    SkCanvas* fCanvas;
58};
59
60void SkNWayCanvas::willSave() {
61    Iter iter(fList);
62    while (iter.next()) {
63        iter->save();
64    }
65
66    this->INHERITED::willSave();
67}
68
69SkCanvas::SaveLayerStrategy SkNWayCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
70                                                        SaveFlags flags) {
71    Iter iter(fList);
72    while (iter.next()) {
73        iter->saveLayer(bounds, paint, flags);
74    }
75
76    this->INHERITED::willSaveLayer(bounds, paint, flags);
77    // No need for a layer.
78    return kNoLayer_SaveLayerStrategy;
79}
80
81void SkNWayCanvas::willRestore() {
82    Iter iter(fList);
83    while (iter.next()) {
84        iter->restore();
85    }
86    this->INHERITED::willRestore();
87}
88
89void SkNWayCanvas::didConcat(const SkMatrix& matrix) {
90    Iter iter(fList);
91    while (iter.next()) {
92        iter->concat(matrix);
93    }
94    this->INHERITED::didConcat(matrix);
95}
96
97void SkNWayCanvas::didSetMatrix(const SkMatrix& matrix) {
98    Iter iter(fList);
99    while (iter.next()) {
100        iter->setMatrix(matrix);
101    }
102    this->INHERITED::didSetMatrix(matrix);
103}
104
105void SkNWayCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
106    Iter iter(fList);
107    while (iter.next()) {
108        iter->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
109    }
110    this->INHERITED::onClipRect(rect, op, edgeStyle);
111}
112
113void SkNWayCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
114    Iter iter(fList);
115    while (iter.next()) {
116        iter->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
117    }
118    this->INHERITED::onClipRRect(rrect, op, edgeStyle);
119}
120
121void SkNWayCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
122    Iter iter(fList);
123    while (iter.next()) {
124        iter->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle);
125    }
126    this->INHERITED::onClipPath(path, op, edgeStyle);
127}
128
129void SkNWayCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
130    Iter iter(fList);
131    while (iter.next()) {
132        iter->clipRegion(deviceRgn, op);
133    }
134    this->INHERITED::onClipRegion(deviceRgn, op);
135}
136
137void SkNWayCanvas::clear(SkColor color) {
138    Iter iter(fList);
139    while (iter.next()) {
140        iter->clear(color);
141    }
142}
143
144void SkNWayCanvas::drawPaint(const SkPaint& paint) {
145    Iter iter(fList);
146    while (iter.next()) {
147        iter->drawPaint(paint);
148    }
149}
150
151void SkNWayCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
152                        const SkPaint& paint) {
153    Iter iter(fList);
154    while (iter.next()) {
155        iter->drawPoints(mode, count, pts, paint);
156    }
157}
158
159void SkNWayCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
160    Iter iter(fList);
161    while (iter.next()) {
162        iter->drawRect(rect, paint);
163    }
164}
165
166void SkNWayCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
167    Iter iter(fList);
168    while (iter.next()) {
169        iter->drawOval(rect, paint);
170    }
171}
172
173void SkNWayCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
174    Iter iter(fList);
175    while (iter.next()) {
176        iter->drawRRect(rrect, paint);
177    }
178}
179
180void SkNWayCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
181                                const SkPaint& paint) {
182    Iter iter(fList);
183    while (iter.next()) {
184        iter->drawDRRect(outer, inner, paint);
185    }
186}
187
188void SkNWayCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
189    Iter iter(fList);
190    while (iter.next()) {
191        iter->drawPath(path, paint);
192    }
193}
194
195void SkNWayCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
196                              const SkPaint* paint) {
197    Iter iter(fList);
198    while (iter.next()) {
199        iter->drawBitmap(bitmap, x, y, paint);
200    }
201}
202
203void SkNWayCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
204                                  const SkRect& dst, const SkPaint* paint,
205                                  DrawBitmapRectFlags flags) {
206    Iter iter(fList);
207    while (iter.next()) {
208        iter->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
209    }
210}
211
212void SkNWayCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
213                                    const SkPaint* paint) {
214    Iter iter(fList);
215    while (iter.next()) {
216        iter->drawBitmapMatrix(bitmap, m, paint);
217    }
218}
219
220void SkNWayCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
221                                  const SkRect& dst, const SkPaint* paint) {
222    Iter iter(fList);
223    while (iter.next()) {
224        iter->drawBitmapNine(bitmap, center, dst, paint);
225    }
226}
227
228void SkNWayCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
229                              const SkPaint* paint) {
230    Iter iter(fList);
231    while (iter.next()) {
232        iter->drawSprite(bitmap, x, y, paint);
233    }
234}
235
236void SkNWayCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
237                              const SkPaint& paint) {
238    Iter iter(fList);
239    while (iter.next()) {
240        iter->drawText(text, byteLength, x, y, paint);
241    }
242}
243
244void SkNWayCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
245                                 const SkPaint& paint) {
246    Iter iter(fList);
247    while (iter.next()) {
248        iter->drawPosText(text, byteLength, pos, paint);
249    }
250}
251
252void SkNWayCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
253                                  SkScalar constY, const SkPaint& paint) {
254    Iter iter(fList);
255    while (iter.next()) {
256        iter->drawPosTextH(text, byteLength, xpos, constY, paint);
257    }
258}
259
260void SkNWayCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
261                                    const SkMatrix* matrix, const SkPaint& paint) {
262    Iter iter(fList);
263    while (iter.next()) {
264        iter->drawTextOnPath(text, byteLength, path, matrix, paint);
265    }
266}
267
268void SkNWayCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
269                                  const SkPaint &paint) {
270    Iter iter(fList);
271    while (iter.next()) {
272        iter->drawTextBlob(blob, x, y, paint);
273    }
274}
275
276void SkNWayCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
277                                 const SkPaint* paint) {
278    Iter iter(fList);
279    while (iter.next()) {
280        iter->drawPicture(picture, matrix, paint);
281    }
282}
283
284void SkNWayCanvas::drawVertices(VertexMode vmode, int vertexCount,
285                          const SkPoint vertices[], const SkPoint texs[],
286                          const SkColor colors[], SkXfermode* xmode,
287                          const uint16_t indices[], int indexCount,
288                          const SkPaint& paint) {
289    Iter iter(fList);
290    while (iter.next()) {
291        iter->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
292                           indices, indexCount, paint);
293    }
294}
295
296void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
297                               const SkPoint texCoords[4], SkXfermode* xmode,
298                               const SkPaint& paint) {
299    Iter iter(fList);
300    while (iter.next()) {
301        iter->drawPatch(cubics, colors, texCoords, xmode, paint);
302    }
303}
304
305void SkNWayCanvas::drawData(const void* data, size_t length) {
306    Iter iter(fList);
307    while (iter.next()) {
308        iter->drawData(data, length);
309    }
310}
311
312SkDrawFilter* SkNWayCanvas::setDrawFilter(SkDrawFilter* filter) {
313    Iter iter(fList);
314    while (iter.next()) {
315        iter->setDrawFilter(filter);
316    }
317    return this->INHERITED::setDrawFilter(filter);
318}
319
320void SkNWayCanvas::beginCommentGroup(const char* description) {
321    Iter iter(fList);
322    while (iter.next()) {
323        iter->beginCommentGroup(description);
324    }
325}
326
327void SkNWayCanvas::addComment(const char* kywd, const char* value) {
328    Iter iter(fList);
329    while (iter.next()) {
330        iter->addComment(kywd, value);
331    }
332}
333
334void SkNWayCanvas::endCommentGroup() {
335    Iter iter(fList);
336    while (iter.next()) {
337        iter->endCommentGroup();
338    }
339}
340