• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkSurface.h"
9 #include "Resources.h"
10 #include "gm.h"
11 #include "sk_tool_utils.h"
12 
13 #include "SkColorPriv.h"
14 #include "SkFont.h"
15 #include "SkMath.h"
16 
copy_bitmap(const SkBitmap & src,SkColorType colorType)17 static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
18     const SkBitmap* srcPtr = &src;
19     SkBitmap tmp(src);
20     if (kRGB_565_SkColorType == colorType) {
21         tmp.setAlphaType(kOpaque_SkAlphaType);
22         srcPtr = &tmp;
23     }
24 
25     SkBitmap copy;
26     sk_tool_utils::copy_to(&copy, colorType, *srcPtr);
27     copy.setImmutable();
28     return copy;
29 }
30 
31 #define SCALE 128
32 
33 // Make either A8 or gray8 bitmap.
make_bitmap(SkColorType ct)34 static SkBitmap make_bitmap(SkColorType ct) {
35     SkBitmap bm;
36     switch (ct) {
37         case kAlpha_8_SkColorType:
38             bm.allocPixels(SkImageInfo::MakeA8(SCALE, SCALE));
39             break;
40         case kGray_8_SkColorType:
41             bm.allocPixels(
42                     SkImageInfo::Make(SCALE, SCALE, ct, kOpaque_SkAlphaType));
43             break;
44         default:
45             SkASSERT(false);
46             return bm;
47     }
48     uint8_t spectrum[256];
49     for (int y = 0; y < 256; ++y) {
50         spectrum[y] = y;
51     }
52     for (int y = 0; y < 128; ++y) {
53         // Shift over one byte each scanline.
54         memcpy(bm.getAddr8(0, y), &spectrum[y], 128);
55     }
56     bm.setImmutable();
57     return bm;
58 }
59 
draw_center_letter(char c,const SkFont & font,SkColor color,SkScalar x,SkScalar y,SkCanvas * canvas)60 static void draw_center_letter(char c, const SkFont& font, SkColor color,
61                                SkScalar x, SkScalar y, SkCanvas* canvas) {
62     SkPaint paint;
63     paint.setColor(color);
64     SkRect bounds;
65     font.measureText(&c, 1, kUTF8_SkTextEncoding, &bounds);
66     canvas->drawSimpleText(&c, 1, kUTF8_SkTextEncoding,
67                            x - bounds.centerX(), y - bounds.centerY(),
68                            font, paint);
69 }
70 
color_wheel_native(SkCanvas * canvas)71 static void color_wheel_native(SkCanvas* canvas) {
72     SkAutoCanvasRestore autoCanvasRestore(canvas, true);
73     canvas->translate(0.5f * SCALE, 0.5f * SCALE);
74     SkPaint p;
75     p.setColor(SK_ColorWHITE);
76     canvas->drawCircle(0.0f, 0.0f, SCALE * 0.5f, p);
77 
78     const double sqrt_3_over_2 = 0.8660254037844387;
79     const SkScalar Z = 0.0f;
80     const SkScalar D = 0.3f * SkIntToScalar(SCALE);
81     const SkScalar X = SkDoubleToScalar(D * sqrt_3_over_2);
82     const SkScalar Y = D * SK_ScalarHalf;
83 
84     SkFont font;
85     font.setEdging(SkFont::Edging::kAlias);
86     font.setTypeface(sk_tool_utils::create_portable_typeface(nullptr, SkFontStyle::Bold()));
87     font.setSize(0.28125f * SCALE);
88     draw_center_letter('K', font, SK_ColorBLACK, Z, Z, canvas);
89     draw_center_letter('R', font, SK_ColorRED, Z, D, canvas);
90     draw_center_letter('G', font, SK_ColorGREEN, -X, -Y, canvas);
91     draw_center_letter('B', font, SK_ColorBLUE, X, -Y, canvas);
92     draw_center_letter('C', font, SK_ColorCYAN, Z, -D, canvas);
93     draw_center_letter('M', font, SK_ColorMAGENTA, X, Y, canvas);
94     draw_center_letter('Y', font, SK_ColorYELLOW, -X, Y, canvas);
95 }
96 
97 template <typename T>
find(T * array,int N,T item)98 int find(T* array, int N, T item) {
99     for (int i = 0; i < N; ++i) {
100         if (array[i] == item) {
101             return i;
102         }
103     }
104     return -1;
105 }
106 
draw(SkCanvas * canvas,const SkPaint & p,const SkFont & font,const SkBitmap & src,SkColorType colorType,const char text[])107 static void draw(SkCanvas* canvas,
108                  const SkPaint& p,
109                  const SkFont& font,
110                  const SkBitmap& src,
111                  SkColorType colorType,
112                  const char text[]) {
113     SkASSERT(src.colorType() == colorType);
114     canvas->drawBitmap(src, 0.0f, 0.0f);
115     canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 0.0f, 12.0f, font, p);
116 }
117 
118 DEF_SIMPLE_GM(all_bitmap_configs, canvas, SCALE, 6 * SCALE) {
119     SkAutoCanvasRestore autoCanvasRestore(canvas, true);
120     SkPaint p;
121     p.setColor(SK_ColorBLACK);
122     p.setAntiAlias(true);
123 
124     SkFont font(sk_tool_utils::create_portable_typeface());
125 
126     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
127 
128     SkBitmap bitmap;
129     if (GetResourceAsBitmap("images/color_wheel.png", &bitmap)) {
130         bitmap.setImmutable();
131         draw(canvas, p, font, bitmap, kN32_SkColorType, "Native 32");
132 
133         canvas->translate(0.0f, SkIntToScalar(SCALE));
134         SkBitmap copy565 = copy_bitmap(bitmap, kRGB_565_SkColorType);
135         p.setColor(SK_ColorRED);
136         draw(canvas, p, font, copy565, kRGB_565_SkColorType, "RGB 565");
137         p.setColor(SK_ColorBLACK);
138 
139         canvas->translate(0.0f, SkIntToScalar(SCALE));
140         SkBitmap copy4444 = copy_bitmap(bitmap, kARGB_4444_SkColorType);
141         draw(canvas, p, font, copy4444, kARGB_4444_SkColorType, "ARGB 4444");
142 
143         canvas->translate(0.0f, SkIntToScalar(SCALE));
144         SkBitmap copyF16 = copy_bitmap(bitmap, kRGBA_F16_SkColorType);
145         draw(canvas, p, font, copyF16, kRGBA_F16_SkColorType, "RGBA F16");
146 
147     } else {
148         canvas->translate(0.0f, SkIntToScalar(3 * SCALE));
149     }
150 
151     canvas->translate(0.0f, SkIntToScalar(SCALE));
152     SkBitmap bitmapA8 = make_bitmap(kAlpha_8_SkColorType);
153     draw(canvas, p, font, bitmapA8, kAlpha_8_SkColorType, "Alpha 8");
154 
155     p.setColor(SK_ColorRED);
156     canvas->translate(0.0f, SkIntToScalar(SCALE));
157     SkBitmap bitmapG8 = make_bitmap(kGray_8_SkColorType);
158     draw(canvas, p, font, bitmapG8, kGray_8_SkColorType, "Gray 8");
159 }
160 
make_not_native32_color_wheel()161 sk_sp<SkImage> make_not_native32_color_wheel() {
162     SkBitmap n32bitmap, notN32bitmap;
163     n32bitmap.allocN32Pixels(SCALE, SCALE);
164     n32bitmap.eraseColor(SK_ColorTRANSPARENT);
165     SkCanvas n32canvas(n32bitmap);
166     color_wheel_native(&n32canvas);
167     n32canvas.flush();
168     #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
169         const SkColorType ct = kRGBA_8888_SkColorType;
170     #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
171         const SkColorType ct = kBGRA_8888_SkColorType;
172     #endif
173     static_assert(ct != kN32_SkColorType, "BRGA!=RGBA");
174     SkAssertResult(sk_tool_utils::copy_to(&notN32bitmap, ct, n32bitmap));
175     SkASSERT(notN32bitmap.colorType() == ct);
176     return SkImage::MakeFromBitmap(notN32bitmap);
177 }
178 
DEF_SIMPLE_GM(not_native32_bitmap_config,canvas,SCALE,SCALE)179 DEF_SIMPLE_GM(not_native32_bitmap_config, canvas, SCALE, SCALE) {
180     sk_sp<SkImage> notN32image(make_not_native32_color_wheel());
181     SkASSERT(notN32image);
182     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
183     canvas->drawImage(notN32image.get(), 0.0f, 0.0f);
184 }
185 
make_pixel(int x,int y,SkAlphaType alphaType)186 static uint32_t make_pixel(int x, int y, SkAlphaType alphaType) {
187     SkASSERT(x >= 0 && x < SCALE);
188     SkASSERT(y >= 0 && y < SCALE);
189 
190     SkScalar R = SCALE / 2.0f;
191 
192     uint32_t alpha = 0x00;
193 
194     if ((x - R) * (x - R) + (y - R) * (y - R) < R * R) {
195         alpha = 0xFF;
196     }
197 
198     uint32_t component;
199     switch (alphaType) {
200         case kPremul_SkAlphaType:
201             component = alpha;
202             break;
203         case kUnpremul_SkAlphaType:
204             component = 0xFF;
205             break;
206         default:
207             SK_ABORT("Should not get here - invalid alpha type");
208             return 0xFF000000;
209     }
210     return alpha << 24 | component;
211 }
212 
make_color_test_bitmap_variant(SkColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,SkBitmap * bm)213 static void make_color_test_bitmap_variant(
214     SkColorType colorType,
215     SkAlphaType alphaType,
216     sk_sp<SkColorSpace> colorSpace,
217     SkBitmap* bm)
218 {
219     SkASSERT(colorType == kRGBA_8888_SkColorType || colorType == kBGRA_8888_SkColorType);
220     SkASSERT(alphaType == kPremul_SkAlphaType || alphaType == kUnpremul_SkAlphaType);
221     bm->allocPixels(
222         SkImageInfo::Make(SCALE, SCALE, colorType, alphaType, colorSpace));
223     const SkPixmap& pm = bm->pixmap();
224     for (int y = 0; y < pm.height(); y++) {
225         for (int x = 0; x < pm.width(); x++) {
226             *pm.writable_addr32(x, y) = make_pixel(x, y, alphaType);
227         }
228     }
229 }
230 
231 DEF_SIMPLE_GM(all_variants_8888, canvas, 4 * SCALE + 30, 2 * SCALE + 10) {
232     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
233 
234     sk_sp<SkColorSpace> colorSpaces[] {
235         SkColorSpace::MakeSRGB(),
236         nullptr,
237     };
238     for (auto colorSpace : colorSpaces) {
239         canvas->save();
240         for (auto alphaType : {kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
241             canvas->save();
242             for (auto colorType : {kRGBA_8888_SkColorType, kBGRA_8888_SkColorType}) {
243                 SkBitmap bm;
244                 make_color_test_bitmap_variant(colorType, alphaType, colorSpace, &bm);
245                 canvas->drawBitmap(bm, 0.0f, 0.0f);
246                 canvas->translate(SCALE + 10, 0.0f);
247             }
248             canvas->restore();
249             canvas->translate(0.0f, SCALE + 10);
250         }
251         canvas->restore();
252         canvas->translate(2 * (SCALE + 10), 0.0f);
253     }
254 }
255