Home | History | Annotate | Download | only in tools
      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, SkFontStyle(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 }
    179