blob: e0a463c45b03969b372f82d450b349e7b59963f0 [file] [log] [blame]
Dominik Röttsches691a7942021-02-11 21:08:44 +02001/*
Dominik Röttsches7368c6d2021-11-01 17:54:47 +02002 * Copyright 2021 Google Inc.
Dominik Röttsches691a7942021-02-11 21:08:44 +02003 *
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"
Dominik Röttsches0443e022024-01-10 19:49:19 +020013#include "include/core/SkFontMgr.h"
Dominik Röttschesf27608b2022-07-08 17:35:18 +030014#include "include/core/SkGraphics.h"
Dominik Röttsches691a7942021-02-11 21:08:44 +020015#include "include/core/SkPaint.h"
16#include "include/core/SkRefCnt.h"
17#include "include/core/SkScalar.h"
18#include "include/core/SkSize.h"
Dominik Röttsches0443e022024-01-10 19:49:19 +020019#include "include/core/SkStream.h"
Dominik Röttsches691a7942021-02-11 21:08:44 +020020#include "include/core/SkString.h"
21#include "include/core/SkTypeface.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öttsches691a7942021-02-11 21:08:44 +020025
Dominik Röttsches0443e022024-01-10 19:49:19 +020026#include "include/ports/SkTypeface_fontations.h"
27// #include "include/ports/SkFontMgr_empty.h"
28
Dominik Röttsches691a7942021-02-11 21:08:44 +020029#include <string.h>
30#include <initializer_list>
31
32namespace skiagm {
33
Dominik Röttschesf27608b2022-07-08 17:35:18 +030034namespace {
Dominik Röttsches0443e022024-01-10 19:49:19 +020035enum TypefaceBackend { UseDefault, UseFontations };
36
37// TODO(b/318667611): Move the explicit instantation to font manager for Fontations.
38#if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
39constexpr auto kBackend = TypefaceBackend::UseFontations;
40#else
41constexpr auto kBackend = TypefaceBackend::UseDefault;
42#endif
43
44template <TypefaceBackend variant> sk_sp<SkTypeface> MakeTypefaceFromResource(const char* resource);
45
46#if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
47template <> sk_sp<SkTypeface> MakeTypefaceFromResource<UseFontations>(const char* resource) {
48 std::unique_ptr<SkStreamAsset> resourceStream(GetResourceAsStream(resource, false));
49 return SkTypeface_Make_Fontations(std::move(resourceStream), SkFontArguments());
50}
51#else
52template <> sk_sp<SkTypeface> MakeTypefaceFromResource<UseDefault>(const char* resource) {
53 return ToolUtils::CreateTypefaceFromResource(resource, 0);
54}
55#endif
56
57} // namespace
58
59namespace {
Dominik Röttsches09627742022-07-28 18:26:02 +030060const SkScalar kTextSizes[] = {12, 18, 30, 120};
Dominik Röttschesebdd78b2022-08-11 18:44:40 +030061const char kTestFontName[] = "fonts/test_glyphs-glyf_colr_1.ttf";
62const char kTestFontNameVariable[] = "fonts/test_glyphs-glyf_colr_1_variable.ttf";
Dominik Röttsches09627742022-07-28 18:26:02 +030063const SkScalar xWidth = 1200;
64const SkScalar xTranslate = 200;
Dominik Röttsches0443e022024-01-10 19:49:19 +020065} // namespace
Dominik Röttschesf27608b2022-07-08 17:35:18 +030066
Dominik Röttsches691a7942021-02-11 21:08:44 +020067class ColrV1GM : public GM {
68public:
Dominik Röttsches09627742022-07-28 18:26:02 +030069 ColrV1GM(const char* testName,
70 SkSpan<const uint32_t> codepoints,
Dominik Röttschesebdd78b2022-08-11 18:44:40 +030071 SkScalar skewX,
72 SkScalar rotateDeg,
73 std::initializer_list<SkFontArguments::VariationPosition::Coordinate>
74 specifiedVariations)
Dominik Röttsches0443e022024-01-10 19:49:19 +020075 : fTestName(testName), fCodepoints(codepoints), fSkewX(skewX), fRotateDeg(rotateDeg) {
Dominik Röttschesebdd78b2022-08-11 18:44:40 +030076 fVariationPosition.coordinateCount = specifiedVariations.size();
77 fCoordinates = std::make_unique<SkFontArguments::VariationPosition::Coordinate[]>(
78 specifiedVariations.size());
79 for (size_t i = 0; i < specifiedVariations.size(); ++i) {
80 fCoordinates[i] = std::data(specifiedVariations)[i];
81 }
82
83 fVariationPosition.coordinates = fCoordinates.get();
84 }
Dominik Röttsches691a7942021-02-11 21:08:44 +020085
Dominik Röttsches09627742022-07-28 18:26:02 +030086protected:
Dominik Röttsches691a7942021-02-11 21:08:44 +020087 void onOnceBeforeDraw() override {
Dominik Röttschesebdd78b2022-08-11 18:44:40 +030088 if (fVariationPosition.coordinateCount) {
Dominik Röttsches0443e022024-01-10 19:49:19 +020089 fTypeface = MakeTypefaceFromResource<kBackend>(kTestFontNameVariable);
Dominik Röttschesebdd78b2022-08-11 18:44:40 +030090 } else {
Dominik Röttsches0443e022024-01-10 19:49:19 +020091 fTypeface = MakeTypefaceFromResource<kBackend>(kTestFontName);
Dominik Röttschesebdd78b2022-08-11 18:44:40 +030092 }
93 fVariationSliders = ToolUtils::VariationSliders(fTypeface.get(), fVariationPosition);
Dominik Röttsches691a7942021-02-11 21:08:44 +020094 }
95
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000096 SkString getName() const override {
Dominik Röttsches09627742022-07-28 18:26:02 +030097 SkASSERT(!fTestName.isEmpty());
98 SkString gm_name = SkStringPrintf("colrv1_%s", fTestName.c_str());
99
Dominik Röttsches2da029b2021-05-11 15:59:43 +0300100 if (fSkewX) {
Dominik Röttsches09627742022-07-28 18:26:02 +0300101 gm_name.append(SkStringPrintf("_skew_%.2f", fSkewX));
Dominik Röttsches691a7942021-02-11 21:08:44 +0200102 }
Dominik Röttsches2da029b2021-05-11 15:59:43 +0300103
104 if (fRotateDeg) {
Dominik Röttsches09627742022-07-28 18:26:02 +0300105 gm_name.append(SkStringPrintf("_rotate_%.2f", fRotateDeg));
Dominik Röttsches2da029b2021-05-11 15:59:43 +0300106 }
Dominik Röttsches09627742022-07-28 18:26:02 +0300107
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300108 for (int i = 0; i < fVariationPosition.coordinateCount; ++i) {
109 SkString tagName = ToolUtils::VariationSliders::tagToString(
110 fVariationPosition.coordinates[i].axis);
111 gm_name.append(SkStringPrintf(
112 "_%s_%.2f", tagName.c_str(), fVariationPosition.coordinates[i].value));
113 }
114
Dominik Röttsches2da029b2021-05-11 15:59:43 +0300115 return gm_name;
Dominik Röttsches691a7942021-02-11 21:08:44 +0200116 }
117
Dominik Röttschesf27608b2022-07-08 17:35:18 +0300118 bool onGetControls(SkMetaData* controls) override {
119 return fVariationSliders.writeControls(controls);
120 }
121
122 void onSetControls(const SkMetaData& controls) override {
123 return fVariationSliders.readControls(controls);
124 }
125
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000126 SkISize getISize() override {
Dominik Röttsches18b0e152022-08-15 12:01:10 +0300127 // Sweep tests get a slightly wider canvas so that glyphs from one group fit in one row.
128 if (fTestName.equals("sweep_varsweep")) {
129 return SkISize::Make(xWidth + 500, xWidth);
130 }
Dominik Röttsches09627742022-07-28 18:26:02 +0300131 return SkISize::Make(xWidth, xWidth);
132 }
133
134 sk_sp<SkTypeface> makeVariedTypeface() {
135 if (!fTypeface) {
136 return nullptr;
137 }
138 SkSpan<const SkFontArguments::VariationPosition::Coordinate> coords =
139 fVariationSliders.getCoordinates();
140 SkFontArguments::VariationPosition varPos = {coords.data(),
141 static_cast<int>(coords.size())};
142 SkFontArguments args;
143 args.setVariationDesignPosition(varPos);
144 return fTypeface->makeClone(args);
145 }
Dominik Röttsches691a7942021-02-11 21:08:44 +0200146
147 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
148 canvas->drawColor(SK_ColorWHITE);
149 SkPaint paint;
150
Dominik Röttsches09627742022-07-28 18:26:02 +0300151 canvas->translate(xTranslate, 20);
Dominik Röttsches691a7942021-02-11 21:08:44 +0200152
Dominik Röttsches09627742022-07-28 18:26:02 +0300153 if (!fTypeface) {
Dominik Röttsches691a7942021-02-11 21:08:44 +0200154 *errorMsg = "Did not recognize COLR v1 font format.";
155 return DrawResult::kSkip;
156 }
157
158 canvas->rotate(fRotateDeg);
159 canvas->skew(fSkewX, 0);
160
Dominik Röttsches09627742022-07-28 18:26:02 +0300161 SkFont font(makeVariedTypeface());
Dominik Röttsches691a7942021-02-11 21:08:44 +0200162
163 SkFontMetrics metrics;
164 SkScalar y = 0;
Dominik Röttsches612c7332021-11-09 16:13:19 +0200165 std::vector<SkColor> paint_colors = {
166 SK_ColorBLACK, SK_ColorGREEN, SK_ColorRED, SK_ColorBLUE};
167 auto paint_color_iterator = paint_colors.begin();
Dominik Röttsches09627742022-07-28 18:26:02 +0300168 for (SkScalar textSize : kTextSizes) {
Dominik Röttsches691a7942021-02-11 21:08:44 +0200169 font.setSize(textSize);
170 font.getMetrics(&metrics);
Dominik Röttsches09627742022-07-28 18:26:02 +0300171 SkScalar y_shift = -(metrics.fAscent + metrics.fDescent + metrics.fLeading) * 1.2;
172 y += y_shift;
Dominik Röttsches612c7332021-11-09 16:13:19 +0200173 paint.setColor(*paint_color_iterator);
Dominik Röttsches09627742022-07-28 18:26:02 +0300174 int x = 0;
175 // Perform simple line breaking to fit more glyphs into the GM canvas.
176 for (size_t i = 0; i < fCodepoints.size(); ++i) {
177 canvas->drawSimpleText(&fCodepoints[i],
178 sizeof(uint32_t),
179 SkTextEncoding::kUTF32,
180 x,
181 y,
182 font,
183 paint);
184 SkScalar glyphAdvance = font.measureText(
185 &fCodepoints[i], sizeof(uint32_t), SkTextEncoding::kUTF32, nullptr);
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000186 if (x + glyphAdvance < getISize().width() - xTranslate) {
Dominik Röttsches09627742022-07-28 18:26:02 +0300187 x += glyphAdvance + glyphAdvance * 0.05f;
188 } else {
189 y += y_shift;
190 x = 0;
191 }
192 }
Dominik Röttsches612c7332021-11-09 16:13:19 +0200193 paint_color_iterator++;
Dominik Röttsches691a7942021-02-11 21:08:44 +0200194 }
195 return DrawResult::kOk;
196 }
197
198private:
199 using INHERITED = GM;
Dominik Röttschesf27608b2022-07-08 17:35:18 +0300200
Dominik Röttsches09627742022-07-28 18:26:02 +0300201 SkString fTestName;
202 sk_sp<SkTypeface> fTypeface;
203 SkSpan<const uint32_t> fCodepoints;
Dominik Röttsches691a7942021-02-11 21:08:44 +0200204 SkScalar fSkewX;
205 SkScalar fRotateDeg;
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300206 std::unique_ptr<SkFontArguments::VariationPosition::Coordinate[]> fCoordinates;
207 SkFontArguments::VariationPosition fVariationPosition;
Dominik Röttschesf27608b2022-07-08 17:35:18 +0300208 ToolUtils::VariationSliders fVariationSliders;
Dominik Röttsches691a7942021-02-11 21:08:44 +0200209};
210
Dominik Röttsches09627742022-07-28 18:26:02 +0300211// Generated using test glyphs generator script from https://github.com/googlefonts/color-fonts:
212// $ python3 config/test_glyphs-glyf_colr_1.py -vvv --generate-descriptions fonts/
213// Regenerate descriptions and paste the generated arrays here when updating the test font.
214namespace ColrV1TestDefinitions {
215const uint32_t gradient_stops_repeat[] = {0xf0100, 0xf0101, 0xf0102, 0xf0103};
Dominik Röttsches18b0e152022-08-15 12:01:10 +0300216const uint32_t sweep_varsweep[] = {
217 0xf0200, 0xf0201, 0xf0202, 0xf0203, 0xf0204, 0xf0205, 0xf0206, 0xf0207, 0xf0208,
218 0xf0209, 0xf020a, 0xf020b, 0xf020c, 0xf020d, 0xf020e, 0xf020f, 0xf0210, 0xf0211,
219 0xf0212, 0xf0213, 0xf0214, 0xf0215, 0xf0216, 0xf0217, 0xf0218, 0xf0219, 0xf021a,
220 0xf021b, 0xf021c, 0xf021d, 0xf021e, 0xf021f, 0xf0220, 0xf0221, 0xf0222, 0xf0223,
221 0xf0224, 0xf0225, 0xf0226, 0xf0227, 0xf0228, 0xf0229, 0xf022a, 0xf022b, 0xf022c,
222 0xf022d, 0xf022e, 0xf022f, 0xf0230, 0xf0231, 0xf0232, 0xf0233, 0xf0234, 0xf0235,
223 0xf0236, 0xf0237, 0xf0238, 0xf0239, 0xf023a, 0xf023b, 0xf023c, 0xf023d, 0xf023e,
224 0xf023f, 0xf0240, 0xf0241, 0xf0242, 0xf0243, 0xf0244, 0xf0245, 0xf0246, 0xf0247};
Dominik Röttsches09627742022-07-28 18:26:02 +0300225const uint32_t paint_scale[] = {0xf0300, 0xf0301, 0xf0302, 0xf0303, 0xf0304, 0xf0305};
Dominik Röttsches3ed97a82022-08-16 18:59:21 +0300226const uint32_t extend_mode[] = {
227 0xf0500, 0xf0501, 0xf0502, 0xf0503, 0xf0504, 0xf0505, 0xf0506, 0xf0507, 0xf0508};
Dominik Röttsches09627742022-07-28 18:26:02 +0300228const uint32_t paint_rotate[] = {0xf0600, 0xf0601, 0xf0602, 0xf0603};
229const uint32_t paint_skew[] = {0xf0700, 0xf0701, 0xf0702, 0xf0703, 0xf0704, 0xf0705};
230const uint32_t paint_transform[] = {0xf0800, 0xf0801, 0xf0802, 0xf0803};
231const uint32_t paint_translate[] = {0xf0900, 0xf0901, 0xf0902, 0xf0903, 0xf0904, 0xf0905, 0xf0906};
232const uint32_t composite_mode[] = {0xf0a00, 0xf0a01, 0xf0a02, 0xf0a03, 0xf0a04, 0xf0a05, 0xf0a06,
233 0xf0a07, 0xf0a08, 0xf0a09, 0xf0a0a, 0xf0a0b, 0xf0a0c, 0xf0a0d,
234 0xf0a0e, 0xf0a0f, 0xf0a10, 0xf0a11, 0xf0a12, 0xf0a13, 0xf0a14,
235 0xf0a15, 0xf0a16, 0xf0a17, 0xf0a18, 0xf0a19, 0xf0a1a, 0xf0a1b};
236const uint32_t foreground_color[] = {
237 0xf0b00, 0xf0b01, 0xf0b02, 0xf0b03, 0xf0b04, 0xf0b05, 0xf0b06, 0xf0b07};
238const uint32_t clipbox[] = {0xf0c00, 0xf0c01, 0xf0c02, 0xf0c03, 0xf0c04};
239const uint32_t gradient_p2_skewed[] = {0xf0d00};
240const uint32_t variable_alpha[] = {0xf1000};
Dominik Röttschesad8cd0e2023-12-21 18:36:49 +0200241const uint32_t paintcolrglyph_cycle[] = { 0xf1100, 0xf1101, 0xf1200 };
Dominik Röttschescf84bab2023-12-15 19:10:47 +0200242const uint32_t sweep_coincident[] = { 0xf1300, 0xf1301, 0xf1302, 0xf1303, 0xf1304, 0xf1305,
243 0xf1306, 0xf1307, 0xf1308, 0xf1309, 0xf130a, 0xf130b,
244 0xf130c, 0xf130d, 0xf130e, 0xf130f, 0xf1310, 0xf1311,
245 0xf1312, 0xf1313, 0xf1314, 0xf1315, 0xf1316, 0xf1317};
Dominik Röttsches90ce0512024-01-18 17:41:52 +0200246const uint32_t paint_glyph_nested[] = { 0xf1400, 0xf1401, 0xf1402, 0xf1403,
247 0xf1404, 0xf1405, 0xf1406, 0xf1407,
248 0xf1408, 0xf1409, 0xf140a, 0xf140b,
249 0xf140c, 0xf140d, 0xf140e, 0xf140f };
Dominik Röttsches09627742022-07-28 18:26:02 +0300250}; // namespace ColrV1TestDefinitions
251
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300252namespace {
253std::unique_ptr<ColrV1GM> F(
254 const char* name,
255 SkSpan<const uint32_t> codepoints,
256 SkScalar skewX,
257 SkScalar rotateDeg,
258 std::initializer_list<SkFontArguments::VariationPosition::Coordinate> variations)
259{
260 return std::make_unique<ColrV1GM>(name, codepoints, skewX, rotateDeg, variations);
261}
Dominik Röttsches09627742022-07-28 18:26:02 +0300262
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300263SkFourByteTag constexpr operator "" _t(const char* tagName, size_t size) {
264 SkASSERT(size == 4);
265 return SkSetFourByteTag(tagName[0], tagName[1], tagName[2], tagName[3]);
266}
267}
268#define C(TEST_CATEGORY) #TEST_CATEGORY, ColrV1TestDefinitions::TEST_CATEGORY
269DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {}))
Dominik Röttschesa57f08a2022-08-12 14:09:02 +0300270DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {{"CLIO"_t, 200.f}}))
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300271DEF_GM(return F(C(composite_mode), 0.0f, 0.0f, {}))
272DEF_GM(return F(C(composite_mode), -0.5f, 0.0f, {}))
273DEF_GM(return F(C(composite_mode), -0.5f, 20.0f, {}))
274DEF_GM(return F(C(composite_mode), 0.0f, 20.0f, {}))
275DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {}))
Dominik Röttschesbd506e32022-08-24 15:03:15 +0300276DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL1"_t, -0.25f}, {"COL3"_t, 0.25f}}))
277DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL1"_t, 0.5f}, {"COL3"_t, -0.5f}}))
Dominik Röttschesebf9b2d2022-08-19 19:43:45 +0300278DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL3"_t, 0.5f}}))
279DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL3"_t, 1.f}}))
Dominik Röttsches85b2c7d2022-10-03 17:31:27 +0300280// Radial gradient tests where radii become negative
281DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL1"_t, -1.5f}}))
282// Both radii negative and equal, nothing should render.
283DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"GRR0"_t, -200.f}, {"GRR1"_t, -300.f}}))
284// Small cones opening to the right.
285DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"GRX0"_t, -1000.f}, {"GRX1"_t, -1000.f}, {"GRR0"_t, -1000.f}, {"GRR1"_t, -900.f}}))
286// Small cones opening to the left.
287DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"GRX0"_t, 1000.f}, {"GRX1"_t, -1000.f}, {"GRR0"_t, -1000.f}, {"GRR1"_t, 200.f}}))
288// Pad cone should appear green.
289DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"GRR0"_t, -50.f}, {"COL3"_t, -2.f}, {"COL2"_t, -2.f}, {"COL1"_t, -0.9f}}))
290// Pad cone should appear red.
291DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"GRR0"_t, -50.f}, {"COL3"_t, -2.f}, {"COL2"_t, -2.f}, {"COL1"_t, -1.1f}}))
Dominik Röttsches3edd61c2022-10-07 17:31:05 +0300292// Hard boundary for pad mode, should appear on the right inside the glyph for linear and radial.
293DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL3"_t, 1.f}, {"COL2"_t, 1.5f}, {"COL1"_t, 2.f}}))
Dominik Röttsches85b2c7d2022-10-03 17:31:27 +0300294// Extend mode with rotation or skew below.
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300295DEF_GM(return F(C(extend_mode), -0.5f, 0.0f, {}))
296DEF_GM(return F(C(extend_mode), -0.5f, 20.0f, {}))
297DEF_GM(return F(C(extend_mode), 0.0f, 20.0f, {}))
Dominik Röttschesa57f08a2022-08-12 14:09:02 +0300298DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"COL2"_t, -0.3f}}))
299DEF_GM(return F(C(extend_mode), 0.0f, 0.0f, {{"GRR0"_t, 430.f}, {"GRR1"_t, 40.f}}))
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300300DEF_GM(return F(C(foreground_color), 0.0f, 0.0f, {}))
301DEF_GM(return F(C(gradient_p2_skewed), 0.0f, 0.0f, {}))
302DEF_GM(return F(C(gradient_stops_repeat), 0.0f, 0.0f, {}))
303DEF_GM(return F(C(gradient_stops_repeat), -0.5f, 0.0f, {}))
304DEF_GM(return F(C(gradient_stops_repeat), -0.5f, 20.0f, {}))
305DEF_GM(return F(C(gradient_stops_repeat), 0.0f, 20.0f, {}))
306DEF_GM(return F(C(paint_rotate), 0.0f, 0.0f, {}))
Dominik Röttschesa57f08a2022-08-12 14:09:02 +0300307DEF_GM(return F(C(paint_rotate), 0.0f, 0.0f, {{"ROTA"_t, 40.f}}))
308DEF_GM(return F(C(paint_rotate), 0.0f, 0.0f, {{"ROTX"_t, -250.f}, {"ROTY"_t, -250.f}}))
309DEF_GM(return F(C(paint_scale), 0.0f, 0.0f, {}))
310DEF_GM(return F(C(paint_scale), 0.0f, 0.0f, {{"SCOX"_t, 200.f}, {"SCOY"_t, 200.f}}))
311DEF_GM(return F(C(paint_scale), 0.0f, 0.0f, {{"SCSX"_t, 0.25f}, {"SCOY"_t, 0.25f}}))
312DEF_GM(return F(C(paint_scale), 0.0f, 0.0f, {{"SCSX"_t, -1.f}, {"SCOY"_t, -1.f}}))
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300313DEF_GM(return F(C(paint_skew), 0.0f, 0.0f, {}))
Dominik Röttschesa57f08a2022-08-12 14:09:02 +0300314DEF_GM(return F(C(paint_skew), 0.0f, 0.0f, {{"SKXA"_t, 20.f}}))
315DEF_GM(return F(C(paint_skew), 0.0f, 0.0f, {{"SKYA"_t, 20.f}}))
316DEF_GM(return F(C(paint_skew), 0.0f, 0.0f, {{"SKCX"_t, 200.f},{"SKCY"_t, 200.f}}))
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300317DEF_GM(return F(C(paint_transform), 0.0f, 0.0f, {}))
318DEF_GM(return F(C(paint_translate), 0.0f, 0.0f, {}))
Dominik Röttschesa57f08a2022-08-12 14:09:02 +0300319DEF_GM(return F(C(paint_translate), 0.0f, 0.0f, {{"TLDX"_t, 100.f}, {"TLDY"_t, 100.f}}))
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300320DEF_GM(return F(C(sweep_varsweep), 0.0f, 0.0f, {}))
321DEF_GM(return F(C(sweep_varsweep), -0.5f, 0.0f, {}))
322DEF_GM(return F(C(sweep_varsweep), -0.5f, 20.0f, {}))
323DEF_GM(return F(C(sweep_varsweep), 0.0f, 20.0f, {}))
Dominik Röttsches18b0e152022-08-15 12:01:10 +0300324DEF_GM(return F(C(sweep_varsweep), 0.0f, 0.0f, {{"SWPS"_t, 0.f}}))
325DEF_GM(return F(C(sweep_varsweep), 0.0f, 0.0f, {{"SWPS"_t, 90.f}}))
326DEF_GM(return F(C(sweep_varsweep), 0.0f, 0.0f, {{"SWPE"_t, -90.f}}))
327DEF_GM(return F(C(sweep_varsweep), 0.0f, 0.0f, {{"SWPE"_t, -45.f}}))
328DEF_GM(return F(C(sweep_varsweep), 0.0f, 0.0f, {{"SWPS"_t, -45.f},{"SWPE"_t, 45.f}}))
329DEF_GM(return F(C(sweep_varsweep),
330 0.0f,
331 0.0f,
332 {{"SWC1"_t, -0.25f},
333 {"SWC2"_t, 0.083333333f},
334 {"SWC3"_t, 0.083333333f},
335 {"SWC4"_t, +0.25f}}))
Dominik Röttschesebdd78b2022-08-11 18:44:40 +0300336DEF_GM(return F(C(variable_alpha), 0.0f, 0.0f, {}))
Dominik Röttschesa57f08a2022-08-12 14:09:02 +0300337DEF_GM(return F(C(variable_alpha), 0.0f, 0.0f, {{"APH1"_t, -0.7f}}))
338DEF_GM(return F(C(variable_alpha), 0.0f, 0.0f, {{"APH2"_t, -0.7f}, {"APH3"_t, -0.2f}}))
Dominik Röttschesad8cd0e2023-12-21 18:36:49 +0200339DEF_GM(return F(C(paintcolrglyph_cycle), 0.0f, 0.0f, {}))
Dominik Röttschescf84bab2023-12-15 19:10:47 +0200340DEF_GM(return F(C(sweep_coincident), 0.0f, 0.0f, {}))
Dominik Röttsches90ce0512024-01-18 17:41:52 +0200341DEF_GM(return F(C(paint_glyph_nested), 0.0f, 0.0f, {}))
Dominik Röttsches691a7942021-02-11 21:08:44 +0200342
343} // namespace skiagm