xref: /aosp_15_r20/external/skia/gm/palette.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 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/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkFont.h"
12 #include "include/core/SkFontMetrics.h"
13 #include "include/core/SkFontMgr.h"
14 #include "include/core/SkPaint.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkScalar.h"
17 #include "include/core/SkSize.h"
18 #include "include/core/SkStream.h"
19 #include "include/core/SkString.h"
20 #include "include/core/SkTypeface.h"
21 #include "include/core/SkTypes.h"
22 #include "tools/Resources.h"
23 #include "tools/ToolUtils.h"
24 #include "tools/fonts/FontToolUtils.h"
25 
26 #if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
27 #include "include/ports/SkTypeface_fontations.h"
28 #endif
29 
30 #include <string.h>
31 
32 namespace skiagm {
33 
34 // Copied from https://github.com/googlefonts/color-fonts#colrv1-test-font glyph descriptions
35 // markdown file.
36 namespace ColrV1TestDefinitions {
37 const uint32_t color_circles_palette[] = {0xf0e00, 0xf0e01};
38 };
39 
40 namespace {
41 const char kColrCpalTestFontPath[] = "fonts/test_glyphs-glyf_colr_1.ttf";
42 
43 constexpr SkFontArguments::Palette::Override kColorOverridesAll[] = {
44         // A gradient of dark to light purple for the circle palette test glyph.
45         // Randomly ordered with `shuf`.
46         // Add a repeat (later overrides override earlier overrides).
47         // Add three out of bounds entries (font has 12 palette entries).
48         // clang-format off
49         { 6, 0xffffff00},
50         { 2, 0xff76078f},
51         { 4, 0xffb404c4},
52         { 1, 0xff510970},
53         { 6, 0xfffa00ff},
54         { 8, 0xff888888},
55         {10, 0xff888888},
56         { 9, 0xff888888},
57         { 7, 0xff888888},
58         {11, 0xff888888},
59         { 0, 0xff310b55},
60         { 3, 0xff9606aa},
61         { 5, 0xffd802e2},
62         {13, 0xff00ffff},
63         {12, 0xff00ffff},
64         {static_cast<uint16_t>(-1), 0xff00ff00},
65         // clang-format on
66 };
67 
68 constexpr SkFontArguments::Palette::Override kColorOverridesOne[] = {
69         {2, 0xff02dfe2},
70 };
71 
72 constexpr SkFontArguments::Palette kLightPaletteOverride{2, nullptr, 0};
73 constexpr SkFontArguments::Palette kDarkPaletteOverride{1, nullptr, 0};
74 constexpr SkFontArguments::Palette kOnePaletteOverride{
75         0, kColorOverridesOne, std::size(kColorOverridesOne)};
76 constexpr SkFontArguments::Palette kAllPaletteOverride{
77         0, kColorOverridesAll, std::size(kColorOverridesAll)};
78 
MakeTypefaceFromResource(const char * resource,const SkFontArguments & args)79 sk_sp<SkTypeface> MakeTypefaceFromResource(const char* resource, const SkFontArguments& args) {
80     return ToolUtils::TestFontMgr()->makeFromStream(GetResourceAsStream(resource), args);
81 }
82 
83 }  // namespace
84 
85 class FontPaletteGM : public GM {
86 public:
FontPaletteGM(const char * test_name,const SkFontArguments::Palette & paletteOverride)87     FontPaletteGM(const char* test_name, const SkFontArguments::Palette& paletteOverride)
88             : fName(test_name), fPalette(paletteOverride) {}
89 
90 protected:
91     sk_sp<SkTypeface> fTypefaceDefault;
92     sk_sp<SkTypeface> fTypefaceFromStream;
93     sk_sp<SkTypeface> fTypefaceCloned;
94 
onOnceBeforeDraw()95     void onOnceBeforeDraw() override {
96         SkFontArguments paletteArguments;
97         paletteArguments.setPalette(fPalette);
98 
99         fTypefaceDefault = MakeTypefaceFromResource(kColrCpalTestFontPath, SkFontArguments());
100         fTypefaceCloned =
101                 fTypefaceDefault ? fTypefaceDefault->makeClone(paletteArguments) : nullptr;
102 
103         fTypefaceFromStream = MakeTypefaceFromResource(kColrCpalTestFontPath, paletteArguments);
104     }
105 
getName() const106     SkString getName() const override {
107         SkString gm_name = SkStringPrintf("font_palette_%s", fName.c_str());
108         return gm_name;
109     }
110 
getISize()111     SkISize getISize() override { return SkISize::Make(1000, 400); }
112 
onDraw(SkCanvas * canvas,SkString * errorMsg)113     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
114         canvas->drawColor(SK_ColorWHITE);
115         SkPaint paint;
116 
117         canvas->translate(10, 20);
118 
119         if (!fTypefaceCloned || !fTypefaceFromStream) {
120             *errorMsg = "Did not recognize COLR v1 test font format.";
121             return DrawResult::kSkip;
122         }
123 
124         SkFontMetrics metrics;
125         SkScalar y = 0;
126         SkScalar textSize = 200;
127         for (auto& typeface : {fTypefaceFromStream, fTypefaceCloned}) {
128             SkFont defaultFont(fTypefaceDefault);
129             SkFont paletteFont(typeface);
130             defaultFont.setSize(textSize);
131             paletteFont.setSize(textSize);
132 
133             defaultFont.getMetrics(&metrics);
134             y += -metrics.fAscent;
135             // Set a recognizable foreground color which is not to be overriden.
136             paint.setColor(SK_ColorGRAY);
137             // Draw the default palette on the left, for COLRv0 and COLRv1.
138             canvas->drawSimpleText(
139                     ColrV1TestDefinitions::color_circles_palette,
140                     std::size(ColrV1TestDefinitions::color_circles_palette) * sizeof(uint32_t),
141                     SkTextEncoding::kUTF32,
142                     0,
143                     y,
144                     defaultFont,
145                     paint);
146             // Draw the overriden palette on the right.
147             canvas->drawSimpleText(
148                     ColrV1TestDefinitions::color_circles_palette,
149                     std::size(ColrV1TestDefinitions::color_circles_palette) * sizeof(uint32_t),
150                     SkTextEncoding::kUTF32,
151                     440,
152                     y,
153                     paletteFont,
154                     paint);
155             y += metrics.fDescent + metrics.fLeading;
156         }
157         return DrawResult::kOk;
158     }
159 
160 private:
161     using INHERITED = GM;
162     SkString fName;
163     SkFontArguments::Palette fPalette;
164 };
165 
166 DEF_GM(return new FontPaletteGM("default", SkFontArguments::Palette()));
167 DEF_GM(return new FontPaletteGM("light", kLightPaletteOverride));
168 DEF_GM(return new FontPaletteGM("dark", kDarkPaletteOverride));
169 DEF_GM(return new FontPaletteGM("one", kOnePaletteOverride));
170 DEF_GM(return new FontPaletteGM("all", kAllPaletteOverride));
171 
172 }  // namespace skiagm
173