2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
10 #include "SkTestScalerContext.h"
13 #include "sk_tool_utils.h"
15 namespace sk_tool_utils {
17 #include "test_font_data.cpp"
19 static void release_portable_typefaces() {
20 // We'll clean this up in our own tests, but disable for clients.
21 // Chrome seems to have funky multi-process things going on in unit tests that
22 // makes this unsafe to delete when the main process atexit()s.
23 // SkLazyPtr does the same sort of thing.
25 for (int index = 0; index < gTestFontsCount; ++index) {
26 SkTestFontData& fontData = gTestFonts[index];
27 SkSafeUnref(fontData.fFontCache);
32 SK_DECLARE_STATIC_MUTEX(gTestFontMutex);
34 SkTypeface* create_font(const char* name, SkTypeface::Style style) {
35 SkTestFontData* fontData = NULL;
38 for (int index = 0; index < gSubFontsCount; ++index) {
39 sub = &gSubFonts[index];
40 if (!strcmp(name, sub->fName) && sub->fStyle == style) {
41 fontData = &sub->fFont;
46 SkDebugf("missing %s %d\n", name, style);
47 return SkTypeface::CreateFromName(name, style);
50 sub = &gSubFonts[gDefaultFontIndex];
51 fontData = &sub->fFont;
55 SkAutoMutexAcquire ac(gTestFontMutex);
56 if (fontData->fFontCache) {
57 font = SkSafeRef(fontData->fFontCache);
59 font = SkNEW_ARGS(SkTestFont, (*fontData));
60 SkDEBUGCODE(font->fDebugName = sub->fName);
61 SkDEBUGCODE(font->fDebugStyle = sub->fStyle);
62 fontData->fFontCache = SkSafeRef(font);
63 atexit(release_portable_typefaces);
66 return SkNEW_ARGS(SkTestTypeface, (font, style));
70 SkTypeface* resource_font(const char* name, SkTypeface::Style style) {
71 const char* file = NULL;
73 for (int index = 0; index < gSubFontsCount; ++index) {
74 const SubFont& sub = gSubFonts[index];
75 if (!strcmp(name, sub.fName) && sub.fStyle == style) {
81 return SkTypeface::CreateFromName(name, style);
84 file = gSubFonts[gDefaultFontIndex].fFile;
86 SkString filepath(GetResourcePath(file));
87 if (sk_exists(filepath.c_str())) {
88 return SkTypeface::CreateFromFile(filepath.c_str());
90 return SkTypeface::CreateFromName(name, style);
96 char const * const gStyleName[] = {
103 static SkString strip_spaces(const char* str) {
105 int count = (int) strlen(str);
106 for (int index = 0; index < count; ++index) {
108 if (c != ' ' && c != '-') {
115 const char gHeader[] =
117 " * Copyright 2014 Google Inc.\n"
119 " * Use of this source code is governed by a BSD-style license that can be\n"
120 " * found in the LICENSE file.\n"
123 "// Auto-generated by ";
125 static FILE* font_header() {
126 SkString pathStr(GetResourcePath());
127 pathStr = SkOSPath::Join(pathStr.c_str(), "..");
128 pathStr = SkOSPath::Join(pathStr.c_str(), "tools");
129 pathStr = SkOSPath::Join(pathStr.c_str(), "test_font_data_chars.cpp");
130 FILE* out = fopen(pathStr.c_str(), "w");
131 fprintf(out, "%s%s\n\n", gHeader, SkOSPath::Basename(__FILE__).c_str());
135 void report_used_chars() {
136 FILE* out = font_header();
137 for (int index = 0; index < gTestFontsCount; ++index) {
138 SkTestFontData& fontData = gTestFonts[index];
139 SkTestFont* font = fontData.fFontCache;
143 SkString name(strip_spaces(font->debugFontName()));
144 fprintf(out, "const char g%s%s[] =\n", name.c_str(), gStyleName[font->fDebugStyle]);
145 SkString used(" \"");
146 for (int c = ' '; c <= '~'; ++c) {
147 int bitOffset = c - ' ';
148 if (font->fDebugBits[bitOffset >> 3] & (1 << (bitOffset & 7))) {
149 if (c == '"' || c == '\\') {
155 if (used.size() > 1) {
156 fprintf(out, "%s\"", used.c_str());
159 while (font->fDebugOverage[oIndex]) {
160 uint16_t uni = font->fDebugOverage[oIndex];
161 size_t byteCount = SkUTF16_ToUTF8(&uni, 1, NULL);
162 SkAutoSTMalloc<10, char> utf8(byteCount);
163 SkUTF16_ToUTF8(&uni, 1, utf8);
164 for (unsigned byteIndex = 0; byteIndex < byteCount; ++byteIndex) {
165 char unibyte = utf8[byteIndex];
166 fprintf(out, " \"\\x%02X\"", (unsigned char) unibyte);
168 if (++oIndex >= (int) sizeof(font->fDebugOverage)) {