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