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(const char* name) {
97 Iter iter(fList);
98 while (iter.next()) {
99 iter->markCTM(name);
100 }
101 this->INHERITED::onMarkCTM(name);
102}
103
104void SkNWayCanvas::didConcat44(const SkM44& m) {
105 Iter iter(fList);
106 while (iter.next()) {
107 iter->concat(m);
108 }
109}
110
111void SkNWayCanvas::didConcat(const SkMatrix& matrix) {
112 Iter iter(fList);
113 while (iter.next()) {
114 iter->concat(matrix);
115 }
116}
117
118void SkNWayCanvas::didSetMatrix(const SkMatrix& matrix) {
119 Iter iter(fList);
120 while (iter.next()) {
121 iter->setMatrix(matrix);
122 }
123}
124
125void SkNWayCanvas::didTranslate(SkScalar x, SkScalar y) {
126 Iter iter(fList);
127 while (iter.next()) {
128 iter->translate(x, y);
129 }
130}
131
132void SkNWayCanvas::didScale(SkScalar x, SkScalar y) {
133 Iter iter(fList);
134 while (iter.next()) {
135 iter->scale(x, y);
136 }
137}
138
139void SkNWayCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
140 Iter iter(fList);
141 while (iter.next()) {
142 iter->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
143 }
144 this->INHERITED::onClipRect(rect, op, edgeStyle);
145}
146
147void SkNWayCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
148 Iter iter(fList);
149 while (iter.next()) {
150 iter->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
151 }
152 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
153}
154
155void SkNWayCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
156 Iter iter(fList);
157 while (iter.next()) {
158 iter->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle);
159 }
160 this->INHERITED::onClipPath(path, op, edgeStyle);
161}
162
163void SkNWayCanvas::onClipShader(sk_sp<SkShader> sh, SkClipOp op) {
164 Iter iter(fList);
165 while (iter.next()) {
166 iter->clipShader(sh, op);
167 }
168 this->INHERITED::onClipShader(std::move(sh), op);
169}
170
171void SkNWayCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
172 Iter iter(fList);
173 while (iter.next()) {
174 iter->clipRegion(deviceRgn, op);
175 }
176 this->INHERITED::onClipRegion(deviceRgn, op);
177}
178
179void SkNWayCanvas::onDrawPaint(const SkPaint& paint) {
180 Iter iter(fList);
181 while (iter.next()) {
182 iter->drawPaint(paint);
183 }
184}
185
186void SkNWayCanvas::onDrawBehind(const SkPaint& paint) {
187 Iter iter(fList);
188 while (iter.next()) {
189 SkCanvasPriv::DrawBehind(iter.get(), paint);
190 }
191}
192
193void SkNWayCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
194 const SkPaint& paint) {
195 Iter iter(fList);
196 while (iter.next()) {
197 iter->drawPoints(mode, count, pts, paint);
198 }
199}
200
201void SkNWayCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
202 Iter iter(fList);
203 while (iter.next()) {
204 iter->drawRect(rect, paint);
205 }
206}
207
208void SkNWayCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
209 Iter iter(fList);
210 while (iter.next()) {
211 iter->drawRegion(region, paint);
212 }
213}
214
215void SkNWayCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
216 Iter iter(fList);
217 while (iter.next()) {
218 iter->drawOval(rect, paint);
219 }
220}
221
222void SkNWayCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
223 bool useCenter, const SkPaint& paint) {
224 Iter iter(fList);
225 while (iter.next()) {
226 iter->drawArc(rect, startAngle, sweepAngle, useCenter, paint);
227 }
228}
229
230void SkNWayCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
231 Iter iter(fList);
232 while (iter.next()) {
233 iter->drawRRect(rrect, paint);
234 }
235}
236
237void SkNWayCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
238 Iter iter(fList);
239 while (iter.next()) {
240 iter->drawDRRect(outer, inner, paint);
241 }
242}
243
244void SkNWayCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
245 Iter iter(fList);
246 while (iter.next()) {
247 iter->drawPath(path, paint);
248 }
249}
250
251void SkNWayCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top,
252 const SkPaint* paint) {
253 Iter iter(fList);
254 while (iter.next()) {
255 iter->drawImage(image, left, top, paint);
256 }
257}
258
259void SkNWayCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
260 const SkPaint* paint, SrcRectConstraint constraint) {
261 Iter iter(fList);
262 while (iter.next()) {
263 iter->legacy_drawImageRect(image, src, dst, paint, constraint);
264 }
265}
266
267void SkNWayCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
268 const SkPaint* paint) {
269 Iter iter(fList);
270 while (iter.next()) {
271 iter->drawImageNine(image, center, dst, paint);
272 }
273}
274
275void SkNWayCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
276 const SkRect& dst, const SkPaint* paint) {
277 Iter iter(fList);
278 while (iter.next()) {
279 iter->drawImageLattice(image, lattice, dst, paint);
280 }
281}
282
283void SkNWayCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
284 const SkPaint &paint) {
285 Iter iter(fList);
286 while (iter.next()) {
287 iter->drawTextBlob(blob, x, y, paint);
288 }
289}
290
291void SkNWayCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
292 const SkPaint* paint) {
293 Iter iter(fList);
294 while (iter.next()) {
295 iter->drawPicture(picture, matrix, paint);
296 }
297}
298
299void SkNWayCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
300 Iter iter(fList);
301 while (iter.next()) {
302 iter->drawDrawable(drawable, matrix);
303 }
304}
305
306void SkNWayCanvas::onDrawVerticesObject(const SkVertices* vertices,
307 SkBlendMode bmode, const SkPaint& paint) {
308 Iter iter(fList);
309 while (iter.next()) {
310 iter->drawVertices(vertices, bmode, paint);
311 }
312}
313
314void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
315 const SkPoint texCoords[4], SkBlendMode bmode,
316 const SkPaint& paint) {
317 Iter iter(fList);
318 while (iter.next()) {
319 iter->drawPatch(cubics, colors, texCoords, bmode, paint);
320 }
321}
322
323void SkNWayCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[], const SkRect tex[],
324 const SkColor colors[], int count, SkBlendMode bmode,
325 const SkRect* cull, const SkPaint* paint) {
326 Iter iter(fList);
327 while (iter.next()) {
328 iter->drawAtlas(image, xform, tex, colors, count, bmode, cull, paint);
329 }
330}
331
332void SkNWayCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
333 Iter iter(fList);
334 while (iter.next()) {
335 iter->private_draw_shadow_rec(path, rec);
336 }
337}
338
339void SkNWayCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
340 Iter iter(fList);
341 while (iter.next()) {
342 iter->drawAnnotation(rect, key, data);
343 }
344}
345
346void SkNWayCanvas::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
347 QuadAAFlags aa, const SkColor4f& color, SkBlendMode mode) {
348 Iter iter(fList);
349 while (iter.next()) {
350 iter->experimental_DrawEdgeAAQuad(rect, clip, aa, color, mode);
351 }
352}
353
354void SkNWayCanvas::onDrawEdgeAAImageSet(const ImageSetEntry set[], int count,
355 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
356 const SkPaint* paint, SrcRectConstraint constraint) {
357 Iter iter(fList);
358 while (iter.next()) {
359 iter->experimental_DrawEdgeAAImageSet(
360 set, count, dstClips, preViewMatrices, paint, constraint);
361 }
362}
363
364void SkNWayCanvas::onFlush() {
365 Iter iter(fList);
366 while (iter.next()) {
367 iter->flush();
368 }
369}
370