15fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark/*
25fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark * Copyright 2014 Google Inc.
35fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark *
45fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark * Use of this source code is governed by a BSD-style license that can be
55fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark * found in the LICENSE file.
65fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark */
75fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
8992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "Resources.h"
9992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "SkOSFile.h"
10992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "SkTestScalerContext.h"
11992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "SkThread.h"
12992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "SkUtils.h"
13992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "sk_tool_utils.h"
145fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
155fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclarknamespace sk_tool_utils {
165fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
17992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include "test_font_data.cpp"
18992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark
19992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkstatic void release_portable_typefaces() {
20992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    // We'll clean this up in our own tests, but disable for clients.
21992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    // Chrome seems to have funky multi-process things going on in unit tests that
22992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    // makes this unsafe to delete when the main process atexit()s.
23992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    // SkLazyPtr does the same sort of thing.
24992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#if SK_DEVELOPER
25c2a484644a49127adb55c435bd51c006f102d1a5caryclark    for (int index = 0; index < gTestFontsCount; ++index) {
26992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkTestFontData& fontData = gTestFonts[index];
27992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkSafeUnref(fontData.fFontCache);
28992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
29992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#endif
30992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark}
315fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
32992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary ClarkSK_DECLARE_STATIC_MUTEX(gTestFontMutex);
33992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark
34992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary ClarkSkTypeface* create_font(const char* name, SkTypeface::Style style) {
35992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    SkTestFontData* fontData = NULL;
36992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    const SubFont* sub;
37992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    if (name) {
38c2a484644a49127adb55c435bd51c006f102d1a5caryclark        for (int index = 0; index < gSubFontsCount; ++index) {
39992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            sub = &gSubFonts[index];
40992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            if (!strcmp(name, sub->fName) && sub->fStyle == style) {
41992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                fontData = &sub->fFont;
42992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                break;
43992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            }
44992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
45992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        if (!fontData) {
46992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            SkDebugf("missing %s %d\n", name, style);
47992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            return SkTypeface::CreateFromName(name, style);
48992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
49992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    } else {
50992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        sub = &gSubFonts[gDefaultFontIndex];
51992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        fontData = &sub->fFont;
52992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
53992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    SkTestFont* font;
54992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    {
55992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkAutoMutexAcquire ac(gTestFontMutex);
56992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        if (fontData->fFontCache) {
57992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            font = SkSafeRef(fontData->fFontCache);
58992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        } else {
59992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            font = SkNEW_ARGS(SkTestFont, (*fontData));
60992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            SkDEBUGCODE(font->fDebugName = sub->fName);
61992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            SkDEBUGCODE(font->fDebugStyle = sub->fStyle);
62992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            fontData->fFontCache = SkSafeRef(font);
63992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            atexit(release_portable_typefaces);
64992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
65992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
66992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    return SkNEW_ARGS(SkTestTypeface, (font, style));
67992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark}
685fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
695fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
70992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary ClarkSkTypeface* resource_font(const char* name, SkTypeface::Style style) {
71992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    const char* file = NULL;
72992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    if (name) {
73c2a484644a49127adb55c435bd51c006f102d1a5caryclark        for (int index = 0; index < gSubFontsCount; ++index) {
74992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            const SubFont& sub = gSubFonts[index];
75992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            if (!strcmp(name, sub.fName) && sub.fStyle == style) {
76992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                file = sub.fFile;
77992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                break;
78992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            }
79992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
80992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        if (!file) {
81992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            return SkTypeface::CreateFromName(name, style);
82992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
83992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    } else {
84992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        file = gSubFonts[gDefaultFontIndex].fFile;
85992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
86992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    SkString filepath(GetResourcePath(file));
87992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    if (sk_exists(filepath.c_str())) {
88992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        return SkTypeface::CreateFromFile(filepath.c_str());
89992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
90992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    return SkTypeface::CreateFromName(name, style);
91992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark}
925fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
93992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#ifdef SK_DEBUG
94992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#include <stdio.h>
95992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark
96992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkchar const * const gStyleName[] = {
97992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    "",
98992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    "_Bold",
99992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    "_Italic",
100992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    "_BoldItalic",
101992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark};
102992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark
103992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkstatic SkString strip_spaces(const char* str) {
104992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    SkString result;
105992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    int count = (int) strlen(str);
106992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    for (int index = 0; index < count; ++index) {
107992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        char c = str[index];
108992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        if (c != ' ' && c != '-') {
109992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            result += c;
110992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
111992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
112992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    return result;
113992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark}
1145fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
115992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkconst char gHeader[] =
116992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark"/*\n"
117992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark" * Copyright 2014 Google Inc.\n"
118992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark" *\n"
119992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark" * Use of this source code is governed by a BSD-style license that can be\n"
120992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark" * found in the LICENSE file.\n"
121992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark" */\n"
122992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark"\n"
123992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark"// Auto-generated by ";
124992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark
125992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkstatic FILE* font_header() {
126992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    SkString pathStr(GetResourcePath());
127992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    pathStr = SkOSPath::Join(pathStr.c_str(), "..");
128992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    pathStr = SkOSPath::Join(pathStr.c_str(), "tools");
129992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    pathStr = SkOSPath::Join(pathStr.c_str(), "test_font_data_chars.cpp");
130992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    FILE* out = fopen(pathStr.c_str(), "w");
131992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    fprintf(out, "%s%s\n\n", gHeader, SkOSPath::Basename(__FILE__).c_str());
132992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    return out;
133992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark}
1345fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
135992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clarkvoid report_used_chars() {
136992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    FILE* out = font_header();
137992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    for (int index = 0; index < gTestFontsCount; ++index) {
138992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkTestFontData& fontData = gTestFonts[index];
139992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkTestFont* font = fontData.fFontCache;
140992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        if (!font) {
141992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            continue;
142992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
143992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkString name(strip_spaces(font->debugFontName()));
144992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        fprintf(out, "const char g%s%s[] =\n", name.c_str(), gStyleName[font->fDebugStyle]);
145992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        SkString used("    \"");
146992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        for (int c = ' '; c <= '~'; ++c) {
147992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            int bitOffset = c - ' ';
148992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            if (font->fDebugBits[bitOffset >> 3] & (1 << (bitOffset & 7))) {
149992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                if (c == '"' || c == '\\') {
150992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                    used += '\\';
151992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                }
152992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                used += c;
153992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            }
154992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
155992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        if (used.size() > 1) {
156992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            fprintf(out, "%s\"", used.c_str());
157992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
158992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        int oIndex = 0;
159992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        while (font->fDebugOverage[oIndex]) {
160992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            uint16_t uni = font->fDebugOverage[oIndex];
161992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            size_t byteCount = SkUTF16_ToUTF8(&uni, 1, NULL);
162992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            SkAutoSTMalloc<10, char> utf8(byteCount);
163992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            SkUTF16_ToUTF8(&uni, 1, utf8);
164992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            for (unsigned byteIndex = 0; byteIndex < byteCount; ++byteIndex) {
165992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                char unibyte = utf8[byteIndex];
166992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                fprintf(out, " \"\\x%02X\"", (unsigned char) unibyte);
167992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            }
168992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            if (++oIndex >= (int) sizeof(font->fDebugOverage)) {
169992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark                break;
170992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark            }
171992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        }
172992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark       fprintf(out, ";\n");
173992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    }
174992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark    fclose(out);
1755fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark}
176992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark#endif
1775fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark
1785fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark}
179