OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 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 "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkRandom.h" | 10 #include "SkRandom.h" |
11 #include "SkShader.h" | 11 #include "SkShader.h" |
12 #include "SkXfermode.h" | 12 #include "SkXfermode.h" |
13 | 13 |
14 namespace skiagm { | 14 namespace skiagm { |
15 | 15 |
16 /** | 16 /** |
17 * Renders overlapping circles with random SkXfermode::Modes against a checkerbo ard. | 17 * Renders overlapping shapes with random SkXfermode::Modes against a checkerboa rd. |
18 */ | 18 */ |
19 class MixedXfermodesGM : public GM { | 19 class MixedXfermodesGM : public GM { |
20 public: | 20 public: |
21 MixedXfermodesGM() { | 21 MixedXfermodesGM() { |
robertphillips
2013/05/14 21:49:37
Move this into an initialization method to make th
bsalomon
2013/05/15 13:10:20
Done.
| |
22 static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCC CC, 0xFFFFFFFF }; | 22 static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCC CC, 0xFFFFFFFF }; |
23 SkBitmap bitmap; | 23 SkBitmap bitmap; |
24 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2, 2 * sizeof(uint32_t) ); | 24 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2, 2 * sizeof(uint32_t) ); |
25 bitmap.allocPixels(); | 25 bitmap.allocPixels(); |
26 bitmap.lockPixels(); | 26 bitmap.lockPixels(); |
27 memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData)) ; | 27 memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData)) ; |
28 bitmap.unlockPixels(); | 28 bitmap.unlockPixels(); |
29 fBG.reset(SkShader::CreateBitmapShader(bitmap, | 29 fBG.reset(SkShader::CreateBitmapShader(bitmap, |
30 SkShader::kRepeat_TileMode, | 30 SkShader::kRepeat_TileMode, |
31 SkShader::kRepeat_TileMode)); | 31 SkShader::kRepeat_TileMode)); |
32 SkASSERT(NULL != fBG); | 32 SkASSERT(NULL != fBG); |
33 SkMatrix lm; | 33 SkMatrix lm; |
34 lm.setScale(SkIntToScalar(20), SkIntToScalar(20)); | 34 lm.setScale(SkIntToScalar(20), SkIntToScalar(20)); |
35 fBG->setLocalMatrix(lm); | 35 fBG->setLocalMatrix(lm); |
36 } | 36 } |
37 | 37 |
38 protected: | 38 protected: |
robertphillips
2013/05/14 21:49:37
overrides?
bsalomon
2013/05/15 13:10:20
Done.
| |
39 virtual SkString onShortName() { | 39 virtual SkString onShortName() { |
40 return SkString("mixed_xfermodes"); | 40 return SkString("mixed_xfermodes"); |
41 } | 41 } |
42 | 42 |
43 virtual SkISize onISize() { | 43 virtual SkISize onISize() { |
44 return make_isize(790, 640); | 44 return make_isize(790, 640); |
45 } | 45 } |
46 | 46 |
47 virtual void drawShape(SkCanvas* canvas, | |
48 const SkPaint& paint, | |
49 SkMWCRandom* random) { | |
50 static const SkRect kRect = SkRect::MakeXYWH(SkIntToScalar(-50), SkIntTo Scalar(-50), | |
51 SkIntToScalar(75), SkIntToS calar(105)); | |
robertphillips
2013/05/14 21:49:37
x -> drawOption? geometry?
bsalomon
2013/05/15 13:10:20
shape
| |
52 int x = random->nextULessThan(5); | |
53 switch (x) { | |
54 case 0: | |
55 canvas->drawCircle(0, 0, 50, paint); | |
56 break; | |
57 case 1: | |
58 canvas->drawRoundRect(kRect, SkIntToScalar(10), SkIntToScalar(20), p aint); | |
59 break; | |
60 case 2: | |
61 canvas->drawRect(kRect, paint); | |
62 break; | |
63 case 3: | |
64 if (fConvexPath.isEmpty()) { | |
65 SkPoint points[4]; | |
66 kRect.toQuad(points); | |
67 fConvexPath.moveTo(points[0]); | |
68 fConvexPath.quadTo(points[1], points[2]); | |
69 fConvexPath.quadTo(points[3], points[0]); | |
robertphillips
2013/05/14 21:49:37
assert that 'fConvexPath' is indeed convex?
bsalomon
2013/05/15 13:10:20
Done.
| |
70 } | |
71 canvas->drawPath(fConvexPath, paint); | |
72 break; | |
73 case 4: | |
74 if (fConcavePath.isEmpty()) { | |
75 SkPoint points[5] = {{0, SkIntToScalar(-50)} }; | |
76 SkMatrix rot; | |
77 rot.setRotate(SkIntToScalar(360) / 5); | |
78 for (int i = 1; i < 5; ++i) { | |
79 rot.mapPoints(points + i, points + i - 1, 1); | |
80 } | |
81 fConcavePath.moveTo(points[0]); | |
82 for (int i = 0; i < 5; ++i) { | |
83 fConcavePath.lineTo(points[(2 * i) % 5]); | |
84 } | |
85 fConcavePath.setFillType(SkPath::kEvenOdd_FillType); | |
robertphillips
2013/05/14 21:49:37
assert that 'fConcavePath' is non-convex?
bsalomon
2013/05/15 13:10:20
Done.
| |
86 } | |
87 canvas->drawPath(fConcavePath, paint); | |
88 break; | |
89 } | |
90 } | |
91 | |
47 virtual void onDraw(SkCanvas* canvas) { | 92 virtual void onDraw(SkCanvas* canvas) { |
48 SkPaint bgPaint; | 93 SkPaint bgPaint; |
49 bgPaint.setShader(fBG.get()); | 94 bgPaint.setShader(fBG.get()); |
50 canvas->drawPaint(bgPaint); | 95 canvas->drawPaint(bgPaint); |
51 SkISize size = canvas->getDeviceSize(); | 96 SkISize size = canvas->getDeviceSize(); |
52 SkScalar areaSqrt = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeig ht))); | 97 SkScalar maxScale = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeig ht))) / 300; |
53 SkScalar minR = areaSqrt / 10; | |
54 SkScalar maxR = areaSqrt / 4; | |
55 SkMWCRandom random; | 98 SkMWCRandom random; |
56 for (int i = 0; i < kNumCircles; ++i) { | 99 for (int i = 0; i < kNumShapes; ++i) { |
57 SkScalar cx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth)); | 100 SkScalar s = random.nextRangeScalar(SK_Scalar1 / 8, SK_Scalar1) * ma xScale; |
58 SkScalar cy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight)) ; | 101 SkScalar r = random.nextRangeScalar(0, SkIntToScalar(360)); |
59 SkScalar r = random.nextRangeScalar(minR, maxR); | 102 SkScalar dx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth)); |
103 SkScalar dy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight)) ; | |
60 SkColor color = random.nextU(); | 104 SkColor color = random.nextU(); |
61 | |
62 SkXfermode::Mode mode = | 105 SkXfermode::Mode mode = |
63 static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::k LastMode + 1)); | 106 static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::k LastMode + 1)); |
64 // FIXME: Currently testing kDarken on GPU. | |
65 mode = SkXfermode::kDarken_Mode; | |
66 | 107 |
67 SkPaint p; | 108 SkPaint p; |
68 p.setAntiAlias(true); | 109 p.setAntiAlias(true); |
69 p.setColor(color); | 110 p.setColor(color); |
70 p.setXfermodeMode(mode); | 111 p.setXfermodeMode(mode); |
71 canvas->drawCircle(cx, cy, r, p); | 112 canvas->save(); |
113 canvas->translate(dx, dy); | |
114 canvas->scale(s, s); | |
115 canvas->rotate(r); | |
116 this->drawShape(canvas, p, &random); | |
117 canvas->restore(); | |
72 } | 118 } |
73 | |
74 // FIXME: Remove text draw once this GM is finished. | |
75 SkPaint txtPaint; | |
76 txtPaint.setTextSize(areaSqrt / 20); | |
77 txtPaint.setAntiAlias(true); | |
78 static const char kTxt[] = "Work in progres... Do not baseline."; | |
79 canvas->drawText(kTxt, strlen(kTxt), | |
80 areaSqrt/50, | |
81 SkIntToScalar(size.fHeight / 2), | |
82 txtPaint); | |
83 } | 119 } |
84 | 120 |
85 private: | 121 private: |
86 enum { | 122 enum { |
87 kMinR = 10, | 123 kNumShapes = 100, |
88 kMaxR = 50, | |
89 kNumCircles = 50, | |
90 }; | 124 }; |
91 SkAutoTUnref<SkShader> fBG; | 125 SkAutoTUnref<SkShader> fBG; |
126 SkPath fConcavePath; | |
127 SkPath fConvexPath; | |
92 typedef GM INHERITED; | 128 typedef GM INHERITED; |
93 }; | 129 }; |
94 | 130 |
95 ////////////////////////////////////////////////////////////////////////////// | 131 ////////////////////////////////////////////////////////////////////////////// |
96 | 132 |
97 static GM* MyFactory(void*) { return new MixedXfermodesGM; } | 133 static GM* MyFactory(void*) { return new MixedXfermodesGM; } |
98 static GMRegistry reg(MyFactory); | 134 static GMRegistry reg(MyFactory); |
99 | 135 |
100 } | 136 } |
OLD | NEW |