OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SampleCode.h" | 8 #include "SampleCode.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkInterpolator.h" | 10 #include "SkInterpolator.h" |
11 #include "SkTime.h" | 11 #include "SkTime.h" |
12 | 12 |
13 // This slide tests out the match up between BW clipping and rendering. It can | 13 // This slide tests out the match up between BW clipping and rendering. It can |
14 // draw a large rect through some clip geometry and draw the same geometry | 14 // draw a large rect through some clip geometry and draw the same geometry |
15 // normally. Which one is drawn first can be toggled. The pair of objects is tra
nslated | 15 // normally. Which one is drawn first can be toggled. The pair of objects is tra
nslated |
16 // fractionally (via an animator) to expose snapping bugs. The key bindings are: | 16 // fractionally (via an animator) to expose snapping bugs. The key bindings are: |
17 // 1-9: the different geometries | 17 // 1-9: the different geometries |
18 // t: toggle which is drawn first the clip or the normal geometry | 18 // t: toggle which is drawn first the clip or the normal geometry |
19 // f: flip-flops which corner the bottom AA clip rect occupies in the com
plex clip cases | |
20 | 19 |
21 // The possible geometric combinations to test | 20 // The possible geometric combinations to test |
22 enum Geometry { | 21 enum Geometry { |
23 kRect_Geometry, | 22 kRect_Geometry, |
24 kRRect_Geometry, | 23 kRRect_Geometry, |
25 kCircle_Geometry, | 24 kCircle_Geometry, |
26 kConvexPath_Geometry, | 25 kConvexPath_Geometry, |
27 kConcavePath_Geometry, | 26 kConcavePath_Geometry, |
28 kRectAndRect_Geometry, | 27 kRectAndRect_Geometry, |
29 kRectAndRRect_Geometry, | 28 kRectAndRRect_Geometry, |
30 kRectAndConvex_Geometry, | 29 kRectAndConvex_Geometry, |
31 kRectAndConcave_Geometry | 30 kRectAndConcave_Geometry |
32 }; | 31 }; |
33 | 32 |
34 // The basic rect used is [kMin,kMin]..[kMax,kMax] | 33 // The basic rect used is [kMin,kMin]..[kMax,kMax] |
35 static const float kMin = 100.5f; | 34 static const float kMin = 100.5f; |
36 static const float kMid = 200.0f; | 35 static const float kMid = 200.0f; |
37 static const float kMax = 299.5f; | 36 static const float kMax = 299.5f; |
38 | 37 |
39 // The translation applied to the base AA rect in the combination cases | |
40 // (i.e., kRectAndRect through kRectAndConcave) | |
41 static const float kXlate = 100.0f; | |
42 | |
43 SkRect create_rect(const SkPoint& offset) { | 38 SkRect create_rect(const SkPoint& offset) { |
44 SkRect r = SkRect::MakeLTRB(kMin, kMin, kMax, kMax); | 39 SkRect r = SkRect::MakeLTRB(kMin, kMin, kMax, kMax); |
45 r.offset(offset); | 40 r.offset(offset); |
46 return r; | 41 return r; |
47 } | 42 } |
48 | 43 |
49 SkRRect create_rrect(const SkPoint& offset) { | 44 SkRRect create_rrect(const SkPoint& offset) { |
50 SkRRect rrect; | 45 SkRRect rrect; |
51 rrect.setRectXY(create_rect(offset), 10, 10); | 46 rrect.setRectXY(create_rect(offset), 10, 10); |
52 return rrect; | 47 return rrect; |
(...skipping 24 matching lines...) Expand all Loading... |
77 concavePath.lineTo(kMax, kMax); | 72 concavePath.lineTo(kMax, kMax); |
78 concavePath.lineTo(kMid, 295.0f); | 73 concavePath.lineTo(kMid, 295.0f); |
79 concavePath.lineTo(kMin, kMax); | 74 concavePath.lineTo(kMin, kMax); |
80 concavePath.lineTo(105.0f, kMid); | 75 concavePath.lineTo(105.0f, kMid); |
81 concavePath.close(); | 76 concavePath.close(); |
82 | 77 |
83 concavePath.offset(offset.fX, offset.fY); | 78 concavePath.offset(offset.fX, offset.fY); |
84 return concavePath; | 79 return concavePath; |
85 } | 80 } |
86 | 81 |
| 82 static void draw_clipped_geom(SkCanvas* canvas, const SkPoint& offset, int geom,
bool useAA) { |
| 83 |
| 84 int count = canvas->save(); |
| 85 |
| 86 switch (geom) { |
| 87 case kRect_Geometry: |
| 88 canvas->clipRect(create_rect(offset), SkRegion::kReplace_Op, useAA); |
| 89 break; |
| 90 case kRRect_Geometry: |
| 91 canvas->clipRRect(create_rrect(offset), SkRegion::kReplace_Op, useAA); |
| 92 break; |
| 93 case kCircle_Geometry: |
| 94 canvas->clipRRect(create_circle(offset), SkRegion::kReplace_Op, useAA); |
| 95 break; |
| 96 case kConvexPath_Geometry: |
| 97 canvas->clipPath(create_convex_path(offset), SkRegion::kReplace_Op, useA
A); |
| 98 break; |
| 99 case kConcavePath_Geometry: |
| 100 canvas->clipPath(create_concave_path(offset), SkRegion::kReplace_Op, use
AA); |
| 101 break; |
| 102 case kRectAndRect_Geometry: { |
| 103 SkRect r = create_rect(offset); |
| 104 r.offset(-100.0f, -100.0f); |
| 105 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shad
er clips |
| 106 canvas->clipRect(create_rect(offset), SkRegion::kIntersect_Op, useAA); |
| 107 } break; |
| 108 case kRectAndRRect_Geometry: { |
| 109 SkRect r = create_rect(offset); |
| 110 r.offset(-100.0f, -100.0f); |
| 111 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shad
er clips |
| 112 canvas->clipRRect(create_rrect(offset), SkRegion::kIntersect_Op, useAA); |
| 113 } break; |
| 114 case kRectAndConvex_Geometry: { |
| 115 SkRect r = create_rect(offset); |
| 116 r.offset(-100.0f, -100.0f); |
| 117 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shad
er clips |
| 118 canvas->clipPath(create_convex_path(offset), SkRegion::kIntersect_Op, us
eAA); |
| 119 } break; |
| 120 case kRectAndConcave_Geometry: { |
| 121 SkRect r = create_rect(offset); |
| 122 r.offset(-100.0f, -100.0f); |
| 123 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces shad
er clips |
| 124 canvas->clipPath(create_concave_path(offset), SkRegion::kIntersect_Op, u
seAA); |
| 125 } break; |
| 126 } |
| 127 |
| 128 SkISize size = canvas->getDeviceSize(); |
| 129 SkRect bigR = SkRect::MakeWH(SkIntToScalar(size.width()), SkIntToScalar(size
.height())); |
| 130 |
| 131 SkPaint p; |
| 132 p.setColor(SK_ColorRED); |
| 133 |
| 134 canvas->drawRect(bigR, p); |
| 135 canvas->restoreToCount(count); |
| 136 } |
| 137 |
87 static void draw_normal_geom(SkCanvas* canvas, const SkPoint& offset, int geom,
bool useAA) { | 138 static void draw_normal_geom(SkCanvas* canvas, const SkPoint& offset, int geom,
bool useAA) { |
88 SkPaint p; | 139 SkPaint p; |
89 p.setAntiAlias(useAA); | 140 p.setAntiAlias(useAA); |
90 p.setColor(SK_ColorBLACK); | 141 p.setColor(SK_ColorBLACK); |
91 | 142 |
92 switch (geom) { | 143 switch (geom) { |
93 case kRect_Geometry: // fall thru | 144 case kRect_Geometry: // fall thru |
94 case kRectAndRect_Geometry: | 145 case kRectAndRect_Geometry: |
95 canvas->drawRect(create_rect(offset), p); | 146 canvas->drawRect(create_rect(offset), p); |
96 break; | 147 break; |
(...skipping 10 matching lines...) Expand all Loading... |
107 break; | 158 break; |
108 case kConcavePath_Geometry: // fall thru | 159 case kConcavePath_Geometry: // fall thru |
109 case kRectAndConcave_Geometry: | 160 case kRectAndConcave_Geometry: |
110 canvas->drawPath(create_concave_path(offset), p); | 161 canvas->drawPath(create_concave_path(offset), p); |
111 break; | 162 break; |
112 } | 163 } |
113 } | 164 } |
114 | 165 |
115 class ClipDrawMatchView : public SampleView { | 166 class ClipDrawMatchView : public SampleView { |
116 public: | 167 public: |
117 ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry), fClipFirst(true),
fSign(1) { | 168 ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry), fClipFirst(true)
{ |
118 SkScalar values[2]; | 169 SkScalar values[2]; |
119 | 170 |
120 fTrans.setRepeatCount(999); | 171 fTrans.setRepeatCount(999); |
121 values[0] = values[1] = 0; | 172 values[0] = values[1] = 0; |
122 fTrans.setKeyFrame(0, SkTime::GetMSecs() + 1000, values); | 173 fTrans.setKeyFrame(0, SkTime::GetMSecs() + 1000, values); |
123 values[1] = 1; | 174 values[1] = 1; |
124 fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values); | 175 fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values); |
125 values[0] = values[1] = 1; | 176 values[0] = values[1] = 1; |
126 fTrans.setKeyFrame(2, SkTime::GetMSecs() + 3000, values); | 177 fTrans.setKeyFrame(2, SkTime::GetMSecs() + 3000, values); |
127 values[1] = 0; | 178 values[1] = 0; |
(...skipping 13 matching lines...) Expand all Loading... |
141 switch (uni) { | 192 switch (uni) { |
142 case '1': fGeom = kRect_Geometry; this->inval(NULL); return true
; | 193 case '1': fGeom = kRect_Geometry; this->inval(NULL); return true
; |
143 case '2': fGeom = kRRect_Geometry; this->inval(NULL); return tru
e; | 194 case '2': fGeom = kRRect_Geometry; this->inval(NULL); return tru
e; |
144 case '3': fGeom = kCircle_Geometry; this->inval(NULL); return tr
ue; | 195 case '3': fGeom = kCircle_Geometry; this->inval(NULL); return tr
ue; |
145 case '4': fGeom = kConvexPath_Geometry; this->inval(NULL); retur
n true; | 196 case '4': fGeom = kConvexPath_Geometry; this->inval(NULL); retur
n true; |
146 case '5': fGeom = kConcavePath_Geometry; this->inval(NULL); retu
rn true; | 197 case '5': fGeom = kConcavePath_Geometry; this->inval(NULL); retu
rn true; |
147 case '6': fGeom = kRectAndRect_Geometry; this->inval(NULL); retu
rn true; | 198 case '6': fGeom = kRectAndRect_Geometry; this->inval(NULL); retu
rn true; |
148 case '7': fGeom = kRectAndRRect_Geometry; this->inval(NULL); ret
urn true; | 199 case '7': fGeom = kRectAndRRect_Geometry; this->inval(NULL); ret
urn true; |
149 case '8': fGeom = kRectAndConvex_Geometry; this->inval(NULL); re
turn true; | 200 case '8': fGeom = kRectAndConvex_Geometry; this->inval(NULL); re
turn true; |
150 case '9': fGeom = kRectAndConcave_Geometry; this->inval(NULL); r
eturn true; | 201 case '9': fGeom = kRectAndConcave_Geometry; this->inval(NULL); r
eturn true; |
151 case 'f': fSign = -fSign; this->inval(NULL); return true; | |
152 case 't': fClipFirst = !fClipFirst; this->inval(NULL); return tr
ue; | 202 case 't': fClipFirst = !fClipFirst; this->inval(NULL); return tr
ue; |
153 default: break; | 203 default: break; |
154 } | 204 } |
155 } | 205 } |
156 return this->INHERITED::onQuery(evt); | 206 return this->INHERITED::onQuery(evt); |
157 } | 207 } |
158 | 208 |
159 void drawClippedGeom(SkCanvas* canvas, const SkPoint& offset, bool useAA) { | |
160 | |
161 int count = canvas->save(); | |
162 | |
163 switch (fGeom) { | |
164 case kRect_Geometry: | |
165 canvas->clipRect(create_rect(offset), SkRegion::kReplace_Op, useAA); | |
166 break; | |
167 case kRRect_Geometry: | |
168 canvas->clipRRect(create_rrect(offset), SkRegion::kReplace_Op, useAA
); | |
169 break; | |
170 case kCircle_Geometry: | |
171 canvas->clipRRect(create_circle(offset), SkRegion::kReplace_Op, useA
A); | |
172 break; | |
173 case kConvexPath_Geometry: | |
174 canvas->clipPath(create_convex_path(offset), SkRegion::kReplace_Op,
useAA); | |
175 break; | |
176 case kConcavePath_Geometry: | |
177 canvas->clipPath(create_concave_path(offset), SkRegion::kReplace_Op,
useAA); | |
178 break; | |
179 case kRectAndRect_Geometry: { | |
180 SkRect r = create_rect(offset); | |
181 r.offset(fSign * kXlate, fSign * kXlate); | |
182 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces
shader clips | |
183 canvas->clipRect(create_rect(offset), SkRegion::kIntersect_Op, useAA
); | |
184 } break; | |
185 case kRectAndRRect_Geometry: { | |
186 SkRect r = create_rect(offset); | |
187 r.offset(fSign * kXlate, fSign * kXlate); | |
188 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces
shader clips | |
189 canvas->clipRRect(create_rrect(offset), SkRegion::kIntersect_Op, use
AA); | |
190 } break; | |
191 case kRectAndConvex_Geometry: { | |
192 SkRect r = create_rect(offset); | |
193 r.offset(fSign * kXlate, fSign * kXlate); | |
194 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces
shader clips | |
195 canvas->clipPath(create_convex_path(offset), SkRegion::kIntersect_Op
, useAA); | |
196 } break; | |
197 case kRectAndConcave_Geometry: { | |
198 SkRect r = create_rect(offset); | |
199 r.offset(fSign * kXlate, fSign * kXlate); | |
200 canvas->clipRect(r, SkRegion::kReplace_Op, true); // AA here forces
shader clips | |
201 canvas->clipPath(create_concave_path(offset), SkRegion::kIntersect_O
p, useAA); | |
202 } break; | |
203 } | |
204 | |
205 SkISize size = canvas->getDeviceSize(); | |
206 SkRect bigR = SkRect::MakeWH(SkIntToScalar(size.width()), SkIntToScalar(
size.height())); | |
207 | |
208 SkPaint p; | |
209 p.setColor(SK_ColorRED); | |
210 | |
211 canvas->drawRect(bigR, p); | |
212 canvas->restoreToCount(count); | |
213 } | |
214 | |
215 // Draw a big red rect through some clip geometry and also draw that same | 209 // Draw a big red rect through some clip geometry and also draw that same |
216 // geometry in black. The order in which they are drawn can be swapped. | 210 // geometry in black. The order in which they are drawn can be swapped. |
217 // This tests whether the clip and normally drawn geometry match up. | 211 // This tests whether the clip and normally drawn geometry match up. |
218 void drawGeometry(SkCanvas* canvas, const SkPoint& offset, bool useAA) { | 212 void drawGeometry(SkCanvas* canvas, const SkPoint& offset, bool useAA) { |
219 if (fClipFirst) { | 213 if (fClipFirst) { |
220 this->drawClippedGeom(canvas, offset, useAA); | 214 draw_clipped_geom(canvas, offset, fGeom, useAA); |
221 } | 215 } |
222 | 216 |
223 draw_normal_geom(canvas, offset, fGeom, useAA); | 217 draw_normal_geom(canvas, offset, fGeom, useAA); |
224 | 218 |
225 if (!fClipFirst) { | 219 if (!fClipFirst) { |
226 this->drawClippedGeom(canvas, offset, useAA); | 220 draw_clipped_geom(canvas, offset, fGeom, useAA); |
227 } | 221 } |
228 } | 222 } |
229 | 223 |
230 void onDrawContent(SkCanvas* canvas) SK_OVERRIDE { | 224 void onDrawContent(SkCanvas* canvas) SK_OVERRIDE { |
231 SkScalar trans[2]; | 225 SkScalar trans[2]; |
232 fTrans.timeToValues(SkTime::GetMSecs(), trans); | 226 fTrans.timeToValues(SkTime::GetMSecs(), trans); |
233 | 227 |
234 SkPoint offset; | 228 SkPoint offset; |
235 offset.set(trans[0], trans[1]); | 229 offset.set(trans[0], trans[1]); |
236 | 230 |
237 int saveCount = canvas->save(); | 231 int saveCount = canvas->save(); |
238 this->drawGeometry(canvas, offset, false); | 232 this->drawGeometry(canvas, offset, false); |
239 canvas->restoreToCount(saveCount); | 233 canvas->restoreToCount(saveCount); |
240 | 234 |
241 this->inval(NULL); | 235 this->inval(NULL); |
242 } | 236 } |
243 | 237 |
244 private: | 238 private: |
245 SkInterpolator fTrans; | 239 SkInterpolator fTrans; |
246 Geometry fGeom; | 240 Geometry fGeom; |
247 bool fClipFirst; | 241 bool fClipFirst; |
248 int fSign; | |
249 | 242 |
250 typedef SampleView INHERITED; | 243 typedef SampleView INHERITED; |
251 }; | 244 }; |
252 | 245 |
253 ////////////////////////////////////////////////////////////////////////////// | 246 ////////////////////////////////////////////////////////////////////////////// |
254 | 247 |
255 static SkView* MyFactory() { return new ClipDrawMatchView; } | 248 static SkView* MyFactory() { return new ClipDrawMatchView; } |
256 static SkViewRegister reg(MyFactory); | 249 static SkViewRegister reg(MyFactory); |
OLD | NEW |