Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / tools / sk_tool_utils_font.cpp
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
8 #include "Resources.h"
9 #include "SkOSFile.h"
10 #include "SkTestScalerContext.h"
11 #include "SkThread.h"
12 #include "SkUtils.h"
13 #include "sk_tool_utils.h"
14
15 namespace sk_tool_utils {
16
17 #include "test_font_data.cpp"
18
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.
24 #if SK_DEVELOPER
25     for (int index = 0; index < gTestFontsCount; ++index) {
26         SkTestFontData& fontData = gTestFonts[index];
27         SkSafeUnref(fontData.fFontCache);
28     }
29 #endif
30 }
31
32 SK_DECLARE_STATIC_MUTEX(gTestFontMutex);
33
34 SkTypeface* create_font(const char* name, SkTypeface::Style style) {
35     SkTestFontData* fontData = NULL;
36     const SubFont* sub;
37     if (name) {
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;
42                 break;
43             }
44         }
45         if (!fontData) {
46             SkDebugf("missing %s %d\n", name, style);
47             return SkTypeface::CreateFromName(name, style);
48         }
49     } else {
50         sub = &gSubFonts[gDefaultFontIndex];
51         fontData = &sub->fFont;
52     }
53     SkTestFont* font;
54     {
55         SkAutoMutexAcquire ac(gTestFontMutex);
56         if (fontData->fFontCache) {
57             font = SkSafeRef(fontData->fFontCache);
58         } else {
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);
64         }
65     }
66     return SkNEW_ARGS(SkTestTypeface, (font, style));
67 }
68
69
70 SkTypeface* resource_font(const char* name, SkTypeface::Style style) {
71     const char* file = NULL;
72     if (name) {
73         for (int index = 0; index < gSubFontsCount; ++index) {
74             const SubFont& sub = gSubFonts[index];
75             if (!strcmp(name, sub.fName) && sub.fStyle == style) {
76                 file = sub.fFile;
77                 break;
78             }
79         }
80         if (!file) {
81             return SkTypeface::CreateFromName(name, style);
82         }
83     } else {
84         file = gSubFonts[gDefaultFontIndex].fFile;
85     }
86     SkString filepath(GetResourcePath(file));
87     if (sk_exists(filepath.c_str())) {
88         return SkTypeface::CreateFromFile(filepath.c_str());
89     }
90     return SkTypeface::CreateFromName(name, style);
91 }
92
93 #ifdef SK_DEBUG
94 #include <stdio.h>
95
96 char const * const gStyleName[] = {
97     "",
98     "_Bold",
99     "_Italic",
100     "_BoldItalic",
101 };
102
103 static SkString strip_spaces(const char* str) {
104     SkString result;
105     int count = (int) strlen(str);
106     for (int index = 0; index < count; ++index) {
107         char c = str[index];
108         if (c != ' ' && c != '-') {
109             result += c;
110         }
111     }
112     return result;
113 }
114
115 const char gHeader[] =
116 "/*\n"
117 " * Copyright 2014 Google Inc.\n"
118 " *\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"
121 " */\n"
122 "\n"
123 "// Auto-generated by ";
124
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());
132     return out;
133 }
134
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;
140         if (!font) {
141             continue;
142         }
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 == '\\') {
150                     used += '\\';
151                 }
152                 used += c;
153             }
154         }
155         if (used.size() > 1) {
156             fprintf(out, "%s\"", used.c_str());
157         }
158         int oIndex = 0;
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);
167             }
168             if (++oIndex >= (int) sizeof(font->fDebugOverage)) {
169                 break;
170             }
171         }
172        fprintf(out, ";\n");
173     }
174     fclose(out);
175 }
176 #endif
177
178 }