blob: d9735b2d3d404fb1323fbd1be4fb01e4c743b1f8 [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
13#include "SkMath.h"
14#include "SkColorPriv.h"
15
16static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
Matt Sarett68b8e3d2017-04-28 11:15:22 -040017 const SkBitmap* srcPtr = &src;
18 SkBitmap tmp(src);
19 if (kRGB_565_SkColorType == colorType) {
20 tmp.setAlphaType(kOpaque_SkAlphaType);
21 srcPtr = &tmp;
22 }
23
halcanarydb0dcc72015-03-20 12:31:52 -070024 SkBitmap copy;
Matt Sarett68b8e3d2017-04-28 11:15:22 -040025 sk_tool_utils::copy_to(&copy, colorType, *srcPtr);
halcanarydb0dcc72015-03-20 12:31:52 -070026 copy.setImmutable();
27 return copy;
28}
29
30#define SCALE 128
31
32// Make either A8 or gray8 bitmap.
33static SkBitmap make_bitmap(SkColorType ct) {
34 SkBitmap bm;
35 switch (ct) {
36 case kAlpha_8_SkColorType:
37 bm.allocPixels(SkImageInfo::MakeA8(SCALE, SCALE));
38 break;
39 case kGray_8_SkColorType:
40 bm.allocPixels(
41 SkImageInfo::Make(SCALE, SCALE, ct, kOpaque_SkAlphaType));
42 break;
43 default:
44 SkASSERT(false);
45 return bm;
46 }
halcanarydb0dcc72015-03-20 12:31:52 -070047 uint8_t spectrum[256];
48 for (int y = 0; y < 256; ++y) {
49 spectrum[y] = y;
50 }
51 for (int y = 0; y < 128; ++y) {
52 // Shift over one byte each scanline.
53 memcpy(bm.getAddr8(0, y), &spectrum[y], 128);
54 }
55 bm.setImmutable();
56 return bm;
57}
58
59static void draw_center_letter(char c,
60 SkPaint* p,
61 SkColor color,
62 SkScalar x,
63 SkScalar y,
64 SkCanvas* canvas) {
65 SkRect bounds;
66 p->setColor(color);
67 p->measureText(&c, 1, &bounds);
68 canvas->drawText(&c, 1, x - bounds.centerX(), y - bounds.centerY(), *p);
69}
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;
75 p.setAntiAlias(false);
76 p.setColor(SK_ColorWHITE);
77 canvas->drawCircle(0.0f, 0.0f, SCALE * 0.5f, p);
78
79 const double sqrt_3_over_2 = 0.8660254037844387;
80 const SkScalar Z = 0.0f;
81 const SkScalar D = 0.3f * SkIntToScalar(SCALE);
82 const SkScalar X = SkDoubleToScalar(D * sqrt_3_over_2);
83 const SkScalar Y = D * SK_ScalarHalf;
mbocee6a9912016-05-31 11:42:36 -070084 sk_tool_utils::set_portable_typeface(&p, nullptr, SkFontStyle::FromOldStyle(SkTypeface::kBold));
halcanarydb0dcc72015-03-20 12:31:52 -070085 p.setTextSize(0.28125f * SCALE);
86 draw_center_letter('K', &p, SK_ColorBLACK, Z, Z, canvas);
87 draw_center_letter('R', &p, SK_ColorRED, Z, D, canvas);
88 draw_center_letter('G', &p, SK_ColorGREEN, -X, -Y, canvas);
89 draw_center_letter('B', &p, SK_ColorBLUE, X, -Y, canvas);
90 draw_center_letter('C', &p, SK_ColorCYAN, Z, -D, canvas);
91 draw_center_letter('M', &p, SK_ColorMAGENTA, X, Y, canvas);
92 draw_center_letter('Y', &p, SK_ColorYELLOW, -X, Y, canvas);
93}
94
95template <typename T>
96int find(T* array, int N, T item) {
97 for (int i = 0; i < N; ++i) {
98 if (array[i] == item) {
99 return i;
100 }
101 }
102 return -1;
103}
104
halcanarydb0dcc72015-03-20 12:31:52 -0700105static void draw(SkCanvas* canvas,
106 const SkPaint& p,
107 const SkBitmap& src,
108 SkColorType colorType,
109 const char text[]) {
110 SkASSERT(src.colorType() == colorType);
111 canvas->drawBitmap(src, 0.0f, 0.0f);
Cary Clark2a475ea2017-04-28 15:35:12 -0400112 canvas->drawString(text, 0.0f, 12.0f, p);
halcanarydb0dcc72015-03-20 12:31:52 -0700113}
114
Mike Reeda920d362017-07-03 13:36:17 -0400115DEF_SIMPLE_GM(all_bitmap_configs, canvas, SCALE, 5 * SCALE) {
halcanarydb0dcc72015-03-20 12:31:52 -0700116 SkAutoCanvasRestore autoCanvasRestore(canvas, true);
117 SkPaint p;
118 p.setColor(SK_ColorBLACK);
119 p.setAntiAlias(true);
halcanary96fcdcc2015-08-27 07:41:13 -0700120 sk_tool_utils::set_portable_typeface(&p, nullptr);
halcanarydb0dcc72015-03-20 12:31:52 -0700121
122 sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
123
124 SkBitmap bitmap;
125 if (GetResourceAsBitmap("color_wheel.png", &bitmap)) {
126 bitmap.setImmutable();
127 draw(canvas, p, bitmap, kN32_SkColorType, "Native 32");
128
129 canvas->translate(0.0f, SkIntToScalar(SCALE));
130 SkBitmap copy565 = copy_bitmap(bitmap, kRGB_565_SkColorType);
131 p.setColor(SK_ColorRED);
132 draw(canvas, p, copy565, kRGB_565_SkColorType, "RGB 565");
133 p.setColor(SK_ColorBLACK);
134
135 canvas->translate(0.0f, SkIntToScalar(SCALE));
136 SkBitmap copy4444 = copy_bitmap(bitmap, kARGB_4444_SkColorType);
137 draw(canvas, p, copy4444, kARGB_4444_SkColorType, "ARGB 4444");
138 } else {
139 canvas->translate(0.0f, SkIntToScalar(2 * SCALE));
140 }
141
142 canvas->translate(0.0f, SkIntToScalar(SCALE));
halcanarydb0dcc72015-03-20 12:31:52 -0700143 SkBitmap bitmapA8 = make_bitmap(kAlpha_8_SkColorType);
144 draw(canvas, p, bitmapA8, kAlpha_8_SkColorType, "Alpha 8");
145
146 p.setColor(SK_ColorRED);
147 canvas->translate(0.0f, SkIntToScalar(SCALE));
148 SkBitmap bitmapG8 = make_bitmap(kGray_8_SkColorType);
149 draw(canvas, p, bitmapG8, kGray_8_SkColorType, "Gray 8");
150}
halcanaryaa4ba902015-11-06 07:27:23 -0800151
reed9ce9d672016-03-17 10:51:11 -0700152sk_sp<SkImage> make_not_native32_color_wheel() {
halcanaryaa4ba902015-11-06 07:27:23 -0800153 SkBitmap n32bitmap, notN32bitmap;
154 n32bitmap.allocN32Pixels(SCALE, SCALE);
155 n32bitmap.eraseColor(SK_ColorTRANSPARENT);
156 SkCanvas n32canvas(n32bitmap);
157 color_wheel_native(&n32canvas);
158 n32canvas.flush();
159 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
160 const SkColorType ct = kRGBA_8888_SkColorType;
161 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
162 const SkColorType ct = kBGRA_8888_SkColorType;
163 #endif
164 static_assert(ct != kN32_SkColorType, "BRGA!=RGBA");
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400165 SkAssertResult(sk_tool_utils::copy_to(&notN32bitmap, ct, n32bitmap));
halcanaryaa4ba902015-11-06 07:27:23 -0800166 SkASSERT(notN32bitmap.colorType() == ct);
reed9ce9d672016-03-17 10:51:11 -0700167 return SkImage::MakeFromBitmap(notN32bitmap);
halcanaryaa4ba902015-11-06 07:27:23 -0800168}
169
170DEF_SIMPLE_GM(not_native32_bitmap_config, canvas, SCALE, SCALE) {
reed9ce9d672016-03-17 10:51:11 -0700171 sk_sp<SkImage> notN32image(make_not_native32_color_wheel());
halcanaryaa4ba902015-11-06 07:27:23 -0800172 SkASSERT(notN32image);
173 sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
reed9ce9d672016-03-17 10:51:11 -0700174 canvas->drawImage(notN32image.get(), 0.0f, 0.0f);
halcanaryaa4ba902015-11-06 07:27:23 -0800175}
herb58238462016-06-03 09:44:53 -0700176
177static uint32_t make_pixel(int x, int y, SkAlphaType alphaType) {
178 SkASSERT(x >= 0 && x < SCALE);
179 SkASSERT(y >= 0 && y < SCALE);
180
181 SkScalar R = SCALE / 2.0f;
182
183 uint32_t alpha = 0x00;
184
185 if ((x - R) * (x - R) + (y - R) * (y - R) < R * R) {
186 alpha = 0xFF;
187 }
188
189 uint32_t component;
190 switch (alphaType) {
191 case kPremul_SkAlphaType:
192 component = alpha;
193 break;
194 case kUnpremul_SkAlphaType:
195 component = 0xFF;
196 break;
197 default:
198 SkFAIL("Should not get here - invalid alpha type");
199 return 0xFF000000;
200 }
201 return alpha << 24 | component;
202}
203
204static void make_color_test_bitmap_variant(
205 SkColorType colorType,
206 SkAlphaType alphaType,
brianosman52ede1d2016-06-20 08:25:02 -0700207 sk_sp<SkColorSpace> colorSpace,
herb58238462016-06-03 09:44:53 -0700208 SkBitmap* bm)
209{
210 SkASSERT(colorType == kRGBA_8888_SkColorType || colorType == kBGRA_8888_SkColorType);
211 SkASSERT(alphaType == kPremul_SkAlphaType || alphaType == kUnpremul_SkAlphaType);
212 bm->allocPixels(
brianosman52ede1d2016-06-20 08:25:02 -0700213 SkImageInfo::Make(SCALE, SCALE, colorType, alphaType, colorSpace));
herb58238462016-06-03 09:44:53 -0700214 SkPixmap pm;
215 bm->peekPixels(&pm);
216 for (int y = 0; y < bm->height(); y++) {
217 for (int x = 0; x < bm->width(); x++) {
218 *pm.writable_addr32(x, y) = make_pixel(x, y, alphaType);
219 }
220 }
221}
222
Joe Gregorioc4859072017-01-20 14:21:27 +0000223DEF_SIMPLE_GM(all_variants_8888, canvas, 4 * SCALE + 30, 2 * SCALE + 10) {
herb58238462016-06-03 09:44:53 -0700224 sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
225
brianosman52ede1d2016-06-20 08:25:02 -0700226 sk_sp<SkColorSpace> colorSpaces[] {
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500227 SkColorSpace::MakeSRGB(),
brianosman52ede1d2016-06-20 08:25:02 -0700228 nullptr,
brianosman52ede1d2016-06-20 08:25:02 -0700229 };
230 for (auto colorSpace : colorSpaces) {
herb58238462016-06-03 09:44:53 -0700231 canvas->save();
232 for (auto alphaType : {kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
233 canvas->save();
234 for (auto colorType : {kRGBA_8888_SkColorType, kBGRA_8888_SkColorType}) {
235 SkBitmap bm;
brianosman52ede1d2016-06-20 08:25:02 -0700236 make_color_test_bitmap_variant(colorType, alphaType, colorSpace, &bm);
herb58238462016-06-03 09:44:53 -0700237 canvas->drawBitmap(bm, 0.0f, 0.0f);
238 canvas->translate(SCALE + 10, 0.0f);
239 }
240 canvas->restore();
Joe Gregorioc4859072017-01-20 14:21:27 +0000241 canvas->translate(0.0f, SCALE + 10);
herb58238462016-06-03 09:44:53 -0700242 }
243 canvas->restore();
244 canvas->translate(2 * (SCALE + 10), 0.0f);
245 }
246}