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