blob: 62badb74d331dafb11a969769029b740ff28bd45 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagnerd1701ba2019-04-30 13:44:26 -04009#include "include/core/SkBitmap.h"
10#include "include/core/SkCanvas.h"
11#include "include/core/SkColor.h"
12#include "include/core/SkColorSpace.h"
13#include "include/core/SkFont.h"
14#include "include/core/SkFontStyle.h"
15#include "include/core/SkFontTypes.h"
16#include "include/core/SkImage.h"
17#include "include/core/SkImageInfo.h"
18#include "include/core/SkPaint.h"
19#include "include/core/SkPixmap.h"
20#include "include/core/SkRect.h"
21#include "include/core/SkRefCnt.h"
22#include "include/core/SkScalar.h"
23#include "include/core/SkTypeface.h"
24#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "tools/Resources.h"
26#include "tools/ToolUtils.h"
halcanarydb0dcc72015-03-20 12:31:52 -070027
Ben Wagnerd1701ba2019-04-30 13:44:26 -040028#include <string.h>
29#include <initializer_list>
halcanarydb0dcc72015-03-20 12:31:52 -070030
31static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
Matt Sarett68b8e3d2017-04-28 11:15:22 -040032 const SkBitmap* srcPtr = &src;
33 SkBitmap tmp(src);
34 if (kRGB_565_SkColorType == colorType) {
35 tmp.setAlphaType(kOpaque_SkAlphaType);
36 srcPtr = &tmp;
37 }
38
halcanarydb0dcc72015-03-20 12:31:52 -070039 SkBitmap copy;
Mike Kleinea3f0142019-03-20 11:12:10 -050040 ToolUtils::copy_to(&copy, colorType, *srcPtr);
halcanarydb0dcc72015-03-20 12:31:52 -070041 copy.setImmutable();
42 return copy;
43}
44
45#define SCALE 128
46
47// Make either A8 or gray8 bitmap.
48static SkBitmap make_bitmap(SkColorType ct) {
49 SkBitmap bm;
50 switch (ct) {
51 case kAlpha_8_SkColorType:
52 bm.allocPixels(SkImageInfo::MakeA8(SCALE, SCALE));
53 break;
54 case kGray_8_SkColorType:
55 bm.allocPixels(
56 SkImageInfo::Make(SCALE, SCALE, ct, kOpaque_SkAlphaType));
57 break;
58 default:
59 SkASSERT(false);
60 return bm;
61 }
halcanarydb0dcc72015-03-20 12:31:52 -070062 uint8_t spectrum[256];
63 for (int y = 0; y < 256; ++y) {
64 spectrum[y] = y;
65 }
66 for (int y = 0; y < 128; ++y) {
67 // Shift over one byte each scanline.
68 memcpy(bm.getAddr8(0, y), &spectrum[y], 128);
69 }
70 bm.setImmutable();
71 return bm;
72}
73
Mike Reed94cca602018-12-02 16:04:27 -050074static void draw_center_letter(char c, const SkFont& font, SkColor color,
75 SkScalar x, SkScalar y, SkCanvas* canvas) {
halcanarydb0dcc72015-03-20 12:31:52 -070076 SkRect bounds;
Ben Wagner51e15a62019-05-07 15:38:46 -040077 font.measureText(&c, 1, SkTextEncoding::kUTF8, &bounds);
78 canvas->drawSimpleText(&c, 1, SkTextEncoding::kUTF8,
Mike Reed94cca602018-12-02 16:04:27 -050079 x - bounds.centerX(), y - bounds.centerY(),
Hal Canary0a7b3932019-05-02 11:31:28 -040080 font, SkPaint(SkColor4f::FromColor(color)));
halcanarydb0dcc72015-03-20 12:31:52 -070081}
82
83static void color_wheel_native(SkCanvas* canvas) {
84 SkAutoCanvasRestore autoCanvasRestore(canvas, true);
85 canvas->translate(0.5f * SCALE, 0.5f * SCALE);
Hal Canary0a7b3932019-05-02 11:31:28 -040086 canvas->drawCircle(0.0f, 0.0f, SCALE * 0.5f, SkPaint(SkColors::kWhite));
halcanarydb0dcc72015-03-20 12:31:52 -070087
88 const double sqrt_3_over_2 = 0.8660254037844387;
89 const SkScalar Z = 0.0f;
90 const SkScalar D = 0.3f * SkIntToScalar(SCALE);
91 const SkScalar X = SkDoubleToScalar(D * sqrt_3_over_2);
92 const SkScalar Y = D * SK_ScalarHalf;
Mike Reed94cca602018-12-02 16:04:27 -050093
94 SkFont font;
95 font.setEdging(SkFont::Edging::kAlias);
Mike Kleinea3f0142019-03-20 11:12:10 -050096 font.setTypeface(ToolUtils::create_portable_typeface(nullptr, SkFontStyle::Bold()));
Mike Reed94cca602018-12-02 16:04:27 -050097 font.setSize(0.28125f * SCALE);
98 draw_center_letter('K', font, SK_ColorBLACK, Z, Z, canvas);
99 draw_center_letter('R', font, SK_ColorRED, Z, D, canvas);
100 draw_center_letter('G', font, SK_ColorGREEN, -X, -Y, canvas);
101 draw_center_letter('B', font, SK_ColorBLUE, X, -Y, canvas);
102 draw_center_letter('C', font, SK_ColorCYAN, Z, -D, canvas);
103 draw_center_letter('M', font, SK_ColorMAGENTA, X, Y, canvas);
104 draw_center_letter('Y', font, SK_ColorYELLOW, -X, Y, canvas);
halcanarydb0dcc72015-03-20 12:31:52 -0700105}
106
107template <typename T>
108int find(T* array, int N, T item) {
109 for (int i = 0; i < N; ++i) {
110 if (array[i] == item) {
111 return i;
112 }
113 }
114 return -1;
115}
116
halcanarydb0dcc72015-03-20 12:31:52 -0700117static void draw(SkCanvas* canvas,
118 const SkPaint& p,
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500119 const SkFont& font,
halcanarydb0dcc72015-03-20 12:31:52 -0700120 const SkBitmap& src,
121 SkColorType colorType,
122 const char text[]) {
123 SkASSERT(src.colorType() == colorType);
Mike Reed6dbeac52021-01-13 13:14:23 -0500124 canvas->drawImage(src.asImage(), 0.0f, 0.0f);
Ben Wagner51e15a62019-05-07 15:38:46 -0400125 canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 0.0f, 12.0f, font, p);
halcanarydb0dcc72015-03-20 12:31:52 -0700126}
127
Brian Osman567f4fd2018-09-12 11:48:38 -0400128DEF_SIMPLE_GM(all_bitmap_configs, canvas, SCALE, 6 * SCALE) {
halcanarydb0dcc72015-03-20 12:31:52 -0700129 SkAutoCanvasRestore autoCanvasRestore(canvas, true);
Hal Canary0a7b3932019-05-02 11:31:28 -0400130 SkPaint p(SkColors::kBlack);
halcanarydb0dcc72015-03-20 12:31:52 -0700131 p.setAntiAlias(true);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500132
Mike Kleinea3f0142019-03-20 11:12:10 -0500133 SkFont font(ToolUtils::create_portable_typeface());
halcanarydb0dcc72015-03-20 12:31:52 -0700134
Mike Kleinea3f0142019-03-20 11:12:10 -0500135 ToolUtils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
halcanarydb0dcc72015-03-20 12:31:52 -0700136
137 SkBitmap bitmap;
Hal Canaryc465d132017-12-08 10:21:31 -0500138 if (GetResourceAsBitmap("images/color_wheel.png", &bitmap)) {
halcanarydb0dcc72015-03-20 12:31:52 -0700139 bitmap.setImmutable();
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500140 draw(canvas, p, font, bitmap, kN32_SkColorType, "Native 32");
halcanarydb0dcc72015-03-20 12:31:52 -0700141
142 canvas->translate(0.0f, SkIntToScalar(SCALE));
143 SkBitmap copy565 = copy_bitmap(bitmap, kRGB_565_SkColorType);
144 p.setColor(SK_ColorRED);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500145 draw(canvas, p, font, copy565, kRGB_565_SkColorType, "RGB 565");
halcanarydb0dcc72015-03-20 12:31:52 -0700146 p.setColor(SK_ColorBLACK);
147
148 canvas->translate(0.0f, SkIntToScalar(SCALE));
149 SkBitmap copy4444 = copy_bitmap(bitmap, kARGB_4444_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500150 draw(canvas, p, font, copy4444, kARGB_4444_SkColorType, "ARGB 4444");
Brian Osman567f4fd2018-09-12 11:48:38 -0400151
152 canvas->translate(0.0f, SkIntToScalar(SCALE));
153 SkBitmap copyF16 = copy_bitmap(bitmap, kRGBA_F16_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500154 draw(canvas, p, font, copyF16, kRGBA_F16_SkColorType, "RGBA F16");
Brian Osman567f4fd2018-09-12 11:48:38 -0400155
halcanarydb0dcc72015-03-20 12:31:52 -0700156 } else {
Brian Osman567f4fd2018-09-12 11:48:38 -0400157 canvas->translate(0.0f, SkIntToScalar(3 * SCALE));
halcanarydb0dcc72015-03-20 12:31:52 -0700158 }
159
160 canvas->translate(0.0f, SkIntToScalar(SCALE));
halcanarydb0dcc72015-03-20 12:31:52 -0700161 SkBitmap bitmapA8 = make_bitmap(kAlpha_8_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500162 draw(canvas, p, font, bitmapA8, kAlpha_8_SkColorType, "Alpha 8");
halcanarydb0dcc72015-03-20 12:31:52 -0700163
164 p.setColor(SK_ColorRED);
165 canvas->translate(0.0f, SkIntToScalar(SCALE));
166 SkBitmap bitmapG8 = make_bitmap(kGray_8_SkColorType);
Mike Reedd5cdc2c2019-01-04 15:57:33 -0500167 draw(canvas, p, font, bitmapG8, kGray_8_SkColorType, "Gray 8");
halcanarydb0dcc72015-03-20 12:31:52 -0700168}
halcanaryaa4ba902015-11-06 07:27:23 -0800169
reed9ce9d672016-03-17 10:51:11 -0700170sk_sp<SkImage> make_not_native32_color_wheel() {
halcanaryaa4ba902015-11-06 07:27:23 -0800171 SkBitmap n32bitmap, notN32bitmap;
172 n32bitmap.allocN32Pixels(SCALE, SCALE);
173 n32bitmap.eraseColor(SK_ColorTRANSPARENT);
174 SkCanvas n32canvas(n32bitmap);
175 color_wheel_native(&n32canvas);
halcanaryaa4ba902015-11-06 07:27:23 -0800176 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
177 const SkColorType ct = kRGBA_8888_SkColorType;
178 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
179 const SkColorType ct = kBGRA_8888_SkColorType;
180 #endif
181 static_assert(ct != kN32_SkColorType, "BRGA!=RGBA");
Mike Kleinea3f0142019-03-20 11:12:10 -0500182 SkAssertResult(ToolUtils::copy_to(&notN32bitmap, ct, n32bitmap));
halcanaryaa4ba902015-11-06 07:27:23 -0800183 SkASSERT(notN32bitmap.colorType() == ct);
Mike Reedac9f0c92020-12-23 10:11:33 -0500184 return notN32bitmap.asImage();
halcanaryaa4ba902015-11-06 07:27:23 -0800185}
186
187DEF_SIMPLE_GM(not_native32_bitmap_config, canvas, SCALE, SCALE) {
reed9ce9d672016-03-17 10:51:11 -0700188 sk_sp<SkImage> notN32image(make_not_native32_color_wheel());
halcanaryaa4ba902015-11-06 07:27:23 -0800189 SkASSERT(notN32image);
Mike Kleinea3f0142019-03-20 11:12:10 -0500190 ToolUtils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
reed9ce9d672016-03-17 10:51:11 -0700191 canvas->drawImage(notN32image.get(), 0.0f, 0.0f);
halcanaryaa4ba902015-11-06 07:27:23 -0800192}
herb58238462016-06-03 09:44:53 -0700193
194static uint32_t make_pixel(int x, int y, SkAlphaType alphaType) {
195 SkASSERT(x >= 0 && x < SCALE);
196 SkASSERT(y >= 0 && y < SCALE);
197
198 SkScalar R = SCALE / 2.0f;
199
200 uint32_t alpha = 0x00;
201
202 if ((x - R) * (x - R) + (y - R) * (y - R) < R * R) {
203 alpha = 0xFF;
204 }
205
206 uint32_t component;
207 switch (alphaType) {
208 case kPremul_SkAlphaType:
209 component = alpha;
210 break;
211 case kUnpremul_SkAlphaType:
212 component = 0xFF;
213 break;
214 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400215 SK_ABORT("Should not get here - invalid alpha type");
herb58238462016-06-03 09:44:53 -0700216 }
217 return alpha << 24 | component;
218}
219
220static void make_color_test_bitmap_variant(
221 SkColorType colorType,
222 SkAlphaType alphaType,
brianosman52ede1d2016-06-20 08:25:02 -0700223 sk_sp<SkColorSpace> colorSpace,
herb58238462016-06-03 09:44:53 -0700224 SkBitmap* bm)
225{
226 SkASSERT(colorType == kRGBA_8888_SkColorType || colorType == kBGRA_8888_SkColorType);
227 SkASSERT(alphaType == kPremul_SkAlphaType || alphaType == kUnpremul_SkAlphaType);
228 bm->allocPixels(
brianosman52ede1d2016-06-20 08:25:02 -0700229 SkImageInfo::Make(SCALE, SCALE, colorType, alphaType, colorSpace));
Hal Canary99578d22017-12-14 21:13:47 -0500230 const SkPixmap& pm = bm->pixmap();
Hal Canarya0883652017-12-14 15:33:23 -0500231 for (int y = 0; y < pm.height(); y++) {
232 for (int x = 0; x < pm.width(); x++) {
herb58238462016-06-03 09:44:53 -0700233 *pm.writable_addr32(x, y) = make_pixel(x, y, alphaType);
234 }
235 }
236}
237
Joe Gregorioc4859072017-01-20 14:21:27 +0000238DEF_SIMPLE_GM(all_variants_8888, canvas, 4 * SCALE + 30, 2 * SCALE + 10) {
Mike Kleinea3f0142019-03-20 11:12:10 -0500239 ToolUtils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
herb58238462016-06-03 09:44:53 -0700240
brianosman52ede1d2016-06-20 08:25:02 -0700241 sk_sp<SkColorSpace> colorSpaces[] {
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500242 SkColorSpace::MakeSRGB(),
brianosman52ede1d2016-06-20 08:25:02 -0700243 nullptr,
brianosman52ede1d2016-06-20 08:25:02 -0700244 };
John Stilesbd3ffa42020-07-30 20:24:57 -0400245 for (const sk_sp<SkColorSpace>& colorSpace : colorSpaces) {
herb58238462016-06-03 09:44:53 -0700246 canvas->save();
247 for (auto alphaType : {kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
248 canvas->save();
249 for (auto colorType : {kRGBA_8888_SkColorType, kBGRA_8888_SkColorType}) {
250 SkBitmap bm;
brianosman52ede1d2016-06-20 08:25:02 -0700251 make_color_test_bitmap_variant(colorType, alphaType, colorSpace, &bm);
Mike Reedfa582c82021-01-23 22:07:05 -0500252 canvas->drawImage(bm.asImage(), 0.0f, 0.0f);
herb58238462016-06-03 09:44:53 -0700253 canvas->translate(SCALE + 10, 0.0f);
254 }
255 canvas->restore();
Joe Gregorioc4859072017-01-20 14:21:27 +0000256 canvas->translate(0.0f, SCALE + 10);
herb58238462016-06-03 09:44:53 -0700257 }
258 canvas->restore();
259 canvas->translate(2 * (SCALE + 10), 0.0f);
260 }
261}