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 |
19 | 20 |
20 // The possible geometric combinations to test | 21 // The possible geometric combinations to test |
21 enum Geometry { | 22 enum Geometry { |
22 kRect_Geometry, | 23 kRect_Geometry, |
23 kRRect_Geometry, | 24 kRRect_Geometry, |
24 kCircle_Geometry, | 25 kCircle_Geometry, |
25 kConvexPath_Geometry, | 26 kConvexPath_Geometry, |
26 kConcavePath_Geometry, | 27 kConcavePath_Geometry, |
27 kRectAndRect_Geometry, | 28 kRectAndRect_Geometry, |
28 kRectAndRRect_Geometry, | 29 kRectAndRRect_Geometry, |
29 kRectAndConvex_Geometry, | 30 kRectAndConvex_Geometry, |
30 kRectAndConcave_Geometry | 31 kRectAndConcave_Geometry |
31 }; | 32 }; |
32 | 33 |
33 // The basic rect used is [kMin,kMin]..[kMax,kMax] | 34 // The basic rect used is [kMin,kMin]..[kMax,kMax] |
34 static const float kMin = 100.5f; | 35 static const float kMin = 100.5f; |
35 static const float kMid = 200.0f; | 36 static const float kMid = 200.0f; |
36 static const float kMax = 299.5f; | 37 static const float kMax = 299.5f; |
37 | 38 |
| 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 |
38 SkRect create_rect(const SkPoint& offset) { | 43 SkRect create_rect(const SkPoint& offset) { |
39 SkRect r = SkRect::MakeLTRB(kMin, kMin, kMax, kMax); | 44 SkRect r = SkRect::MakeLTRB(kMin, kMin, kMax, kMax); |
40 r.offset(offset); | 45 r.offset(offset); |
41 return r; | 46 return r; |
42 } | 47 } |
43 | 48 |
44 SkRRect create_rrect(const SkPoint& offset) { | 49 SkRRect create_rrect(const SkPoint& offset) { |
45 SkRRect rrect; | 50 SkRRect rrect; |
46 rrect.setRectXY(create_rect(offset), 10, 10); | 51 rrect.setRectXY(create_rect(offset), 10, 10); |
47 return rrect; | 52 return rrect; |
(...skipping 24 matching lines...) Expand all Loading... |
72 concavePath.lineTo(kMax, kMax); | 77 concavePath.lineTo(kMax, kMax); |
73 concavePath.lineTo(kMid, 295.0f); | 78 concavePath.lineTo(kMid, 295.0f); |
74 concavePath.lineTo(kMin, kMax); | 79 concavePath.lineTo(kMin, kMax); |
75 concavePath.lineTo(105.0f, kMid); | 80 concavePath.lineTo(105.0f, kMid); |
76 concavePath.close(); | 81 concavePath.close(); |
77 | 82 |
78 concavePath.offset(offset.fX, offset.fY); | 83 concavePath.offset(offset.fX, offset.fY); |
79 return concavePath; | 84 return concavePath; |
80 } | 85 } |
81 | 86 |
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 | |
138 static void draw_normal_geom(SkCanvas* canvas, const SkPoint& offset, int geom,
bool useAA) { | 87 static void draw_normal_geom(SkCanvas* canvas, const SkPoint& offset, int geom,
bool useAA) { |
139 SkPaint p; | 88 SkPaint p; |
140 p.setAntiAlias(useAA); | 89 p.setAntiAlias(useAA); |
141 p.setColor(SK_ColorBLACK); | 90 p.setColor(SK_ColorBLACK); |
142 | 91 |
143 switch (geom) { | 92 switch (geom) { |
144 case kRect_Geometry: // fall thru | 93 case kRect_Geometry: // fall thru |
145 case kRectAndRect_Geometry: | 94 case kRectAndRect_Geometry: |
146 canvas->drawRect(create_rect(offset), p); | 95 canvas->drawRect(create_rect(offset), p); |
147 break; | 96 break; |
(...skipping 10 matching lines...) Expand all Loading... |
158 break; | 107 break; |
159 case kConcavePath_Geometry: // fall thru | 108 case kConcavePath_Geometry: // fall thru |
160 case kRectAndConcave_Geometry: | 109 case kRectAndConcave_Geometry: |
161 canvas->drawPath(create_concave_path(offset), p); | 110 canvas->drawPath(create_concave_path(offset), p); |
162 break; | 111 break; |
163 } | 112 } |
164 } | 113 } |
165 | 114 |
166 class ClipDrawMatchView : public SampleView { | 115 class ClipDrawMatchView : public SampleView { |
167 public: | 116 public: |
168 ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry), fClipFirst(true)
{ | 117 ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry), fClipFirst(true),
fSign(1) { |
169 SkScalar values[2]; | 118 SkScalar values[2]; |
170 | 119 |
171 fTrans.setRepeatCount(999); | 120 fTrans.setRepeatCount(999); |
172 values[0] = values[1] = 0; | 121 values[0] = values[1] = 0; |
173 fTrans.setKeyFrame(0, SkTime::GetMSecs() + 1000, values); | 122 fTrans.setKeyFrame(0, SkTime::GetMSecs() + 1000, values); |
174 values[1] = 1; | 123 values[1] = 1; |
175 fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values); | 124 fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values); |
176 values[0] = values[1] = 1; | 125 values[0] = values[1] = 1; |
177 fTrans.setKeyFrame(2, SkTime::GetMSecs() + 3000, values); | 126 fTrans.setKeyFrame(2, SkTime::GetMSecs() + 3000, values); |
178 values[1] = 0; | 127 values[1] = 0; |
(...skipping 13 matching lines...) Expand all Loading... |
192 switch (uni) { | 141 switch (uni) { |
193 case '1': fGeom = kRect_Geometry; this->inval(NULL); return true
; | 142 case '1': fGeom = kRect_Geometry; this->inval(NULL); return true
; |
194 case '2': fGeom = kRRect_Geometry; this->inval(NULL); return tru
e; | 143 case '2': fGeom = kRRect_Geometry; this->inval(NULL); return tru
e; |
195 case '3': fGeom = kCircle_Geometry; this->inval(NULL); return tr
ue; | 144 case '3': fGeom = kCircle_Geometry; this->inval(NULL); return tr
ue; |
196 case '4': fGeom = kConvexPath_Geometry; this->inval(NULL); retur
n true; | 145 case '4': fGeom = kConvexPath_Geometry; this->inval(NULL); retur
n true; |
197 case '5': fGeom = kConcavePath_Geometry; this->inval(NULL); retu
rn true; | 146 case '5': fGeom = kConcavePath_Geometry; this->inval(NULL); retu
rn true; |
198 case '6': fGeom = kRectAndRect_Geometry; this->inval(NULL); retu
rn true; | 147 case '6': fGeom = kRectAndRect_Geometry; this->inval(NULL); retu
rn true; |
199 case '7': fGeom = kRectAndRRect_Geometry; this->inval(NULL); ret
urn true; | 148 case '7': fGeom = kRectAndRRect_Geometry; this->inval(NULL); ret
urn true; |
200 case '8': fGeom = kRectAndConvex_Geometry; this->inval(NULL); re
turn true; | 149 case '8': fGeom = kRectAndConvex_Geometry; this->inval(NULL); re
turn true; |
201 case '9': fGeom = kRectAndConcave_Geometry; this->inval(NULL); r
eturn true; | 150 case '9': fGeom = kRectAndConcave_Geometry; this->inval(NULL); r
eturn true; |
| 151 case 'f': fSign = -fSign; this->inval(NULL); return true; |
202 case 't': fClipFirst = !fClipFirst; this->inval(NULL); return tr
ue; | 152 case 't': fClipFirst = !fClipFirst; this->inval(NULL); return tr
ue; |
203 default: break; | 153 default: break; |
204 } | 154 } |
205 } | 155 } |
206 return this->INHERITED::onQuery(evt); | 156 return this->INHERITED::onQuery(evt); |
207 } | 157 } |
208 | 158 |
| 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 |
209 // Draw a big red rect through some clip geometry and also draw that same | 215 // Draw a big red rect through some clip geometry and also draw that same |
210 // geometry in black. The order in which they are drawn can be swapped. | 216 // geometry in black. The order in which they are drawn can be swapped. |
211 // This tests whether the clip and normally drawn geometry match up. | 217 // This tests whether the clip and normally drawn geometry match up. |
212 void drawGeometry(SkCanvas* canvas, const SkPoint& offset, bool useAA) { | 218 void drawGeometry(SkCanvas* canvas, const SkPoint& offset, bool useAA) { |
213 if (fClipFirst) { | 219 if (fClipFirst) { |
214 draw_clipped_geom(canvas, offset, fGeom, useAA); | 220 this->drawClippedGeom(canvas, offset, useAA); |
215 } | 221 } |
216 | 222 |
217 draw_normal_geom(canvas, offset, fGeom, useAA); | 223 draw_normal_geom(canvas, offset, fGeom, useAA); |
218 | 224 |
219 if (!fClipFirst) { | 225 if (!fClipFirst) { |
220 draw_clipped_geom(canvas, offset, fGeom, useAA); | 226 this->drawClippedGeom(canvas, offset, useAA); |
221 } | 227 } |
222 } | 228 } |
223 | 229 |
224 void onDrawContent(SkCanvas* canvas) SK_OVERRIDE { | 230 void onDrawContent(SkCanvas* canvas) SK_OVERRIDE { |
225 SkScalar trans[2]; | 231 SkScalar trans[2]; |
226 fTrans.timeToValues(SkTime::GetMSecs(), trans); | 232 fTrans.timeToValues(SkTime::GetMSecs(), trans); |
227 | 233 |
228 SkPoint offset; | 234 SkPoint offset; |
229 offset.set(trans[0], trans[1]); | 235 offset.set(trans[0], trans[1]); |
230 | 236 |
231 int saveCount = canvas->save(); | 237 int saveCount = canvas->save(); |
232 this->drawGeometry(canvas, offset, false); | 238 this->drawGeometry(canvas, offset, false); |
233 canvas->restoreToCount(saveCount); | 239 canvas->restoreToCount(saveCount); |
234 | 240 |
235 this->inval(NULL); | 241 this->inval(NULL); |
236 } | 242 } |
237 | 243 |
238 private: | 244 private: |
239 SkInterpolator fTrans; | 245 SkInterpolator fTrans; |
240 Geometry fGeom; | 246 Geometry fGeom; |
241 bool fClipFirst; | 247 bool fClipFirst; |
| 248 int fSign; |
242 | 249 |
243 typedef SampleView INHERITED; | 250 typedef SampleView INHERITED; |
244 }; | 251 }; |
245 | 252 |
246 ////////////////////////////////////////////////////////////////////////////// | 253 ////////////////////////////////////////////////////////////////////////////// |
247 | 254 |
248 static SkView* MyFactory() { return new ClipDrawMatchView; } | 255 static SkView* MyFactory() { return new ClipDrawMatchView; } |
249 static SkViewRegister reg(MyFactory); | 256 static SkViewRegister reg(MyFactory); |
OLD | NEW |