1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/core/SkShader.h"
9#include "include/utils/SkNWayCanvas.h"
10#include "src/core/SkCanvasPriv.h"
11
12SkNWayCanvas::SkNWayCanvas(int width, int height) : INHERITED(width, height) {}
13
14SkNWayCanvas::~SkNWayCanvas() {
15 this->removeAll();
16}
17
18void SkNWayCanvas::addCanvas(SkCanvas* canvas) {
19 if (canvas) {
20 *fList.append() = canvas;
21 }
22}
23
24void SkNWayCanvas::removeCanvas(SkCanvas* canvas) {
25 int index = fList.find(canvas);
26 if (index >= 0) {
27 fList.removeShuffle(index);
28 }
29}
30
31void SkNWayCanvas::removeAll() {
32 fList.reset();
33}
34
35///////////////////////////////////////////////////////////////////////////
36// These are forwarded to the N canvases we're referencing
37
38class SkNWayCanvas::Iter {
39public:
40 Iter(const SkTDArray<SkCanvas*>& list) : fList(list) {
41 fIndex = 0;
42 }
43 bool next() {
44 if (fIndex < fList.count()) {
45 fCanvas = fList[fIndex++];
46 return true;
47 }
48 return false;
49 }
50 SkCanvas* operator->() { return fCanvas; }
51 SkCanvas* get() const { return fCanvas; }
52
53private:
54 const SkTDArray<SkCanvas*>& fList;
55 int fIndex;
56 SkCanvas* fCanvas;
57};
58
59void SkNWayCanvas::willSave() {
60 Iter iter(fList);
61 while (iter.next()) {
62 iter->save();
63 }
64
65 this->INHERITED::willSave();
66}
67
68SkCanvas::SaveLayerStrategy SkNWayCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
69 Iter iter(fList);
70 while (iter.next()) {
71 iter->saveLayer(rec);
72 }
73
74 this->INHERITED::getSaveLayerStrategy(rec);
75 // No need for a layer.
76 return kNoLayer_SaveLayerStrategy;
77}
78
79bool SkNWayCanvas::onDoSaveBehind(const SkRect* bounds) {
80 Iter iter(fList);
81 while (iter.next()) {
82 SkCanvasPriv::SaveBehind(iter.get(), bounds);
83 }
84 this->INHERITED::onDoSaveBehind(bounds);
85 return false;
86}
87
88void SkNWayCanvas::willRestore() {
89 Iter iter(fList);
90 while (iter.next()) {
91 iter->restore();
92 }
93 this->INHERITED::willRestore();
94}
95
96void SkNWayCanvas::onMarkCTM(MarkerID id) {
97 Iter iter(fList);
98 while (iter.next()) {
99 iter->markCTM(id);
100 }
101 this->INHERITED::onMarkCTM(id);
102}
103
104#ifdef SK_SUPPORT_LEGACY_DIDCONCAT44
105void SkNWayCanvas::didConcat44(const SkScalar m[16]) {
106 Iter iter(fList);
107 while (iter.next()) {
108 iter->concat(SkM44::ColMajor(m));
109 }
110}
111#else
112void SkNWayCanvas::didConcat44(const SkM44& m) {
113 Iter iter(fList);
114 while (iter.next()) {
115 iter->concat(m);
116 }
117}
118#endif
119
120void SkNWayCanvas::didConcat(const SkMatrix& matrix) {
121 Iter iter(fList);
122 while (iter.next()) {
123 iter->concat(matrix);
124 }
125}
126
127void SkNWayCanvas::didSetMatrix(const SkMatrix& matrix) {
128 Iter iter(fList);
129 while (iter.next()) {
130 iter->setMatrix(matrix);
131 }
132}
133
134void SkNWayCanvas::didTranslate(SkScalar x, SkScalar y) {
135 Iter iter(fList);
136 while (iter.next()) {
137 iter->translate(x, y);
138 }
139}
140
141void SkNWayCanvas::didScale(SkScalar x, SkScalar y) {
142 Iter iter(fList);
143 while (iter.next()) {
144 iter->scale(x, y);
145 }
146}
147
148void SkNWayCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
149 Iter iter(fList);
150 while (iter.next()) {
151 iter->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
152 }
153 this->INHERITED::onClipRect(rect, op, edgeStyle);
154}
155
156void SkNWayCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
157 Iter iter(fList);
158 while (iter.next()) {
159 iter->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
160 }
161 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
162}
163
164void SkNWayCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
165 Iter iter(fList);
166 while (iter.next()) {
167 iter->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle);
168 }
169 this->INHERITED::onClipPath(path, op, edgeStyle);
170}
171
172void SkNWayCanvas::onClipShader(sk_sp<SkShader> sh, SkClipOp op) {
173 Iter iter(fList);
174 while (iter.next()) {
175 iter->clipShader(sh, op);
176 }
177 this->INHERITED::onClipShader(std::move(sh), op);
178}
179
180void SkNWayCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
181 Iter iter(fList);
182 while (iter.next()) {
183 iter->clipRegion(deviceRgn, op);
184 }
185 this->INHERITED::onClipRegion(deviceRgn, op);
186}
187
188void SkNWayCanvas::onDrawPaint(const SkPaint& paint) {
189 Iter iter(fList);
190 while (iter.next()) {
191 iter->drawPaint(paint);
192 }
193}
194
195void SkNWayCanvas::onDrawBehind(const SkPaint& paint) {
196 Iter iter(fList);
197 while (iter.next()) {
198 SkCanvasPriv::DrawBehind(iter.get(), paint);
199 }
200}
201
202void SkNWayCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
203 const SkPaint& paint) {
204 Iter iter(fList);
205 while (iter.next()) {
206 iter->drawPoints(mode, count, pts, paint);
207 }
208}
209
210void SkNWayCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
211 Iter iter(fList);
212 while (iter.next()) {
213 iter->drawRect(rect, paint);
214 }
215}
216
217void SkNWayCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
218 Iter iter(fList);
219 while (iter.next()) {
220 iter->drawRegion(region, paint);
221 }
222}
223
224void SkNWayCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
225 Iter iter(fList);
226 while (iter.next()) {
227 iter->drawOval(rect, paint);
228 }
229}
230
231void SkNWayCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
232 bool useCenter, const SkPaint& paint) {
233 Iter iter(fList);
234 while (iter.next()) {
235 iter->drawArc(rect, startAngle, sweepAngle, useCenter, paint);
236 }
237}
238
239void SkNWayCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
240 Iter iter(fList);
241 while (iter.next()) {
242 iter->drawRRect(rrect, paint);
243 }
244}
245
246void SkNWayCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
247 Iter iter(fList);
248 while (iter.next()) {
249 iter->drawDRRect(outer, inner, paint);
250 }
251}
252
253void SkNWayCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
254 Iter iter(fList);
255 while (iter.next()) {
256 iter->drawPath(path, paint);
257 }
258}
259
260void SkNWayCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top,
261 const SkPaint* paint) {
262 Iter iter(fList);
263 while (iter.next()) {
264 iter->drawImage(image, left, top, paint);
265 }
266}
267
268void SkNWayCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
269 const SkPaint* paint, SrcRectConstraint constraint) {
270 Iter iter(fList);
271 while (iter.next()) {
272 iter->legacy_drawImageRect(image, src, dst, paint, constraint);
273 }
274}
275
276void SkNWayCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
277 const SkPaint* paint) {
278 Iter iter(fList);
279 while (iter.next()) {
280 iter->drawImageNine(image, center, dst, paint);
281 }
282}
283
284void SkNWayCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
285 const SkRect& dst, const SkPaint* paint) {
286 Iter iter(fList);
287 while (iter.next()) {
288 iter->drawImageLattice(image, lattice, dst, paint);
289 }
290}
291
292void SkNWayCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
293 const SkPaint &paint) {
294 Iter iter(fList);
295 while (iter.next()) {
296 iter->drawTextBlob(blob, x, y, paint);
297 }
298}
299
300void SkNWayCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
301 const SkPaint* paint) {
302 Iter iter(fList);
303 while (iter.next()) {
304 iter->drawPicture(picture, matrix, paint);
305 }
306}
307
308void SkNWayCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
309 Iter iter(fList);
310 while (iter.next()) {
311 iter->drawDrawable(drawable, matrix);
312 }
313}
314
315void SkNWayCanvas::onDrawVerticesObject(const SkVertices* vertices,
316 SkBlendMode bmode, const SkPaint& paint) {
317 Iter iter(fList);
318 while (iter.next()) {
319 iter->drawVertices(vertices, bmode, paint);
320 }
321}
322
323void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
324 const SkPoint texCoords[4], SkBlendMode bmode,
325 const SkPaint& paint) {
326 Iter iter(fList);
327 while (iter.next()) {
328 iter->drawPatch(cubics, colors, texCoords, bmode, paint);
329 }
330}
331
332void SkNWayCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[], const SkRect tex[],
333 const SkColor colors[], int count, SkBlendMode bmode,
334 const SkRect* cull, const SkPaint* paint) {
335 Iter iter(fList);
336 while (iter.next()) {
337 iter->drawAtlas(image, xform, tex, colors, count, bmode, cull, paint);
338 }
339}
340
341void SkNWayCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
342 Iter iter(fList);
343 while (iter.next()) {
344 iter->private_draw_shadow_rec(path, rec);
345 }
346}
347
348void SkNWayCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
349 Iter iter(fList);
350 while (iter.next()) {
351 iter->drawAnnotation(rect, key, data);
352 }
353}
354
355void SkNWayCanvas::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
356 QuadAAFlags aa, const SkColor4f& color, SkBlendMode mode) {
357 Iter iter(fList);
358 while (iter.next()) {
359 iter->experimental_DrawEdgeAAQuad(rect, clip, aa, color, mode);
360 }
361}
362
363void SkNWayCanvas::onDrawEdgeAAImageSet(const ImageSetEntry set[], int count,
364 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
365 const SkPaint* paint, SrcRectConstraint constraint) {
366 Iter iter(fList);
367 while (iter.next()) {
368 iter->experimental_DrawEdgeAAImageSet(
369 set, count, dstClips, preViewMatrices, paint, constraint);
370 }
371}
372
373void SkNWayCanvas::onFlush() {
374 Iter iter(fList);
375 while (iter.next()) {
376 iter->flush();
377 }
378}
379