blob: 478f9c07c226153fa2cf938881df8a7ad501f392 [file] [log] [blame]
Dominik Röttsches01be94d2022-02-17 12:37:49 +02001/*
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"
Kevin Lubickbe579dc2023-10-05 11:11:20 -040018#include "include/core/SkStream.h"
Dominik Röttsches01be94d2022-02-17 12:37:49 +020019#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"
Kevin Lubick1e971192023-11-10 16:14:44 -050024#include "tools/fonts/FontToolUtils.h"
Dominik Röttsches01be94d2022-02-17 12:37:49 +020025
Dominik Röttsches0443e022024-01-10 19:49:19 +020026#if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
27#include "include/ports/SkTypeface_fontations.h"
28#endif
29
Dominik Röttsches01be94d2022-02-17 12:37:49 +020030#include <string.h>
31
32namespace skiagm {
33
Dominik Röttsches131a8282022-08-10 18:42:54 +030034// Copied from https://github.com/googlefonts/color-fonts#colrv1-test-font glyph descriptions markdown file.
35namespace ColrV1TestDefinitions {
36const uint32_t color_circles_palette[] = {0xf0e00, 0xf0e01};
37};
38
Dominik Röttsches01be94d2022-02-17 12:37:49 +020039namespace {
Dominik Röttsches131a8282022-08-10 18:42:54 +030040const char kColrCpalTestFontPath[] = "fonts/test_glyphs-glyf_colr_1.ttf";
Dominik Röttsches01be94d2022-02-17 12:37:49 +020041
42constexpr SkFontArguments::Palette::Override kColorOverridesAll[] = {
43 // A gradient of dark to light purple for the circle palette test glyph.
Ben Wagner0ec715d2022-02-17 23:08:13 -050044 // Randomly ordered with `shuf`.
45 // Add a repeat (later overrides override earlier overrides).
46 // Add three out of bounds entries (font has 12 palette entries).
47 { 6, 0xffffff00},
48 { 2, 0xff76078f},
49 { 4, 0xffb404c4},
50 { 1, 0xff510970},
51 { 6, 0xfffa00ff},
52 { 8, 0xff888888},
Dominik Röttsches01be94d2022-02-17 12:37:49 +020053 {10, 0xff888888},
Ben Wagner0ec715d2022-02-17 23:08:13 -050054 { 9, 0xff888888},
55 { 7, 0xff888888},
56 {11, 0xff888888},
57 { 0, 0xff310b55},
58 { 3, 0xff9606aa},
59 { 5, 0xffd802e2},
60 {13, 0xff00ffff},
61 {12, 0xff00ffff},
Dominik Röttsches7e6e2572023-12-21 12:42:51 +020062 {static_cast<uint16_t>(-1), 0xff00ff00},
Ben Wagner0ec715d2022-02-17 23:08:13 -050063};
Dominik Röttsches01be94d2022-02-17 12:37:49 +020064
65constexpr SkFontArguments::Palette::Override kColorOverridesOne[] = {
66 {2, 0xff02dfe2},
67};
68
69constexpr SkFontArguments::Palette kLightPaletteOverride{2, nullptr, 0};
70constexpr SkFontArguments::Palette kDarkPaletteOverride{1, nullptr, 0};
71constexpr SkFontArguments::Palette kOnePaletteOverride{
Herb Derbyc37b3862022-06-21 09:49:17 -040072 0, kColorOverridesOne, std::size(kColorOverridesOne)};
Dominik Röttsches01be94d2022-02-17 12:37:49 +020073constexpr SkFontArguments::Palette kAllPaletteOverride{
Herb Derbyc37b3862022-06-21 09:49:17 -040074 0, kColorOverridesAll, std::size(kColorOverridesAll)};
Dominik Röttsches01be94d2022-02-17 12:37:49 +020075
Dominik Röttsches0443e022024-01-10 19:49:19 +020076
77
78enum TypefaceBackend { UseDefault, UseFontations };
79
80// TODO(b/318667611): Move the explicit instantation to font manager for Fontations.
81#if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
82constexpr auto kBackend = TypefaceBackend::UseFontations;
83#else
84constexpr auto kBackend = TypefaceBackend::UseDefault;
85#endif
86
87template <TypefaceBackend variant>
88sk_sp<SkTypeface> MakeTypefaceFromResource(const char* resource, const SkFontArguments& args);
89
90#if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
91template <>
92sk_sp<SkTypeface> MakeTypefaceFromResource<UseFontations>(const char* resource,
93 const SkFontArguments& args) {
94 std::unique_ptr<SkStreamAsset> resourceStream(GetResourceAsStream(resource, false));
95 return SkTypeface_Make_Fontations(std::move(resourceStream), args);
96}
97#else
98template <>
99sk_sp<SkTypeface> MakeTypefaceFromResource<UseDefault>(const char* resource,
100 const SkFontArguments& args) {
101 return ToolUtils::TestFontMgr()->makeFromStream(GetResourceAsStream(resource), args);
102}
103#endif
104
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200105} // namespace
106
107class FontPaletteGM : public GM {
108public:
109 FontPaletteGM(const char* test_name,
110 const SkFontArguments::Palette& paletteOverride)
111 : fName(test_name), fPalette(paletteOverride) {}
112
113protected:
114 sk_sp<SkTypeface> fTypefaceDefault;
115 sk_sp<SkTypeface> fTypefaceFromStream;
116 sk_sp<SkTypeface> fTypefaceCloned;
117
118 void onOnceBeforeDraw() override {
119 SkFontArguments paletteArguments;
120 paletteArguments.setPalette(fPalette);
121
Dominik Röttsches0443e022024-01-10 19:49:19 +0200122 fTypefaceDefault =
123 MakeTypefaceFromResource<kBackend>(kColrCpalTestFontPath, SkFontArguments());
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200124 fTypefaceCloned =
125 fTypefaceDefault ? fTypefaceDefault->makeClone(paletteArguments) : nullptr;
126
Dominik Röttsches0443e022024-01-10 19:49:19 +0200127 fTypefaceFromStream =
128 MakeTypefaceFromResource<kBackend>(kColrCpalTestFontPath, paletteArguments);
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200129 }
130
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000131 SkString getName() const override {
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200132 SkString gm_name = SkStringPrintf("font_palette_%s", fName.c_str());
133 return gm_name;
134 }
135
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000136 SkISize getISize() override { return SkISize::Make(1000, 400); }
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200137
138 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
139 canvas->drawColor(SK_ColorWHITE);
140 SkPaint paint;
141
142 canvas->translate(10, 20);
143
144 if (!fTypefaceCloned || !fTypefaceFromStream) {
145 *errorMsg = "Did not recognize COLR v1 test font format.";
146 return DrawResult::kSkip;
147 }
148
149 SkFontMetrics metrics;
150 SkScalar y = 0;
151 SkScalar textSize = 200;
152 for (auto& typeface : { fTypefaceFromStream, fTypefaceCloned} ) {
153 SkFont defaultFont(fTypefaceDefault);
154 SkFont paletteFont(typeface);
155 defaultFont.setSize(textSize);
156 paletteFont.setSize(textSize);
157
158 defaultFont.getMetrics(&metrics);
159 y += -metrics.fAscent;
160 // Set a recognizable foreground color which is not to be overriden.
161 paint.setColor(SK_ColorGRAY);
162 // Draw the default palette on the left, for COLRv0 and COLRv1.
Dominik Röttsches131a8282022-08-10 18:42:54 +0300163 canvas->drawSimpleText(
164 ColrV1TestDefinitions::color_circles_palette,
165 std::size(ColrV1TestDefinitions::color_circles_palette) * sizeof(uint32_t),
166 SkTextEncoding::kUTF32,
167 0,
168 y,
169 defaultFont,
170 paint);
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200171 // Draw the overriden palette on the right.
Dominik Röttsches131a8282022-08-10 18:42:54 +0300172 canvas->drawSimpleText(
173 ColrV1TestDefinitions::color_circles_palette,
174 std::size(ColrV1TestDefinitions::color_circles_palette) * sizeof(uint32_t),
175 SkTextEncoding::kUTF32,
176 440,
177 y,
178 paletteFont,
179 paint);
Dominik Röttsches01be94d2022-02-17 12:37:49 +0200180 y += metrics.fDescent + metrics.fLeading;
181 }
182 return DrawResult::kOk;
183 }
184
185private:
186 using INHERITED = GM;
187 SkString fName;
188 SkFontArguments::Palette fPalette;
189};
190
191DEF_GM(return new FontPaletteGM("default", SkFontArguments::Palette()));
192DEF_GM(return new FontPaletteGM("light", kLightPaletteOverride));
193DEF_GM(return new FontPaletteGM("dark", kDarkPaletteOverride));
194DEF_GM(return new FontPaletteGM("one", kOnePaletteOverride));
195DEF_GM(return new FontPaletteGM("all", kAllPaletteOverride));
196
197} // namespace skiagm