OLD | NEW |
---|---|
(Empty) | |
1 | |
2 /* | |
3 * Copyright 2013 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 "SkCanvasStack.h" | |
9 | |
10 SkCanvasStack::SkCanvasStack(int width, int height) | |
11 : INHERITED(width, height) {} | |
12 | |
13 SkCanvasStack::~SkCanvasStack() { | |
14 this->removeAll(); | |
15 } | |
16 | |
17 void SkCanvasStack::pushCanvas(SkCanvas* canvas, const SkIPoint& origin) { | |
18 if (canvas) { | |
19 // compute the bounds of this canvas | |
20 const SkIRect canvasBounds = SkIRect::MakeSize(canvas->getDeviceSize()); | |
21 | |
22 // push the canvas onto the stack | |
23 this->INHERITED::addCanvas(canvas); | |
24 | |
25 // push the canvas data onto the stack | |
26 CanvasData* data = &fCanvasData.push_back(); | |
27 data->origin = origin; | |
28 data->requiredClip.setRect(canvasBounds); | |
29 | |
30 // subtract this region from the canvas objects already on the stack. | |
31 // This ensures they do not draw into the space occupied by the layers | |
32 // above them. | |
33 for (int i = fList.count() - 1; i > 0; --i) { | |
34 SkIRect localBounds = canvasBounds; | |
35 localBounds.offset(origin - fCanvasData[i-1].origin); | |
36 | |
37 fCanvasData[i-1].requiredClip.op(localBounds, SkRegion::kDifference_ Op); | |
38 fList[i-i]->clipRegion(fCanvasData[i-1].requiredClip); | |
bungeman-skia
2013/12/02 18:34:18
i-i
| |
39 } | |
40 } | |
41 SkASSERT(fList.count() == fCanvasData.count()); | |
42 } | |
43 | |
44 void SkCanvasStack::removeAll() { | |
45 fCanvasData.reset(); | |
46 this->INHERITED::removeAll(); | |
47 } | |
48 | |
49 /** | |
50 * Traverse all canvases (e.g. layers) the stack and ensure that they are clippe d | |
51 * to their bounds and that the area covered by any canvas higher in the stack i s | |
52 * also clipped out. | |
53 */ | |
54 void SkCanvasStack::clipToZOrderedBounds() { | |
55 SkASSERT(fList.count() == fCanvasData.count()); | |
56 for (int i = 0; i < fList.count(); ++i) { | |
57 fList[i]->clipRegion(fCanvasData[i].requiredClip, SkRegion::kIntersect_O p); | |
58 } | |
59 } | |
60 | |
61 //////////////////////////////////////////////////////////////////////////////// | |
62 | |
63 /** | |
64 * We need to handle setMatrix specially as it overwrites the matrix in each | |
65 * canvas unlike all other matrix operations (i.e. translate, scale, etc) which | |
66 * just pre-concatenate with the existing matrix. | |
67 */ | |
68 void SkCanvasStack::setMatrix(const SkMatrix& matrix) { | |
69 SkASSERT(fList.count() == fCanvasData.count()); | |
70 for (int i = 0; i < fList.count(); ++i) { | |
71 | |
72 SkMatrix tempMatrix = matrix; | |
73 tempMatrix.postTranslate(SkIntToScalar(-fCanvasData[i].origin.x()), | |
74 SkIntToScalar(-fCanvasData[i].origin.y())); | |
75 fList[i]->setMatrix(tempMatrix); | |
76 } | |
77 this->SkCanvas::setMatrix(matrix); | |
78 } | |
79 | |
80 bool SkCanvasStack::clipRect(const SkRect& r, SkRegion::Op op, bool aa) { | |
81 bool result = this->INHERITED::clipRect(r, op, aa); | |
82 clipToZOrderedBounds(); | |
reed1
2013/09/04 15:00:00
nit: this->clipToZOrderedBounds()
| |
83 return result; | |
84 } | |
85 | |
86 bool SkCanvasStack::clipRRect(const SkRRect& rr, SkRegion::Op op, bool aa) { | |
87 bool result = this->INHERITED::clipRRect(rr, op, aa); | |
88 clipToZOrderedBounds(); | |
89 return result; | |
90 } | |
91 | |
92 bool SkCanvasStack::clipPath(const SkPath& p, SkRegion::Op op, bool aa) { | |
93 bool result = this->INHERITED::clipPath(p, op, aa); | |
94 clipToZOrderedBounds(); | |
95 return result; | |
96 } | |
97 | |
98 bool SkCanvasStack::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { | |
99 SkASSERT(fList.count() == fCanvasData.count()); | |
reed1
2013/09/04 15:00:00
perhaps small comment here:
// This loop replaces
| |
100 for (int i = 0; i < fList.count(); ++i) { | |
101 SkRegion tempRegion; | |
102 deviceRgn.translate(-fCanvasData[i].origin.x(), | |
103 -fCanvasData[i].origin.y(), &tempRegion); | |
104 tempRegion.op(fCanvasData[i].requiredClip, SkRegion::kIntersect_Op); | |
105 fList[i]->clipRegion(tempRegion, op); | |
106 } | |
107 return this->SkCanvas::clipRegion(deviceRgn, op); | |
108 } | |
OLD | NEW |