blob: 35784e34f575b9cd3766b7f9786578294097b174 [file] [log] [blame]
Dominik Röttsches1f8bee32023-04-14 13:41:30 +03001/*
2 * Copyright 2023 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"
Dominik Röttsches643fae12023-05-27 18:02:00 +030010#include "include/core/SkFont.h"
Dominik Röttsches1f8bee32023-04-14 13:41:30 +030011#include "include/core/SkRefCnt.h"
Dominik Röttsches643fae12023-05-27 18:02:00 +030012#include "include/core/SkStream.h"
Dominik Röttschesa17cc992023-06-06 09:56:11 +030013#include "include/core/SkString.h"
Dominik Röttsches1f8bee32023-04-14 13:41:30 +030014#include "include/core/SkTypeface.h"
Dominik Röttsches643fae12023-05-27 18:02:00 +030015#include "include/ports/SkTypeface_fontations.h"
Dominik Röttschesc1c01af2023-05-08 21:09:07 +030016#include "tools/Resources.h"
Dominik Röttsches1f8bee32023-04-14 13:41:30 +030017
18namespace skiagm {
19
20namespace {
21const SkScalar kTextSizes[] = {12, 18, 30, 120};
Dominik Röttschesa17cc992023-06-06 09:56:11 +030022const char kReportFontName[] = "fonts/Roboto-Regular.ttf";
Dominik Röttsches016af932023-05-15 17:24:28 +030023const SkScalar kDumpFontSize = 20.0f;
24
25// TODO(drott): Test these dumps is in a unit test instead of dumping them to GM surface.
Dominik Röttschesa17cc992023-06-06 09:56:11 +030026void dumpToCanvas(SkCanvas* canvas, SkString text, sk_sp<SkTypeface> reportTypeface) {
Dominik Röttsches016af932023-05-15 17:24:28 +030027 canvas->drawSimpleText(text.c_str(),
28 text.size() - 1,
Dominik Röttschesa17cc992023-06-06 09:56:11 +030029 SkTextEncoding::kUTF8,
30 0,
31 0,
32 SkFont(reportTypeface, kDumpFontSize),
Dominik Röttsches016af932023-05-15 17:24:28 +030033 SkPaint());
34}
35
Dominik Röttschesa17cc992023-06-06 09:56:11 +030036void dumpLocalizedStrings(SkCanvas* canvas,
37 sk_sp<SkTypeface> typeface,
38 sk_sp<SkTypeface> reportTypeface) {
Dominik Röttsches016af932023-05-15 17:24:28 +030039 auto family_names = typeface->createFamilyNameIterator();
40 SkTypeface::LocalizedString famName;
41 SkString localizedName;
42 while (family_names->next(&famName)) {
43 localizedName.printf(
44 "Name: %s Language: %s\n", famName.fString.c_str(), famName.fLanguage.c_str());
Dominik Röttschesa17cc992023-06-06 09:56:11 +030045 dumpToCanvas(canvas, localizedName, reportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +030046 canvas->translate(0, kDumpFontSize * 1.2);
47 }
48 family_names->unref();
49}
50
Dominik Röttschesa17cc992023-06-06 09:56:11 +030051void dumpGlyphCount(SkCanvas* canvas,
52 sk_sp<SkTypeface> typeface,
53 sk_sp<SkTypeface> reportTypeface) {
Dominik Röttsches016af932023-05-15 17:24:28 +030054 SkString glyphCount;
55 glyphCount.printf("Num glyphs: %d\n", typeface->countGlyphs());
Dominik Röttschesa17cc992023-06-06 09:56:11 +030056 dumpToCanvas(canvas, glyphCount, reportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +030057}
58
Dominik Röttschesa17cc992023-06-06 09:56:11 +030059void dumpFamilyAndPostscriptName(SkCanvas* canvas,
60 sk_sp<SkTypeface> typeface,
61 sk_sp<SkTypeface> reportTypeface) {
Dominik Röttsches016af932023-05-15 17:24:28 +030062 SkString name;
63 typeface->getFamilyName(&name);
64 SkString nameDump;
65 nameDump.printf("Family name: %s\n", name.c_str());
Dominik Röttschesa17cc992023-06-06 09:56:11 +030066 dumpToCanvas(canvas, nameDump, reportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +030067
68 if (typeface->getPostScriptName(&name)) {
69 canvas->translate(0, kDumpFontSize * 1.2);
70 nameDump.printf("PS Name: %s\n", name.c_str());
Dominik Röttschesa17cc992023-06-06 09:56:11 +030071 dumpToCanvas(canvas, nameDump, reportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +030072 } else {
73 canvas->translate(0, kDumpFontSize * 1.2);
74 nameDump.printf("No Postscript name.");
Dominik Röttschesa17cc992023-06-06 09:56:11 +030075 dumpToCanvas(canvas, nameDump, reportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +030076 }
77}
78
Dominik Röttsches1f8bee32023-04-14 13:41:30 +030079} // namespace
80
81class FontationsTypefaceGM : public GM {
82public:
Dominik Röttsches773765c2023-06-07 12:00:15 +030083 enum class TypefaceConstruction {
84 kMakeWithFontArguments,
85 kCloneWithFontArguments,
86 };
Dominik Röttschesa17cc992023-06-06 09:56:11 +030087 FontationsTypefaceGM(const char* testName,
88 const char* testFontFilename,
89 std::initializer_list<SkFontArguments::VariationPosition::Coordinate>
Dominik Röttsches773765c2023-06-07 12:00:15 +030090 specifiedVariations,
91 TypefaceConstruction construction = TypefaceConstruction::kMakeWithFontArguments)
92 : fTestName(testName)
93 , fTestFontFilename(testFontFilename)
94 , fConstruction(construction) {
Dominik Röttschesa17cc992023-06-06 09:56:11 +030095 this->setBGColor(SK_ColorWHITE);
96 fVariationPosition.coordinateCount = specifiedVariations.size();
97 fCoordinates = std::make_unique<SkFontArguments::VariationPosition::Coordinate[]>(
98 specifiedVariations.size());
99 for (size_t i = 0; i < specifiedVariations.size(); ++i) {
100 fCoordinates[i] = std::data(specifiedVariations)[i];
101 }
102
103 fVariationPosition.coordinates = fCoordinates.get();
104 }
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300105
106protected:
Dominik Röttschesc1c01af2023-05-08 21:09:07 +0300107 void onOnceBeforeDraw() override {
Dominik Röttsches773765c2023-06-07 12:00:15 +0300108 if (fConstruction == TypefaceConstruction::kMakeWithFontArguments) {
109 fTestTypeface = SkTypeface_Make_Fontations(
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300110 GetResourceAsStream(fTestFontFilename),
111 SkFontArguments().setVariationDesignPosition(fVariationPosition));
Dominik Röttsches773765c2023-06-07 12:00:15 +0300112 } else {
113 fTestTypeface = SkTypeface_Make_Fontations(GetResourceAsStream(fTestFontFilename),
114 SkFontArguments())
115 ->makeClone(SkFontArguments().setVariationDesignPosition(
116 fVariationPosition));
117 }
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300118 fReportTypeface =
119 SkTypeface_Make_Fontations(GetResourceAsStream(kReportFontName), SkFontArguments());
Dominik Röttschesc1c01af2023-05-08 21:09:07 +0300120 }
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300121
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000122 SkString getName() const override {
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300123 return SkStringPrintf("typeface_fontations_%s", fTestName.c_str());
124 }
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300125
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000126 SkISize getISize() override { return SkISize::Make(400, 200); }
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300127
128 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
129 SkPaint paint;
130 paint.setColor(SK_ColorBLACK);
131
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300132 if (!fTestTypeface) {
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300133 *errorMsg = "Unable to initialize typeface.";
134 return DrawResult::kSkip;
135 }
136
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300137 SkFont font(fTestTypeface);
138 const char32_t testText[] = U"abc";
139 size_t testTextBytesize = std::char_traits<char32_t>::length(testText) * sizeof(char32_t);
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300140 SkScalar x = 100;
141 SkScalar y = 150;
142
143 for (SkScalar textSize : kTextSizes) {
144 font.setSize(textSize);
145 y += font.getSpacing();
146
147 /* Draw origin marker as a green dot. */
148 paint.setColor(SK_ColorGREEN);
149 canvas->drawRect(SkRect::MakeXYWH(x, y, 2, 2), paint);
150 paint.setColor(SK_ColorBLACK);
151
Dominik Röttschesc1c01af2023-05-08 21:09:07 +0300152 canvas->drawSimpleText(
153 testText, testTextBytesize, SkTextEncoding::kUTF32, x, y, font, paint);
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300154 }
155
Dominik Röttsches016af932023-05-15 17:24:28 +0300156 canvas->translate(100, 470);
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300157 dumpGlyphCount(canvas, fTestTypeface, fReportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +0300158 canvas->translate(0, kDumpFontSize * 1.2);
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300159 dumpLocalizedStrings(canvas, fTestTypeface, fReportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +0300160 canvas->translate(0, kDumpFontSize * 1.2);
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300161 dumpFamilyAndPostscriptName(canvas, fTestTypeface, fReportTypeface);
Dominik Röttsches016af932023-05-15 17:24:28 +0300162
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300163 return DrawResult::kOk;
164 }
165
166private:
167 using INHERITED = GM;
168
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300169 const SkString fTestName;
170 const char* fTestFontFilename;
171 sk_sp<SkTypeface> fTestTypeface;
172 sk_sp<SkTypeface> fReportTypeface;
173 SkFontArguments::VariationPosition fVariationPosition;
174 std::unique_ptr<SkFontArguments::VariationPosition::Coordinate[]> fCoordinates;
Dominik Röttsches773765c2023-06-07 12:00:15 +0300175 TypefaceConstruction fConstruction;
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300176};
177
Dominik Röttschesa17cc992023-06-06 09:56:11 +0300178namespace {
179SkFourByteTag constexpr operator"" _t(const char* tagName, size_t size) {
180 SkASSERT(size == 4);
181 return SkSetFourByteTag(tagName[0], tagName[1], tagName[2], tagName[3]);
182}
183} // namespace
184DEF_GM(return new FontationsTypefaceGM("roboto", "fonts/Roboto-Regular.ttf", {});)
Dominik Röttsches773765c2023-06-07 12:00:15 +0300185DEF_GM(return new FontationsTypefaceGM(
186 "distortable_light",
187 "fonts/Distortable.ttf",
188 {{"wght"_t, 0.5f}}))
189DEF_GM(return new FontationsTypefaceGM(
190 "distortable_bold",
191 "fonts/Distortable.ttf",
192 {{"wght"_t, 2.0f}},
193 FontationsTypefaceGM::TypefaceConstruction::kCloneWithFontArguments);)
Dominik Röttsches1f8bee32023-04-14 13:41:30 +0300194
195} // namespace skiagm