Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Enumerations | Functions
create_test_font.cpp File Reference
#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkPath.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkTDArray.h"
#include "src/base/SkUTF.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkPathPriv.h"
#include "src/utils/SkOSPath.h"
#include <stdio.h>

Go to the source code of this file.

Enumerations

enum  { kMaxLineLength = 80 }
 

Functions

static FILE * font_header (const char *family)
 
static ptrdiff_t last_line_length (const SkString &str)
 
static void output_fixed (SkScalar num, int emSize, SkString *out)
 
static void output_scalar (SkScalar num, int emSize, SkString *out)
 
static int output_points (const SkPoint *pts, int emSize, int count, SkString *ptsOut)
 
static void output_path_data (const SkFont &font, int emSize, SkString *ptsOut, SkTDArray< SkPath::Verb > *verbs, SkTDArray< unsigned > *charCodes, SkTDArray< SkScalar > *widths)
 
static int offset_str_len (unsigned num)
 
static SkString strip_final (const SkString &str)
 
static void output_font (sk_sp< SkTypeface > face, const char *identifier, FILE *out)
 
static SkString identifier (const FontFamilyDesc &family, const FontDesc &font)
 
static void generate_fonts (const char *basepath, const SkSpan< const FontFamilyDesc > &families, sk_sp< const SkFontMgr > mgr)
 
static const char * slant_to_string (SkFontStyle::Slant slant)
 
static void generate_index (const SkSpan< const FontFamilyDesc > &families, const FontDesc *defaultFont)
 
int main (int, char *const [])
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
kMaxLineLength 

Definition at line 92 of file create_test_font.cpp.

92 {
93 kMaxLineLength = 80,
94};
@ kMaxLineLength

Function Documentation

◆ font_header()

static FILE * font_header ( const char *  family)
static

Definition at line 63 of file create_test_font.cpp.

63 {
64 SkString outPath(SkOSPath::Join(".", "tools"));
65 outPath = SkOSPath::Join(outPath.c_str(), "fonts");
66 outPath = SkOSPath::Join(outPath.c_str(), "test_font_");
67 SkString fam(family);
68 do {
69 int dashIndex = fam.find("-");
70 if (dashIndex < 0) {
71 break;
72 }
73 fam.data()[dashIndex] = '_';
74 } while (true);
75 outPath.append(fam);
76 outPath.append(".inc");
77 FILE* out = fopen(outPath.c_str(), "w");
78
79 static const char kHeader[] =
80 "/*\n"
81 " * Copyright 2015 Google Inc.\n"
82 " *\n"
83 " * Use of this source code is governed by a BSD-style license that can be\n"
84 " * found in the LICENSE file.\n"
85 " */\n"
86 "\n"
87 "// Auto-generated by ";
88 fprintf(out, "%s%s\n\n", kHeader, SkOSPath::Basename(__FILE__).c_str());
89 return out;
90}
static SkString Join(const char *rootPath, const char *relativePath)
Definition SkOSPath.cpp:14
static SkString Basename(const char *fullPath)
Definition SkOSPath.cpp:23

◆ generate_fonts()

static void generate_fonts ( const char *  basepath,
const SkSpan< const FontFamilyDesc > &  families,
sk_sp< const SkFontMgr mgr 
)
static

Definition at line 304 of file create_test_font.cpp.

306 {
307 SkASSERT_RELEASE(mgr);
308 FILE* out = nullptr;
309 for (const FontFamilyDesc& family : families) {
310 out = font_header(family.fGenericName);
311 for (const FontDesc& font : family.fFonts) {
312 SkString filepath(SkOSPath::Join(basepath, font.fFile));
313 SkASSERTF(sk_exists(filepath.c_str()), "The file %s does not exist.", filepath.c_str());
314 sk_sp<SkTypeface> resourceTypeface = mgr->makeFromFile(filepath.c_str(), 0);
315 SkASSERTF(resourceTypeface, "The file %s is not a font.", filepath.c_str());
316 output_font(std::move(resourceTypeface), identifier(family, font).c_str(), out);
317 }
318 fclose(out);
319 }
320}
#define SkASSERT_RELEASE(cond)
Definition SkAssert.h:100
#define SkASSERTF(cond, fmt,...)
Definition SkAssert.h:117
bool sk_exists(const char *path, SkFILE_Flags=(SkFILE_Flags) 0)
sk_sp< SkTypeface > makeFromFile(const char path[], int ttcIndex=0) const
static SkString identifier(const FontFamilyDesc &family, const FontDesc &font)
static FILE * font_header(const char *family)
static void output_font(sk_sp< SkTypeface > face, const char *identifier, FILE *out)
font
Font Metadata and Metrics.

◆ generate_index()

static void generate_index ( const SkSpan< const FontFamilyDesc > &  families,
const FontDesc *  defaultFont 
)
static

Definition at line 331 of file create_test_font.cpp.

333{
334 FILE* out = font_header("index");
335 fprintf(out, "static SkTestFontData gTestFonts[] = {\n");
336 for (const FontFamilyDesc& family : families) {
337 for (const FontDesc& font : family.fFonts) {
338 SkString identifierStr = identifier(family, font);
339 const char* identifier = identifierStr.c_str();
340 const SkFontStyle& style = font.fNamedStyle.fStyle;
341 fprintf(out,
342 " { %sPoints, %sVerbs,\n"
343 " %sCharCodes, %sCharCodesCount, %sWidths,\n"
344 " %sMetrics, \"Toy %s\", SkFontStyle(%d,%d,%s)\n"
345 " },\n",
348 identifier, family.fFamilyName,
349 style.weight(), style.width(), slant_to_string(style.slant()));
350 }
351 }
352 fprintf(out, "};\n\n");
353 fprintf(out,
354 "struct SubFont {\n"
355 " const char* fFamilyName;\n"
356 " const char* fStyleName;\n"
357 " SkFontStyle fStyle;\n"
358 " SkTestFontData& fFont;\n"
359 " const char* fFile;\n"
360 "};\n\n"
361 "const SubFont gSubFonts[] = {\n");
362 int defaultIndex = -1;
363 int testFontsIndex = 0;
364 for (const FontFamilyDesc& family : families) {
365 for (const FontDesc& font : family.fFonts) {
366 if (&font == defaultFont) {
367 defaultIndex = testFontsIndex;
368 }
369 const SkFontStyle& style = font.fNamedStyle.fStyle;
370 fprintf(out,
371 " { \"%s\", \"%s\", SkFontStyle(%d,%d,%s), gTestFonts[%d], \"%s\" },\n",
372 family.fGenericName, font.fNamedStyle.fName,
373 style.weight(), style.width(), slant_to_string(style.slant()),
374 testFontsIndex, font.fFile);
375 testFontsIndex++;
376 }
377 }
378 testFontsIndex = 0;
379 for (const FontFamilyDesc& family : families) {
380 for (const FontDesc& font : family.fFonts) {
381 fprintf(out,
382 " { \"Toy %s\", \"%s\", SkFontStyle(%d,%d,%s), gTestFonts[%d], \"%s\" },\n",
383 family.fFamilyName, font.fNamedStyle.fName,
384 font.fNamedStyle.fStyle.weight(), font.fNamedStyle.fStyle.width(),
385 slant_to_string(font.fNamedStyle.fStyle.slant()), testFontsIndex, font.fFile);
386 testFontsIndex++;
387 }
388 }
389 fprintf(out, "};\n\n");
390 SkASSERT(defaultIndex >= 0);
391 fprintf(out, "const size_t gDefaultFontIndex = %d;\n", defaultIndex);
392 fclose(out);
393}
#define SkASSERT(cond)
Definition SkAssert.h:116
Slant slant() const
Definition SkFontStyle.h:64
int width() const
Definition SkFontStyle.h:63
int weight() const
Definition SkFontStyle.h:62
const char * c_str() const
Definition SkString.h:133
static const char * slant_to_string(SkFontStyle::Slant slant)

◆ identifier()

static SkString identifier ( const FontFamilyDesc &  family,
const FontDesc &  font 
)
static

Definition at line 298 of file create_test_font.cpp.

298 {
299 SkString id(family.fIdentifierName);
300 id.append(font.fNamedStyle.fIdentifierName);
301 return id;
302}
const uintptr_t id

◆ last_line_length()

static ptrdiff_t last_line_length ( const SkString str)
static

Definition at line 96 of file create_test_font.cpp.

96 {
97 const char* first = str.c_str();
98 const char* last = first + str.size();
99 const char* ptr = last;
100 while (ptr > first && *--ptr != '\n')
101 ;
102 return last - ptr - 1;
103}
size_t size() const
Definition SkString.h:131

◆ main()

int main ( int  ,
char * const  [] 
)

Definition at line 395 of file create_test_font.cpp.

395 {
396 constexpr NamedFontStyle normal = {"Normal", "Normal", SkFontStyle::Normal() };
397 constexpr NamedFontStyle bold = {"Bold", "Bold", SkFontStyle::Bold() };
398 constexpr NamedFontStyle italic = {"Italic", "Italic", SkFontStyle::Italic() };
399 constexpr NamedFontStyle bolditalic = {"Bold Italic", "BoldItalic", SkFontStyle::BoldItalic()};
400
401 static constexpr FontDesc kMonoFonts[] = {
402 {normal, "LiberationMono-Regular.ttf"},
403 {bold, "LiberationMono-Bold.ttf"},
404 {italic, "LiberationMono-Italic.ttf"},
405 {bolditalic, "LiberationMono-BoldItalic.ttf"},
406 };
407
408 static constexpr FontDesc kSansFonts[] = {
409 {normal, "LiberationSans-Regular.ttf"},
410 {bold, "LiberationSans-Bold.ttf"},
411 {italic, "LiberationSans-Italic.ttf"},
412 {bolditalic, "LiberationSans-BoldItalic.ttf"},
413 };
414
415 static constexpr FontDesc kSerifFonts[] = {
416 {normal, "LiberationSerif-Regular.ttf"},
417 {bold, "LiberationSerif-Bold.ttf"},
418 {italic, "LiberationSerif-Italic.ttf"},
419 {bolditalic, "LiberationSerif-BoldItalic.ttf"},
420 };
421
422 static constexpr FontFamilyDesc kFamiliesData[] = {
423 {"monospace", "Liberation Mono", "LiberationMono", kMonoFonts},
424 {"sans-serif", "Liberation Sans", "LiberationSans", kSansFonts},
425 {"serif", "Liberation Serif", "LiberationSerif", kSerifFonts},
426 };
427
428 static constexpr SkSpan<const FontFamilyDesc> kFamilies(kFamiliesData);
429
431#if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
432 mgr = SkFontMgr_New_FontConfig(nullptr);
433#elif defined(SK_FONTMGR_CORETEXT_AVAILABLE)
434 mgr = SkFontMgr_New_CoreText(nullptr);
435#elif defined(SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE)
437#else
438 SkDEBUGFAIL("Unsupported FontMgr");
439#endif
440
441#if defined(SK_BUILD_FOR_UNIX)
442#define SK_FONT_FOLDER "/usr/share/fonts/truetype/liberation/"
443#elif defined(SK_BUILD_FOR_MAC)
444#define SK_FONT_FOLDER "/Library/Fonts/"
445#else
446#error "Unsupported OS"
447#endif
448
449 generate_fonts(SK_FONT_FOLDER, kFamilies, mgr);
450 generate_index(kFamilies, &kFamilies[1].fFonts[0]);
451 return 0;
452}
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
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)
static constexpr SkFontStyle Italic()
Definition SkFontStyle.h:72
static constexpr SkFontStyle BoldItalic()
Definition SkFontStyle.h:75
static constexpr SkFontStyle Bold()
Definition SkFontStyle.h:69
static constexpr SkFontStyle Normal()
Definition SkFontStyle.h:66
static void generate_index(const SkSpan< const FontFamilyDesc > &families, const FontDesc *defaultFont)
static void generate_fonts(const char *basepath, const SkSpan< const FontFamilyDesc > &families, sk_sp< const SkFontMgr > mgr)

◆ offset_str_len()

static int offset_str_len ( unsigned  num)
static

Definition at line 179 of file create_test_font.cpp.

179 {
180 if (num == (unsigned) -1) {
181 return 10;
182 }
183 unsigned result = 1;
184 unsigned ref = 10;
185 while (ref <= num) {
186 ++result;
187 ref *= 10;
188 }
189 return result;
190}
GAsyncResult * result

◆ output_fixed()

static void output_fixed ( SkScalar  num,
int  emSize,
SkString out 
)
static

Definition at line 105 of file create_test_font.cpp.

105 {
106 uint32_t hex = (uint32_t)(num * 65536 / emSize);
107 out->appendf("0x%08x,", hex);
108 *out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
109}
Type::kYUV Type::kRGBA() int(0.7 *637)
static ptrdiff_t last_line_length(const SkString &str)

◆ output_font()

static void output_font ( sk_sp< SkTypeface face,
const char *  identifier,
FILE *  out 
)
static

Definition at line 206 of file create_test_font.cpp.

206 {
207 const int emSize = face->getUnitsPerEm() * 2;
208 SkFont font;
210 font.setSize(emSize);
211 font.setTypeface(std::move(face));
212
214 SkTDArray<unsigned> charCodes;
216 SkString ptsOut;
217 output_path_data(font, emSize, &ptsOut, &verbs, &charCodes, &widths);
218 fprintf(out, "const SkScalar %sPoints[] = {\n", identifier);
219 ptsOut = strip_final(ptsOut);
220 fprintf(out, "%s", ptsOut.c_str());
221 fprintf(out, "\n};\n\n");
222 fprintf(out, "const unsigned char %sVerbs[] = {\n", identifier);
223 int verbCount = verbs.size();
224 int outChCount = 0;
225 for (int index = 0; index < verbCount;) {
226 SkPath::Verb verb = verbs[index];
228 SkASSERT(SkTFitsIn<uint8_t>(verb));
229 fprintf(out, "%u", verb);
230 if (++index < verbCount) {
231 outChCount += 3;
232 fprintf(out, "%c", ',');
233 if (outChCount >= kMaxLineLength) {
234 outChCount = 0;
235 fprintf(out, "%c", '\n');
236 } else {
237 fprintf(out, "%c", ' ');
238 }
239 }
240 }
241 fprintf(out, "\n};\n\n");
242
243 // all fonts are now 0x00, 0x20 - 0xFE
244 // don't need to generate or output character codes?
245 fprintf(out, "const SkUnichar %sCharCodes[] = {\n", identifier);
246 int offsetCount = charCodes.size();
247 for (int index = 0; index < offsetCount;) {
248 unsigned offset = charCodes[index];
249 fprintf(out, "%u", offset);
250 if (++index < offsetCount) {
251 outChCount += offset_str_len(offset) + 2;
252 fprintf(out, "%c", ',');
253 if (outChCount >= kMaxLineLength) {
254 outChCount = 0;
255 fprintf(out, "%c", '\n');
256 } else {
257 fprintf(out, "%c", ' ');
258 }
259 }
260 }
261 fprintf(out, "\n};\n\n");
262
263 SkString widthsStr;
264 fprintf(out, "const SkFixed %sWidths[] = {\n", identifier);
265 for (int index = 0; index < offsetCount; ++index) {
266 output_fixed(widths[index], emSize, &widthsStr);
267 }
268 widthsStr = strip_final(widthsStr);
269 fprintf(out, "%s\n};\n\n", widthsStr.c_str());
270
271 fprintf(out, "const size_t %sCharCodesCount = std::size(%sCharCodes);\n\n",
273
274 SkFontMetrics metrics;
275 font.getMetrics(&metrics);
276 fprintf(out, "const SkFontMetrics %sMetrics = {\n", identifier);
277 SkString metricsStr;
278 metricsStr.printf("0x%08x, ", metrics.fFlags);
279 output_scalar(metrics.fTop, emSize, &metricsStr);
280 output_scalar(metrics.fAscent, emSize, &metricsStr);
281 output_scalar(metrics.fDescent, emSize, &metricsStr);
282 output_scalar(metrics.fBottom, emSize, &metricsStr);
283 output_scalar(metrics.fLeading, emSize, &metricsStr);
284 output_scalar(metrics.fAvgCharWidth, emSize, &metricsStr);
285 output_scalar(metrics.fMaxCharWidth, emSize, &metricsStr);
286 output_scalar(metrics.fXMin, emSize, &metricsStr);
287 output_scalar(metrics.fXMax, emSize, &metricsStr);
288 output_scalar(metrics.fXHeight, emSize, &metricsStr);
289 output_scalar(metrics.fCapHeight, emSize, &metricsStr);
290 output_scalar(metrics.fUnderlineThickness, emSize, &metricsStr);
291 output_scalar(metrics.fUnderlinePosition, emSize, &metricsStr);
292 output_scalar(metrics.fStrikeoutThickness, emSize, &metricsStr);
293 output_scalar(metrics.fStrikeoutPosition, emSize, &metricsStr);
294 metricsStr = strip_final(metricsStr);
295 fprintf(out, "%s\n};\n\n", metricsStr.c_str());
296}
const SkScalar widths[]
@ kAntiAlias
may have transparent pixels on glyph edges
@ kMove_Verb
Definition SkPath.h:1458
@ kDone_Verb
Definition SkPath.h:1464
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:534
int size() const
Definition SkTDArray.h:138
int getUnitsPerEm() const
static void output_scalar(SkScalar num, int emSize, SkString *out)
static int offset_str_len(unsigned num)
static void output_path_data(const SkFont &font, int emSize, SkString *ptsOut, SkTDArray< SkPath::Verb > *verbs, SkTDArray< unsigned > *charCodes, SkTDArray< SkScalar > *widths)
static SkString strip_final(const SkString &str)
static void output_fixed(SkScalar num, int emSize, SkString *out)
Point offset
SkScalar fTop
greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable ...
SkScalar fLeading
distance to add between lines, typically positive or zero
SkScalar fAvgCharWidth
average character width, zero if unknown
SkScalar fStrikeoutPosition
distance from baseline to bottom of stroke, typically negative
SkScalar fStrikeoutThickness
strikeout thickness
SkScalar fMaxCharWidth
maximum character width, zero if unknown
SkScalar fBottom
greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable ...
uint32_t fFlags
FontMetricsFlags indicating which metrics are valid.
SkScalar fAscent
distance to reserve above baseline, typically negative
SkScalar fXHeight
height of lower-case 'x', zero if unknown, typically negative
SkScalar fUnderlineThickness
underline thickness
SkScalar fDescent
distance to reserve below baseline, typically positive
SkScalar fCapHeight
height of an upper-case letter, zero if unknown, typically negative
SkScalar fXMin
greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with vari...
SkScalar fUnderlinePosition
distance from baseline to top of stroke, typically positive
SkScalar fXMax
greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with var...

◆ output_path_data()

static void output_path_data ( const SkFont font,
int  emSize,
SkString ptsOut,
SkTDArray< SkPath::Verb > *  verbs,
SkTDArray< unsigned > *  charCodes,
SkTDArray< SkScalar > *  widths 
)
static

Definition at line 138 of file create_test_font.cpp.

140 {
141 for (SkUnichar index = 0x00; index < 0x7f; ++index) {
142 uint16_t glyphID = font.unicharToGlyph(index);
143 SkPath path;
144 font.getPath(glyphID, &path);
145 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
146 *verbs->append() = (SkPath::Verb)verb;
147 switch (verb) {
149 output_points(&pts[0], emSize, 1, ptsOut);
150 break;
152 output_points(&pts[1], emSize, 1, ptsOut);
153 break;
155 output_points(&pts[1], emSize, 2, ptsOut);
156 break;
158 output_points(&pts[1], emSize, 3, ptsOut);
159 break;
161 break;
162 default:
163 SkDEBUGFAIL("bad verb");
164 SkASSERT(0);
165 }
166 }
167 *verbs->append() = SkPath::kDone_Verb;
168 *charCodes->append() = index;
170 font.getWidths(&glyphID, 1, &width);
171 // SkASSERT(floor(width) == width); // not true for Hiragino Maru Gothic Pro
172 *widths->append() = width;
173 if (0 == index) {
174 index = 0x1f; // skip the rest of the control codes
175 }
176 }
177}
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
int32_t SkUnichar
Definition SkTypes.h:175
T * append()
Definition SkTDArray.h:191
static int output_points(const SkPoint *pts, int emSize, int count, SkString *ptsOut)
float SkScalar
Definition extension.cpp:12
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
SkScalar w
int32_t width

◆ output_points()

static int output_points ( const SkPoint pts,
int  emSize,
int  count,
SkString ptsOut 
)
static

Definition at line 130 of file create_test_font.cpp.

130 {
131 for (int index = 0; index < count; ++index) {
132 output_scalar(pts[index].fX, emSize, ptsOut);
133 output_scalar(pts[index].fY, emSize, ptsOut);
134 }
135 return count;
136}
int count

◆ output_scalar()

static void output_scalar ( SkScalar  num,
int  emSize,
SkString out 
)
static

Definition at line 111 of file create_test_font.cpp.

111 {
112 num /= emSize;
113 if (num == (int) num) {
114 out->appendS32((int) num);
115 } else {
116 SkString str;
117 str.printf("%1.6g", num);
118 int width = (int) str.size();
119 const char* cStr = str.c_str();
120 while (cStr[width - 1] == '0') {
121 --width;
122 }
123 str.remove(width, str.size() - width);
124 out->appendf("%sf", str.c_str());
125 }
126 *out += ',';
127 *out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
128}
void void void void void void void remove(size_t offset, size_t length)
Definition SkString.cpp:592

◆ slant_to_string()

static const char * slant_to_string ( SkFontStyle::Slant  slant)
static

Definition at line 322 of file create_test_font.cpp.

322 {
323 switch (slant) {
324 case SkFontStyle::kUpright_Slant: return "SkFontStyle::kUpright_Slant";
325 case SkFontStyle::kItalic_Slant : return "SkFontStyle::kItalic_Slant" ;
326 case SkFontStyle::kOblique_Slant: return "SkFontStyle::kOblique_Slant";
327 default: SK_ABORT("Unknown slant");
328 }
329}
#define SK_ABORT(message,...)
Definition SkAssert.h:70

◆ strip_final()

static SkString strip_final ( const SkString str)
static

Definition at line 192 of file create_test_font.cpp.

192 {
193 SkString result(str);
194 if (result.endsWith("\n")) {
195 result.remove(result.size() - 1, 1);
196 }
197 if (result.endsWith(" ")) {
198 result.remove(result.size() - 1, 1);
199 }
200 if (result.endsWith(",")) {
201 result.remove(result.size() - 1, 1);
202 }
203 return result;
204}