OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "gm.h" | 8 #include "gm.h" |
9 #include "SkArithmeticMode.h" | 9 #include "SkArithmeticMode.h" |
10 #include "SkPath.h" | 10 #include "SkPath.h" |
11 #include "SkShader.h" | 11 #include "SkShader.h" |
12 #include "SkXfermode.h" | 12 #include "SkXfermode.h" |
13 | 13 |
14 enum { | 14 enum { |
15 kXfermodeCount = SkXfermode::kLastMode + 2, // All xfermodes plus arithmetic
mode. | 15 kXfermodeCount = SkXfermode::kLastMode + 2, // All xfermodes plus arithmetic
mode. |
16 kShapeSize = 22, | 16 kShapeSize = 22, |
17 kShapeSpacing = 36, | 17 kShapeSpacing = 36, |
18 kShapeTypeSpacing = 4 * kShapeSpacing / 3, | 18 kShapeTypeSpacing = 4 * kShapeSpacing / 3, |
19 kPaintSpacing = 3 * kShapeTypeSpacing, | 19 kPaintSpacing = 4 * kShapeTypeSpacing, |
20 kLabelSpacing = 3 * kShapeSize, | 20 kLabelSpacing = 3 * kShapeSize, |
21 kMargin = kShapeSpacing / 2, | 21 kMargin = kShapeSpacing / 2, |
22 kXfermodeTypeSpacing = kLabelSpacing + 2 * kPaintSpacing + kShapeTypeSpacing
, | 22 kXfermodeTypeSpacing = kLabelSpacing + 2 * kPaintSpacing + kShapeTypeSpacing
, |
23 kTitleSpacing = 3 * kShapeSpacing / 4, | 23 kTitleSpacing = 3 * kShapeSpacing / 4, |
24 kSubtitleSpacing = 5 * kShapeSpacing / 8 | 24 kSubtitleSpacing = 5 * kShapeSpacing / 8 |
25 }; | 25 }; |
26 | 26 |
27 static const SkColor kBGColor = SkColorSetARGB(200, 210, 184, 135); | 27 static const SkColor kBGColor = SkColorSetARGB(200, 210, 184, 135); |
28 | 28 |
29 static const SkColor kShapeColors[2] = { | 29 static const SkColor kShapeColors[2] = { |
30 SkColorSetARGB(130, 255, 0, 128), // input color unknown | 30 SkColorSetARGB(130, 255, 0, 128), // input color unknown |
31 SkColorSetARGB(255, 0, 255, 255) // input color opaque | 31 SkColorSetARGB(255, 0, 255, 255) // input color opaque |
32 }; | 32 }; |
33 | 33 |
34 enum Shape { | 34 enum Shape { |
35 kSquare_Shape, | 35 kSquare_Shape, |
36 kDiamond_Shape, | 36 kDiamond_Shape, |
37 kOval_Shape, | 37 kOval_Shape, |
| 38 kConcave_Shape, |
38 | 39 |
39 kLast_Shape = kOval_Shape | 40 kLast_Shape = kConcave_Shape |
40 }; | 41 }; |
41 | 42 |
42 namespace skiagm { | 43 namespace skiagm { |
43 | 44 |
44 /** | 45 /** |
45 * Verifies AA works properly on all Xfermodes, including arithmetic, with both
opaque and unknown | 46 * Verifies AA works properly on all Xfermodes, including arithmetic, with both
opaque and unknown |
46 * src colors. | 47 * src colors. |
47 */ | 48 */ |
48 class AAXfermodesGM : public GM { | 49 class AAXfermodesGM : public GM { |
49 public: | 50 public: |
(...skipping 23 matching lines...) Expand all Loading... |
73 fLabelPaint.setTextSize(5 * kShapeSize/8); | 74 fLabelPaint.setTextSize(5 * kShapeSize/8); |
74 fLabelPaint.setSubpixelText(true); | 75 fLabelPaint.setSubpixelText(true); |
75 | 76 |
76 static const SkScalar radius = -1.4f * kShapeSize/2; | 77 static const SkScalar radius = -1.4f * kShapeSize/2; |
77 SkPoint pts[4] = { | 78 SkPoint pts[4] = { |
78 {-radius, 0}, | 79 {-radius, 0}, |
79 {0, -1.33f * radius}, | 80 {0, -1.33f * radius}, |
80 {radius, 0}, | 81 {radius, 0}, |
81 {0, 1.33f * radius} | 82 {0, 1.33f * radius} |
82 }; | 83 }; |
83 fPath.moveTo(pts[0]); | 84 fOval.moveTo(pts[0]); |
84 fPath.quadTo(pts[1], pts[2]); | 85 fOval.quadTo(pts[1], pts[2]); |
85 fPath.quadTo(pts[3], pts[0]); | 86 fOval.quadTo(pts[3], pts[0]); |
| 87 |
| 88 fConcave.moveTo(-radius, 0); |
| 89 fConcave.quadTo(0, 0, 0, -radius); |
| 90 fConcave.quadTo(0, 0, radius, 0); |
| 91 fConcave.quadTo(0, 0, 0, radius); |
| 92 fConcave.quadTo(0, 0, -radius, 0); |
| 93 fConcave.close(); |
86 } | 94 } |
87 | 95 |
88 void draw_pass(SkCanvas* canvas, DrawingPass drawingPass) { | 96 void draw_pass(SkCanvas* canvas, DrawingPass drawingPass) { |
89 SkRect clipRect = | 97 SkRect clipRect = |
90 { -kShapeSize*11/16, -kShapeSize*11/16, kShapeSize*11/16, kShape
Size*11/16 }; | 98 { -kShapeSize*11/16, -kShapeSize*11/16, kShapeSize*11/16, kShape
Size*11/16 }; |
91 | 99 |
92 canvas->save(); | 100 canvas->save(); |
93 if (kCheckerboard_Pass == drawingPass) { | 101 if (kCheckerboard_Pass == drawingPass) { |
94 canvas->translate(kMargin, kMargin); | 102 canvas->translate(kMargin, kMargin); |
95 } | 103 } |
96 canvas->translate(0, kTitleSpacing); | 104 canvas->translate(0, kTitleSpacing); |
97 | 105 |
98 for (size_t xfermodeSet = 0; xfermodeSet < 2; xfermodeSet++) { | 106 for (size_t xfermodeSet = 0; xfermodeSet < 2; xfermodeSet++) { |
99 size_t firstMode = (SkXfermode::kLastCoeffMode + 1) * xfermodeSet; | 107 size_t firstMode = (SkXfermode::kLastCoeffMode + 1) * xfermodeSet; |
100 canvas->save(); | 108 canvas->save(); |
101 | 109 |
102 if (kShape_Pass == drawingPass) { | 110 if (kShape_Pass == drawingPass) { |
103 fLabelPaint.setTextAlign(SkPaint::kCenter_Align); | 111 fLabelPaint.setTextAlign(SkPaint::kCenter_Align); |
104 canvas->drawText("Src Unknown", sizeof("Src Unknown") - 1, | 112 canvas->drawText("Src Unknown", sizeof("Src Unknown") - 1, |
105 kLabelSpacing + kShapeSpacing / 2 + kShapeTypeSpacing, | 113 kLabelSpacing + kShapeTypeSpacing * 1.5f + kShapeSpacing
/ 2, |
106 kSubtitleSpacing / 2 + fLabelPaint.getTextSize() / 3, fL
abelPaint); | 114 kSubtitleSpacing / 2 + fLabelPaint.getTextSize() / 3, fL
abelPaint); |
107 canvas->drawText("Src Opaque", sizeof("Src Opaque") - 1, | 115 canvas->drawText("Src Opaque", sizeof("Src Opaque") - 1, |
108 kLabelSpacing + kShapeSpacing / 2 + kShapeTypeSpacing +
kPaintSpacing, | 116 kLabelSpacing + kShapeTypeSpacing * 1.5f + kShapeSpacing
/ 2 + |
109 kSubtitleSpacing / 2 + fLabelPaint.getTextSize() / 3, fL
abelPaint); | 117 kPaintSpacing, kSubtitleSpacing / 2 + fLabelPaint.getTex
tSize() / 3, |
| 118 fLabelPaint); |
110 } | 119 } |
111 | 120 |
112 canvas->translate(0, kSubtitleSpacing + kShapeSpacing/2); | 121 canvas->translate(0, kSubtitleSpacing + kShapeSpacing/2); |
113 | 122 |
114 for (size_t m = 0; m <= SkXfermode::kLastCoeffMode; m++) { | 123 for (size_t m = 0; m <= SkXfermode::kLastCoeffMode; m++) { |
115 SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(firstMode
+ m); | 124 SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(firstMode
+ m); |
116 canvas->save(); | 125 canvas->save(); |
117 | 126 |
118 if (kShape_Pass == drawingPass) { | 127 if (kShape_Pass == drawingPass) { |
119 this->drawModeName(canvas, mode); | 128 this->drawModeName(canvas, mode); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 canvas->saveLayer(nullptr, nullptr); | 173 canvas->saveLayer(nullptr, nullptr); |
165 | 174 |
166 canvas->translate(kMargin, kMargin); | 175 canvas->translate(kMargin, kMargin); |
167 draw_pass(canvas, kBackground_Pass); | 176 draw_pass(canvas, kBackground_Pass); |
168 | 177 |
169 SkPaint titlePaint(fLabelPaint); | 178 SkPaint titlePaint(fLabelPaint); |
170 titlePaint.setTextSize(9 * titlePaint.getTextSize() / 8); | 179 titlePaint.setTextSize(9 * titlePaint.getTextSize() / 8); |
171 titlePaint.setFakeBoldText(true); | 180 titlePaint.setFakeBoldText(true); |
172 titlePaint.setTextAlign(SkPaint::kCenter_Align); | 181 titlePaint.setTextAlign(SkPaint::kCenter_Align); |
173 canvas->drawText("Porter Duff", sizeof("Porter Duff") - 1, | 182 canvas->drawText("Porter Duff", sizeof("Porter Duff") - 1, |
174 kLabelSpacing + 3 * kShapeTypeSpacing, | 183 kLabelSpacing + 4 * kShapeTypeSpacing, |
175 kTitleSpacing / 2 + titlePaint.getTextSize() / 3, title
Paint); | 184 kTitleSpacing / 2 + titlePaint.getTextSize() / 3, title
Paint); |
176 canvas->drawText("Advanced", sizeof("Advanced") - 1, | 185 canvas->drawText("Advanced", sizeof("Advanced") - 1, |
177 kXfermodeTypeSpacing + kLabelSpacing + 3 * kShapeTypeSp
acing, | 186 kXfermodeTypeSpacing + kLabelSpacing + 4 * kShapeTypeSp
acing, |
178 kTitleSpacing / 2 + titlePaint.getTextSize() / 3, title
Paint); | 187 kTitleSpacing / 2 + titlePaint.getTextSize() / 3, title
Paint); |
179 | 188 |
180 draw_pass(canvas, kShape_Pass); | 189 draw_pass(canvas, kShape_Pass); |
181 canvas->restore(); | 190 canvas->restore(); |
182 } | 191 } |
183 | 192 |
184 void drawModeName(SkCanvas* canvas, SkXfermode::Mode mode) { | 193 void drawModeName(SkCanvas* canvas, SkXfermode::Mode mode) { |
185 const char* modeName = mode <= SkXfermode::kLastMode ? SkXfermode::ModeN
ame(mode) | 194 const char* modeName = mode <= SkXfermode::kLastMode ? SkXfermode::ModeN
ame(mode) |
186 : "Arithmetic"; | 195 : "Arithmetic"; |
187 fLabelPaint.setTextAlign(SkPaint::kRight_Align); | 196 fLabelPaint.setTextAlign(SkPaint::kRight_Align); |
188 canvas->drawText(modeName, strlen(modeName), kLabelSpacing - kShapeSize
/ 4, | 197 canvas->drawText(modeName, strlen(modeName), kLabelSpacing - kShapeSize
/ 4, |
189 fLabelPaint.getTextSize() / 3, fLabelPaint); | 198 fLabelPaint.getTextSize() / 4, fLabelPaint); |
190 } | 199 } |
191 | 200 |
192 void setupShapePaint(SkCanvas* canvas, GrColor color, SkXfermode::Mode mode,
SkPaint* paint) { | 201 void setupShapePaint(SkCanvas* canvas, GrColor color, SkXfermode::Mode mode,
SkPaint* paint) { |
193 paint->setColor(color); | 202 paint->setColor(color); |
194 | 203 |
195 if (mode == SkXfermode::kPlus_Mode) { | 204 if (mode == SkXfermode::kPlus_Mode) { |
196 // Check for overflow, otherwise we might get confusing AA artifacts
. | 205 // Check for overflow, otherwise we might get confusing AA artifacts
. |
197 int maxSum = SkTMax(SkTMax(SkColorGetA(kBGColor) + SkColorGetA(color
), | 206 int maxSum = SkTMax(SkTMax(SkColorGetA(kBGColor) + SkColorGetA(color
), |
198 SkColorGetR(kBGColor) + SkColorGetR(color
)), | 207 SkColorGetR(kBGColor) + SkColorGetR(color
)), |
199 SkTMax(SkColorGetG(kBGColor) + SkColorGetG(color
), | 208 SkTMax(SkColorGetG(kBGColor) + SkColorGetG(color
), |
200 SkColorGetB(kBGColor) + SkColorGetB(color
))); | 209 SkColorGetB(kBGColor) + SkColorGetB(color
))); |
201 | 210 |
202 if (maxSum > 255) { | 211 if (maxSum > 255) { |
203 SkPaint dimPaint; | 212 SkPaint dimPaint; |
204 dimPaint.setAntiAlias(false); | 213 dimPaint.setAntiAlias(false); |
205 dimPaint.setXfermode(SkXfermode::Create(SkXfermode::kDstIn_Mode)
); | 214 dimPaint.setXfermode(SkXfermode::Create(SkXfermode::kDstIn_Mode)
); |
206 if (255 != paint->getAlpha()) { | 215 if (255 != paint->getAlpha()) { |
207 // Dim the src and dst colors. | 216 // Dim the src and dst colors. |
208 dimPaint.setARGB(255 * 255 / maxSum, 0, 0, 0); | 217 dimPaint.setARGB(255 * 255 / maxSum, 0, 0, 0); |
209 paint->setAlpha(255 * paint->getAlpha() / maxSum); | 218 paint->setAlpha(255 * paint->getAlpha() / maxSum); |
210 } else { | 219 } else { |
211 // Just clear the dst, we need to preserve the paint's opaci
ty. | 220 // Just clear the dst, we need to preserve the paint's opaci
ty. |
212 dimPaint.setARGB(0, 0, 0, 0); | 221 dimPaint.setARGB(0, 0, 0, 0); |
213 } | 222 } |
214 canvas->drawRectCoords(-kShapeSpacing/2, -kShapeSpacing/2, | 223 canvas->drawRectCoords(-kShapeSpacing/2, -kShapeSpacing/2, |
215 kShapeSpacing/2 + 2 * kShapeTypeSpacing, | 224 kShapeSpacing/2 + 3 * kShapeTypeSpacing, |
216 kShapeSpacing/2, dimPaint); | 225 kShapeSpacing/2, dimPaint); |
217 } | 226 } |
218 } | 227 } |
219 } | 228 } |
220 | 229 |
221 void drawShape(SkCanvas* canvas, Shape shape, const SkPaint& paint, SkXfermo
de::Mode mode) { | 230 void drawShape(SkCanvas* canvas, Shape shape, const SkPaint& paint, SkXfermo
de::Mode mode) { |
222 SkPaint shapePaint(paint); | 231 SkPaint shapePaint(paint); |
223 shapePaint.setAntiAlias(kSquare_Shape != shape); | 232 shapePaint.setAntiAlias(kSquare_Shape != shape); |
224 | 233 |
225 SkAutoTUnref<SkXfermode> xfermode; | 234 SkAutoTUnref<SkXfermode> xfermode; |
(...skipping 14 matching lines...) Expand all Loading... |
240 canvas->save(); | 249 canvas->save(); |
241 canvas->rotate(45); | 250 canvas->rotate(45); |
242 canvas->drawRectCoords(-kShapeSize/2, -kShapeSize/2, kShapeSize/
2, kShapeSize/2, | 251 canvas->drawRectCoords(-kShapeSize/2, -kShapeSize/2, kShapeSize/
2, kShapeSize/2, |
243 shapePaint); | 252 shapePaint); |
244 canvas->restore(); | 253 canvas->restore(); |
245 break; | 254 break; |
246 | 255 |
247 case kOval_Shape: | 256 case kOval_Shape: |
248 canvas->save(); | 257 canvas->save(); |
249 canvas->rotate(static_cast<SkScalar>((511 * mode + 257) % 360)); | 258 canvas->rotate(static_cast<SkScalar>((511 * mode + 257) % 360)); |
250 canvas->drawPath(fPath, shapePaint); | 259 canvas->drawPath(fOval, shapePaint); |
251 canvas->restore(); | 260 canvas->restore(); |
252 break; | 261 break; |
253 | 262 |
| 263 case kConcave_Shape: |
| 264 canvas->drawPath(fConcave, shapePaint); |
| 265 break; |
| 266 |
254 default: | 267 default: |
255 SkFAIL("Invalid shape."); | 268 SkFAIL("Invalid shape."); |
256 } | 269 } |
257 } | 270 } |
258 | 271 |
259 private: | 272 private: |
260 SkPaint fLabelPaint; | 273 SkPaint fLabelPaint; |
261 SkPath fPath; | 274 SkPath fOval; |
| 275 SkPath fConcave; |
262 | 276 |
263 typedef GM INHERITED; | 277 typedef GM INHERITED; |
264 }; | 278 }; |
265 | 279 |
266 ////////////////////////////////////////////////////////////////////////////// | 280 ////////////////////////////////////////////////////////////////////////////// |
267 | 281 |
268 static GM* MyFactory(void*) { return new AAXfermodesGM; } | 282 static GM* MyFactory(void*) { return new AAXfermodesGM; } |
269 static GMRegistry reg(MyFactory); | 283 static GMRegistry reg(MyFactory); |
270 | 284 |
271 } | 285 } |
OLD | NEW |