Flutter Engine
The Flutter Engine
FontToolUtils.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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
9
12#include "include/core/SkFont.h"
18#include "include/core/SkPixelRef.h" // IWYU pragma: keep
23#include "src/base/SkUTF.h"
24#include "src/core/SkOSFile.h"
25#include "tools/Resources.h"
28
29#if defined(SK_BUILD_FOR_WIN) && (defined(SK_FONTMGR_GDI_AVAILABLE) || \
30 defined(SK_FONTMGR_DIRECTWRITE_AVAILABLE))
32#endif
33
34#if defined(SK_BUILD_FOR_ANDROID) && defined(SK_FONTMGR_ANDROID_AVAILABLE)
37#endif
38
39#if defined(SK_FONTMGR_CORETEXT_AVAILABLE) && (defined(SK_BUILD_FOR_IOS) || \
40 defined(SK_BUILD_FOR_MAC))
42#endif
43
44#if defined(SK_FONTMGR_FONTATIONS_AVAILABLE)
46#endif
47
48#if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
50#endif
51
52#if defined(SK_FONTMGR_FREETYPE_DIRECTORY_AVAILABLE)
54#endif
55
56#if defined(SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE)
58#endif
59
60namespace ToolUtils {
61
62static DEFINE_bool(nativeFonts,
63 true,
64 "If true, use native font manager and rendering. "
65 "If false, fonts will draw as portably as possible.");
66#if defined(SK_BUILD_FOR_WIN)
67static DEFINE_bool(gdi, false, "Use GDI instead of DirectWrite for font rendering.");
68#endif
69#if defined(SK_FONTMGR_FONTATIONS_AVAILABLE)
70static DEFINE_bool(fontations, false, "Use Fontations for native font rendering.");
71#endif
72
74 static const sk_sp<SkTypeface> planetTypeface = []() {
75 const char* filename;
76#if defined(SK_BUILD_FOR_WIN)
77 filename = "fonts/planetcolr.ttf";
78#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
79 filename = "fonts/planetsbix.ttf";
80#else
81 filename = "fonts/planetcbdt.ttf";
82#endif
84 if (typeface) {
85 return typeface;
86 }
87 return CreateTestTypeface("Planet", SkFontStyle());
88 }();
89 return planetTypeface;
90}
91
93 static const EmojiTestSample emojiSample = []() {
94 EmojiTestSample sample = {nullptr, ""};
95#if defined(SK_BUILD_FOR_WIN)
97#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
99#else
101#endif
102 if (sample.typeface) {
103 return sample;
104 }
106 }();
107 return emojiSample;
108}
109
111 EmojiTestSample sample;
112 sample.sampleText = "\U0001F600 \u2662"; // 😀 ♢
113 switch (format) {
115 sample.typeface = CreateTypefaceFromResource("fonts/cbdt.ttf");
116 break;
118 sample.typeface = CreateTypefaceFromResource("fonts/sbix.ttf");
119 break;
121 sample.typeface = CreateTypefaceFromResource("fonts/colr.ttf");
122 break;
124 sample.typeface = CreateTypefaceFromResource("fonts/SampleSVG.ttf");
125 sample.sampleText = "abcdefghij";
126 break;
128 sample.typeface = CreatePortableTypeface("Emoji", SkFontStyle());
129 }
130 return sample;
131}
132
134 switch (format) {
136 return SkString("cbdt");
138 return SkString("sbix");
140 return SkString("colrv0");
142 return SkString("test");
144 return SkString("svg");
145 }
146 return SkString();
147}
148
151 SkFont font;
152 const float upem = 200;
153
154 {
155 SkFontMetrics metrics;
156 metrics.fFlags = 0;
157 metrics.fTop = -200;
158 metrics.fAscent = -150;
159 metrics.fDescent = 50;
160 metrics.fBottom = -75;
161 metrics.fLeading = 10;
162 metrics.fAvgCharWidth = 150;
163 metrics.fMaxCharWidth = 300;
164 metrics.fXMin = -20;
165 metrics.fXMax = 290;
166 metrics.fXHeight = -100;
167 metrics.fCapHeight = 0;
168 metrics.fUnderlineThickness = 5;
169 metrics.fUnderlinePosition = 2;
170 metrics.fStrikeoutThickness = 5;
171 metrics.fStrikeoutPosition = -50;
172 builder.setMetrics(metrics, 1.0f/upem);
173 }
174 builder.setFontStyle(SkFontStyle(367, 3, SkFontStyle::kOblique_Slant));
175
176 const SkMatrix scale = SkMatrix::Scale(1.0f/upem, 1.0f/upem);
177 for (SkGlyphID index = 0; index <= 67; ++index) {
179 width = 100;
180
181 builder.setGlyph(index, width/upem, SkPath::Circle(50, -50, 75).makeTransform(scale));
182 }
183
184 return builder.detach();
185}
186
188 static sk_sp<SkFontMgr> portableFontMgr = MakePortableFontMgr();
189 SkASSERT_RELEASE(portableFontMgr);
190 sk_sp<SkTypeface> face = portableFontMgr->legacyMakeTypeface(name, style);
191 SkASSERT_RELEASE(face);
192 return face;
193}
194
196 // At last check, the default typeface is a serif font.
198 SkASSERT_RELEASE(face);
199 return face;
200}
201
203 return SkFont(DefaultPortableTypeface(), 12);
204}
205
206SkBitmap CreateStringBitmap(int w, int h, SkColor c, int x, int y, int textSize,
207 const char* str) {
209 bitmap.allocN32Pixels(w, h);
210 SkCanvas canvas(bitmap);
211
213 paint.setColor(c);
214
216
217 canvas.clear(0x00000000);
218 canvas.drawSimpleText(str,
219 strlen(str),
223 font,
224 paint);
225
226 // Tag data as sRGB (without doing any color space conversion). Color-space aware configs
227 // will process this correctly but legacy configs will render as if this returned N32.
230 result.setPixelRef(sk_ref_sp(bitmap.pixelRef()), 0, 0);
231 return result;
232}
233
234sk_sp<SkImage> CreateStringImage(int w, int h, SkColor c, int x, int y, int textSize,
235 const char* str) {
236 return CreateStringBitmap(w, h, c, x, y, textSize, str).asImage();
237}
238
239#ifndef SK_FONT_FILE_PREFIX
240# if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
241# define SK_FONT_FILE_PREFIX "/System/Library/Fonts/"
242# else
243# define SK_FONT_FILE_PREFIX "/usr/share/fonts/"
244# endif
245#endif
246
248 static sk_sp<SkFontMgr> mgr;
249 static SkOnce once;
250 once([] {
251 if (!FLAGS_nativeFonts) {
252 mgr = MakePortableFontMgr();
253 }
254#if defined(SK_BUILD_FOR_WIN) && defined(SK_FONTMGR_GDI_AVAILABLE)
255 else if (FLAGS_gdi) {
256 mgr = SkFontMgr_New_GDI();
257 }
258#endif
259#if defined(SK_FONTMGR_FONTATIONS_AVAILABLE)
260 else if (FLAGS_fontations) {
262 }
263#endif
264 else {
265#if defined(SK_BUILD_FOR_ANDROID) && defined(SK_FONTMGR_ANDROID_AVAILABLE)
266 mgr = SkFontMgr_New_Android(nullptr, std::make_unique<SkFontScanner_FreeType>());
267#elif defined(SK_BUILD_FOR_WIN) && defined(SK_FONTMGR_DIRECTWRITE_AVAILABLE)
268 mgr = SkFontMgr_New_DirectWrite();
269#elif defined(SK_FONTMGR_CORETEXT_AVAILABLE) && (defined(SK_BUILD_FOR_IOS) || \
270 defined(SK_BUILD_FOR_MAC))
271 mgr = SkFontMgr_New_CoreText(nullptr);
272#elif defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
273 mgr = SkFontMgr_New_FontConfig(nullptr);
274#elif defined(SK_FONTMGR_FREETYPE_DIRECTORY_AVAILABLE)
275 // In particular, this is used on ChromeOS, which is Linux-like but doesn't have
276 // FontConfig.
278#elif defined(SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE)
280#else
281 mgr = SkFontMgr::RefEmpty();
282#endif
283 }
284 SkASSERT_RELEASE(mgr);
285 });
286 return mgr;
287}
288
290 if (!FLAGS_nativeFonts) {
291 return false;
292 }
293#if defined(SK_BUILD_FOR_WIN)
294 if (FLAGS_gdi) {
295 return true;
296 }
297#endif
298 return false;
299}
300
301void UsePortableFontMgr() { FLAGS_nativeFonts = false; }
302
304 return CreateTestTypeface(nullptr, SkFontStyle());
305}
306
310 sk_sp<SkTypeface> face = fm->legacyMakeTypeface(name, style);
311 if (face) {
312 return face;
313 }
314 return CreatePortableTypeface(name, style);
315}
316
320 return fm->makeFromStream(GetResourceAsStream(resource), ttcIndex);
321}
322
324 return SkFont(DefaultTypeface(), 12);
325}
326
327} // namespace ToolUtils
#define SK_FONT_FILE_PREFIX
std::unique_ptr< SkStreamAsset > GetResourceAsStream(const char *resource, bool useFileStream)
Definition: Resources.cpp:31
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
uint32_t SkColor
Definition: SkColor.h:37
SK_API sk_sp< SkFontMgr > SkFontMgr_New_Fontations_Empty()
SK_API sk_sp< SkFontMgr > SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts *custom)
SK_API sk_sp< SkFontMgr > SkFontMgr_New_Custom_Directory(const char *dir)
SK_API sk_sp< SkFontMgr > SkFontMgr_New_Custom_Empty()
SK_API sk_sp< SkFontMgr > SkFontMgr_New_FontConfig(FcConfig *fc)
SK_API sk_sp< SkFontMgr > SkFontMgr_New_CoreText(CTFontCollectionRef)
@ kUTF8
uses bytes to represent UTF-8 or ASCII
static SkString resource(SkPDFResourceType type, int index)
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
#define SkIntToScalar(x)
Definition: SkScalar.h:57
uint16_t SkGlyphID
Definition: SkTypes.h:179
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
void drawSimpleText(const void *text, size_t byteLength, SkTextEncoding encoding, SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.cpp:2413
void clear(SkColor color)
Definition: SkCanvas.h:1199
static sk_sp< SkFontMgr > RefEmpty()
Definition: SkFontMgr.cpp:154
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:127
sk_sp< SkTypeface > legacyMakeTypeface(const char familyName[], SkFontStyle style) const
Definition: SkFontMgr.cpp:150
Definition: SkFont.h:35
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
Definition: SkOnce.h:22
static SkPath Circle(SkScalar center_x, SkScalar center_y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:3598
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
GAsyncResult * result
uint32_t uint32_t * format
double y
double x
sk_sp< SkTypeface > DefaultPortableTypeface()
SkFont DefaultPortableFont()
sk_sp< SkFontMgr > MakePortableFontMgr()
bool FontMgrIsGDI()
void UsePortableFontMgr()
SkString NameForFontFormat(EmojiFontFormat format)
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)
SkFont DefaultFont()
SkBitmap CreateStringBitmap(int w, int h, SkColor c, int x, int y, int textSize, const char *str)
sk_sp< SkTypeface > PlanetTypeface()
sk_sp< SkTypeface > SampleUserTypeface()
static DEFINE_bool(nativeFonts, true, "If true, use native font manager and rendering. " "If false, fonts will draw as portably as possible.")
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
EmojiTestSample EmojiSample()
sk_sp< SkTypeface > DefaultTypeface()
sk_sp< SkTypeface > CreateTestTypeface(const char *name, SkFontStyle style)
sk_sp< SkImage > CreateStringImage(int w, int h, SkColor c, int x, int y, int textSize, const char *str)
sk_sp< SkFontMgr > TestFontMgr()
Definition: bitmap.py:1
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
font
Font Metadata and Metrics.
SkScalar w
SkScalar h
int32_t width
const Scalar scale
SkScalar fTop
greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable ...
Definition: SkFontMetrics.h:53
SkScalar fLeading
distance to add between lines, typically positive or zero
Definition: SkFontMetrics.h:57
SkScalar fAvgCharWidth
average character width, zero if unknown
Definition: SkFontMetrics.h:58
SkScalar fStrikeoutPosition
distance from baseline to bottom of stroke, typically negative
Definition: SkFontMetrics.h:67
SkScalar fStrikeoutThickness
strikeout thickness
Definition: SkFontMetrics.h:66
SkScalar fMaxCharWidth
maximum character width, zero if unknown
Definition: SkFontMetrics.h:59
SkScalar fBottom
greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable ...
Definition: SkFontMetrics.h:56
uint32_t fFlags
FontMetricsFlags indicating which metrics are valid.
Definition: SkFontMetrics.h:52
SkScalar fAscent
distance to reserve above baseline, typically negative
Definition: SkFontMetrics.h:54
SkScalar fXHeight
height of lower-case 'x', zero if unknown, typically negative
Definition: SkFontMetrics.h:62
SkScalar fUnderlineThickness
underline thickness
Definition: SkFontMetrics.h:64
SkScalar fDescent
distance to reserve below baseline, typically positive
Definition: SkFontMetrics.h:55
SkScalar fCapHeight
height of an upper-case letter, zero if unknown, typically negative
Definition: SkFontMetrics.h:63
SkScalar fXMin
greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with vari...
Definition: SkFontMetrics.h:60
SkScalar fUnderlinePosition
distance from baseline to top of stroke, typically positive
Definition: SkFontMetrics.h:65
SkScalar fXMax
greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with var...
Definition: SkFontMetrics.h:61
static SkImageInfo MakeS32(int width, int height, SkAlphaType at)
sk_sp< SkTypeface > typeface
Definition: FontToolUtils.h:48