blob: db3297b36914c55e37a83ea81f09574d63664a7e [file] [log] [blame]
halcanarydb0dcc72015-03-20 12:31:52 -07001/*
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
halcanarydb0dcc72015-03-20 12:31:52 -07008#include "SkSurface.h"
9#include "Resources.h"
10#include "gm.h"
Mike Klein33d20552017-03-22 13:47:51 -040011#include "sk_tool_utils.h"
halcanarydb0dcc72015-03-20 12:31:52 -070012
halcanarydb0dcc72015-03-20 12:31:52 -070013#include "SkColorPriv.h"
Mike Reed94cca602018-12-02 16:04:27 -050014#include "SkFont.h"
15#include "SkMath.h"
halcanarydb0dcc72015-03-20 12:31:52 -070016
17static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
Matt Sarett68b8e3d2017-04-28 11:15:22 -040018 const SkBitmap* srcPtr = &src;
19 SkBitmap tmp(src);
20 if (kRGB_565_SkColorType == colorType) {
21 tmp.setAlphaType(kOpaque_SkAlphaType);
22 srcPtr = &tmp;
23 }
24
halcanarydb0dcc72015-03-20 12:31:52 -070025 SkBitmap copy;
Matt Sarett68b8e3d2017-04-28 11:15:22 -040026 sk_tool_utils::copy_to(&copy, colorType, *srcPtr);
halcanarydb0dcc72015-03-20 12:31:52 -070027 copy.setImmutable();
28 return copy;
29}
30
31#define SCALE 128
32
33// Make either A8 or gray8 bitmap.
34static 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 }
halcanarydb0dcc72015-03-20 12:31:52 -070048 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
Mike Reed94cca602018-12-02 16:04:27 -050060static 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);
halcanarydb0dcc72015-03-20 12:31:52 -070064 SkRect bounds;
Mike Reed94cca602018-12-02 16:04:27 -050065 font.measureText(&c, 1, kUTF8_SkTextEncoding, &bounds);
66 canvas->drawSimpleText(&c, 1, kUTF8_SkTextEncoding,
67 x - bounds.centerX(), y - bounds.centerY(),
68 font, paint);
halcanarydb0dcc72015-03-20 12:31:52 -070069}
70
71static void color_wheel_native(SkCanvas* canvas) {
72 SkAutoCanvasRestore autoCanvasRestore(canvas, true);
73 canvas->translate(0.5f * SCALE, 0.5f * SCALE);
74 SkPaint p;
halcanarydb0dcc72015-03-20 12:31:52 -070075 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;
Mike Reed94cca602018-12-02 16:04:27 -050083
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);
halcanarydb0dcc72015-03-20 12:31:52 -070095}
96
97template <typename T>
98int 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
halcanarydb0dcc72015-03-20 12:31:52 -0700107static void draw(SkCanvas* canvas,
108 const SkPaint& p,
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500109 const SkFont& font,
halcanarydb0dcc72015-03-20 12:31:52 -0700110 const SkBitmap& src,
111 SkColorType colorType,
112 const char text[]) {
113 SkASSERT(src.colorType() == colorType);
114 canvas->drawBitmap(src, 0.0f, 0.0f);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500115 canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 0.0f, 12.0f, font, p);
halcanarydb0dcc72015-03-20 12:31:52 -0700116}
117
Brian Osman567f4fd2018-09-12 11:48:38 -0400118DEF_SIMPLE_GM(all_bitmap_configs, canvas, SCALE, 6 * SCALE) {
halcanarydb0dcc72015-03-20 12:31:52 -0700119 SkAutoCanvasRestore autoCanvasRestore(canvas, true);
120 SkPaint p;
121 p.setColor(SK_ColorBLACK);
122 p.setAntiAlias(true);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500123
124 SkFont font(sk_tool_utils::create_portable_typeface());
halcanarydb0dcc72015-03-20 12:31:52 -0700125
126 sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
127
128 SkBitmap bitmap;
Hal Canaryc465d132017-12-08 10:21:31 -0500129 if (GetResourceAsBitmap("images/color_wheel.png", &bitmap)) {
halcanarydb0dcc72015-03-20 12:31:52 -0700130 bitmap.setImmutable();
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500131 draw(canvas, p, font, bitmap, kN32_SkColorType, "Native 32");
halcanarydb0dcc72015-03-20 12:31:52 -0700132
133 canvas->translate(0.0f, SkIntToScalar(SCALE));
134 SkBitmap copy565 = copy_bitmap(bitmap, kRGB_565_SkColorType);
135 p.setColor(SK_ColorRED);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500136 draw(canvas, p, font, copy565, kRGB_565_SkColorType, "RGB 565");
halcanarydb0dcc72015-03-20 12:31:52 -0700137 p.setColor(SK_ColorBLACK);
138
139 canvas->translate(0.0f, SkIntToScalar(SCALE));
140 SkBitmap copy4444 = copy_bitmap(bitmap, kARGB_4444_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500141 draw(canvas, p, font, copy4444, kARGB_4444_SkColorType, "ARGB 4444");
Brian Osman567f4fd2018-09-12 11:48:38 -0400142
143 canvas->translate(0.0f, SkIntToScalar(SCALE));
144 SkBitmap copyF16 = copy_bitmap(bitmap, kRGBA_F16_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500145 draw(canvas, p, font, copyF16, kRGBA_F16_SkColorType, "RGBA F16");
Brian Osman567f4fd2018-09-12 11:48:38 -0400146
halcanarydb0dcc72015-03-20 12:31:52 -0700147 } else {
Brian Osman567f4fd2018-09-12 11:48:38 -0400148 canvas->translate(0.0f, SkIntToScalar(3 * SCALE));
halcanarydb0dcc72015-03-20 12:31:52 -0700149 }
150
151 canvas->translate(0.0f, SkIntToScalar(SCALE));
halcanarydb0dcc72015-03-20 12:31:52 -0700152 SkBitmap bitmapA8 = make_bitmap(kAlpha_8_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500153 draw(canvas, p, font, bitmapA8, kAlpha_8_SkColorType, "Alpha 8");
halcanarydb0dcc72015-03-20 12:31:52 -0700154
155 p.setColor(SK_ColorRED);
156 canvas->translate(0.0f, SkIntToScalar(SCALE));
157 SkBitmap bitmapG8 = make_bitmap(kGray_8_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500158 draw(canvas, p, font, bitmapG8, kGray_8_SkColorType, "Gray 8");
halcanarydb0dcc72015-03-20 12:31:52 -0700159}
halcanaryaa4ba902015-11-06 07:27:23 -0800160
reed9ce9d672016-03-17 10:51:11 -0700161sk_sp<SkImage> make_not_native32_color_wheel() {
halcanaryaa4ba902015-11-06 07:27:23 -0800162 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");
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400174 SkAssertResult(sk_tool_utils::copy_to(&notN32bitmap, ct, n32bitmap));
halcanaryaa4ba902015-11-06 07:27:23 -0800175 SkASSERT(notN32bitmap.colorType() == ct);
reed9ce9d672016-03-17 10:51:11 -0700176 return SkImage::MakeFromBitmap(notN32bitmap);
halcanaryaa4ba902015-11-06 07:27:23 -0800177}
178
179DEF_SIMPLE_GM(not_native32_bitmap_config, canvas, SCALE, SCALE) {
reed9ce9d672016-03-17 10:51:11 -0700180 sk_sp<SkImage> notN32image(make_not_native32_color_wheel());
halcanaryaa4ba902015-11-06 07:27:23 -0800181 SkASSERT(notN32image);
182 sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
reed9ce9d672016-03-17 10:51:11 -0700183 canvas->drawImage(notN32image.get(), 0.0f, 0.0f);
halcanaryaa4ba902015-11-06 07:27:23 -0800184}
herb58238462016-06-03 09:44:53 -0700185
186static 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:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400207 SK_ABORT("Should not get here - invalid alpha type");
herb58238462016-06-03 09:44:53 -0700208 return 0xFF000000;
209 }
210 return alpha << 24 | component;
211}
212
213static void make_color_test_bitmap_variant(
214 SkColorType colorType,
215 SkAlphaType alphaType,
brianosman52ede1d2016-06-20 08:25:02 -0700216 sk_sp<SkColorSpace> colorSpace,
herb58238462016-06-03 09:44:53 -0700217 SkBitmap* bm)
218{
219 SkASSERT(colorType == kRGBA_8888_SkColorType || colorType == kBGRA_8888_SkColorType);
220 SkASSERT(alphaType == kPremul_SkAlphaType || alphaType == kUnpremul_SkAlphaType);
221 bm->allocPixels(
brianosman52ede1d2016-06-20 08:25:02 -0700222 SkImageInfo::Make(SCALE, SCALE, colorType, alphaType, colorSpace));
Hal Canary99578d22017-12-14 21:13:47 -0500223 const SkPixmap& pm = bm->pixmap();
Hal Canarya0883652017-12-14 15:33:23 -0500224 for (int y = 0; y < pm.height(); y++) {
225 for (int x = 0; x < pm.width(); x++) {
herb58238462016-06-03 09:44:53 -0700226 *pm.writable_addr32(x, y) = make_pixel(x, y, alphaType);
227 }
228 }
229}
230
Joe Gregorioc4859072017-01-20 14:21:27 +0000231DEF_SIMPLE_GM(all_variants_8888, canvas, 4 * SCALE + 30, 2 * SCALE + 10) {
herb58238462016-06-03 09:44:53 -0700232 sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
233
brianosman52ede1d2016-06-20 08:25:02 -0700234 sk_sp<SkColorSpace> colorSpaces[] {
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500235 SkColorSpace::MakeSRGB(),
brianosman52ede1d2016-06-20 08:25:02 -0700236 nullptr,
brianosman52ede1d2016-06-20 08:25:02 -0700237 };
238 for (auto colorSpace : colorSpaces) {
herb58238462016-06-03 09:44:53 -0700239 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;
brianosman52ede1d2016-06-20 08:25:02 -0700244 make_color_test_bitmap_variant(colorType, alphaType, colorSpace, &bm);
herb58238462016-06-03 09:44:53 -0700245 canvas->drawBitmap(bm, 0.0f, 0.0f);
246 canvas->translate(SCALE + 10, 0.0f);
247 }
248 canvas->restore();
Joe Gregorioc4859072017-01-20 14:21:27 +0000249 canvas->translate(0.0f, SCALE + 10);
herb58238462016-06-03 09:44:53 -0700250 }
251 canvas->restore();
252 canvas->translate(2 * (SCALE + 10), 0.0f);
253 }
254}