/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "Resources.h" #include "SkOSFile.h" #include "SkTestScalerContext.h" #include "SkThread.h" #include "SkUtils.h" #include "sk_tool_utils.h" namespace sk_tool_utils { #include "test_font_data.cpp" static void release_portable_typefaces() { // We'll clean this up in our own tests, but disable for clients. // Chrome seems to have funky multi-process things going on in unit tests that // makes this unsafe to delete when the main process atexit()s. // SkLazyPtr does the same sort of thing. #if SK_DEVELOPER for (int index = 0; index < gTestFontsCount; ++index) { SkTestFontData& fontData = gTestFonts[index]; SkSafeUnref(fontData.fFontCache); } #endif } SK_DECLARE_STATIC_MUTEX(gTestFontMutex); SkTypeface* create_font(const char* name, SkTypeface::Style style) { SkTestFontData* fontData = NULL; const SubFont* sub; if (name) { for (int index = 0; index < gSubFontsCount; ++index) { sub = &gSubFonts[index]; if (!strcmp(name, sub->fName) && sub->fStyle == style) { fontData = &sub->fFont; break; } } if (!fontData) { SkDebugf("missing %s %d\n", name, style); return SkTypeface::CreateFromName(name, style); } } else { sub = &gSubFonts[gDefaultFontIndex]; fontData = &sub->fFont; } SkTestFont* font; { SkAutoMutexAcquire ac(gTestFontMutex); if (fontData->fFontCache) { font = SkSafeRef(fontData->fFontCache); } else { font = SkNEW_ARGS(SkTestFont, (*fontData)); SkDEBUGCODE(font->fDebugName = sub->fName); SkDEBUGCODE(font->fDebugStyle = sub->fStyle); fontData->fFontCache = SkSafeRef(font); atexit(release_portable_typefaces); } } return SkNEW_ARGS(SkTestTypeface, (font, style)); } SkTypeface* resource_font(const char* name, SkTypeface::Style style) { const char* file = NULL; if (name) { for (int index = 0; index < gSubFontsCount; ++index) { const SubFont& sub = gSubFonts[index]; if (!strcmp(name, sub.fName) && sub.fStyle == style) { file = sub.fFile; break; } } if (!file) { return SkTypeface::CreateFromName(name, style); } } else { file = gSubFonts[gDefaultFontIndex].fFile; } SkString filepath(GetResourcePath(file)); if (sk_exists(filepath.c_str())) { return SkTypeface::CreateFromFile(filepath.c_str()); } return SkTypeface::CreateFromName(name, style); } #ifdef SK_DEBUG #include char const * const gStyleName[] = { "", "_Bold", "_Italic", "_BoldItalic", }; static SkString strip_spaces(const char* str) { SkString result; int count = (int) strlen(str); for (int index = 0; index < count; ++index) { char c = str[index]; if (c != ' ' && c != '-') { result += c; } } return result; } const char gHeader[] = "/*\n" " * Copyright 2014 Google Inc.\n" " *\n" " * Use of this source code is governed by a BSD-style license that can be\n" " * found in the LICENSE file.\n" " */\n" "\n" "// Auto-generated by "; static FILE* font_header() { SkString pathStr(GetResourcePath()); pathStr = SkOSPath::Join(pathStr.c_str(), ".."); pathStr = SkOSPath::Join(pathStr.c_str(), "tools"); pathStr = SkOSPath::Join(pathStr.c_str(), "test_font_data_chars.cpp"); FILE* out = fopen(pathStr.c_str(), "w"); fprintf(out, "%s%s\n\n", gHeader, SkOSPath::Basename(__FILE__).c_str()); return out; } void report_used_chars() { FILE* out = font_header(); for (int index = 0; index < gTestFontsCount; ++index) { SkTestFontData& fontData = gTestFonts[index]; SkTestFont* font = fontData.fFontCache; if (!font) { continue; } SkString name(strip_spaces(font->debugFontName())); fprintf(out, "const char g%s%s[] =\n", name.c_str(), gStyleName[font->fDebugStyle]); SkString used(" \""); for (int c = ' '; c <= '~'; ++c) { int bitOffset = c - ' '; if (font->fDebugBits[bitOffset >> 3] & (1 << (bitOffset & 7))) { if (c == '"' || c == '\\') { used += '\\'; } used += c; } } if (used.size() > 1) { fprintf(out, "%s\"", used.c_str()); } int oIndex = 0; while (font->fDebugOverage[oIndex]) { uint16_t uni = font->fDebugOverage[oIndex]; size_t byteCount = SkUTF16_ToUTF8(&uni, 1, NULL); SkAutoSTMalloc<10, char> utf8(byteCount); SkUTF16_ToUTF8(&uni, 1, utf8); for (unsigned byteIndex = 0; byteIndex < byteCount; ++byteIndex) { char unibyte = utf8[byteIndex]; fprintf(out, " \"\\x%02X\"", (unsigned char) unibyte); } if (++oIndex >= (int) sizeof(font->fDebugOverage)) { break; } } fprintf(out, ";\n"); } fclose(out); } #endif }