15ef194c31ae498166bd9c468993514c5267ea077caryclark/* 25ef194c31ae498166bd9c468993514c5267ea077caryclark * Copyright 2015 Google Inc. 35ef194c31ae498166bd9c468993514c5267ea077caryclark * 45ef194c31ae498166bd9c468993514c5267ea077caryclark * Use of this source code is governed by a BSD-style license that can be 55ef194c31ae498166bd9c468993514c5267ea077caryclark * found in the LICENSE file. 65ef194c31ae498166bd9c468993514c5267ea077caryclark */ 75ef194c31ae498166bd9c468993514c5267ea077caryclark 85ef194c31ae498166bd9c468993514c5267ea077caryclark#include "SkFontDescriptor.h" 94e97607d9a1cef66fac16f347c5ca813ec4f9515mtklein#include "SkOpts.h" 105ef194c31ae498166bd9c468993514c5267ea077caryclark#include "SkStream.h" 115ef194c31ae498166bd9c468993514c5267ea077caryclark#include "SkString.h" 125ef194c31ae498166bd9c468993514c5267ea077caryclark#include "SkTypeface.h" 135ef194c31ae498166bd9c468993514c5267ea077caryclark#include "SkUtils.h" 144f588b5b617da169914e3829389f02883ca70b7ccaryclark#include "../sfnt/SkOTUtils.h" 155ef194c31ae498166bd9c468993514c5267ea077caryclark 16cb571e11480e929a1fa18c47ffa2c0ee22f87afbbenjaminwagner#include "SkWhitelistChecksums.inc" 175ef194c31ae498166bd9c468993514c5267ea077caryclark 185ef194c31ae498166bd9c468993514c5267ea077caryclark#define WHITELIST_DEBUG 0 195ef194c31ae498166bd9c468993514c5267ea077caryclark 205ef194c31ae498166bd9c468993514c5267ea077caryclarkextern void WhitelistSerializeTypeface(const SkTypeface*, SkWStream* ); 2113b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> WhitelistDeserializeTypeface(SkStream* ); 225ef194c31ae498166bd9c468993514c5267ea077caryclarkextern bool CheckChecksums(); 235ef194c31ae498166bd9c468993514c5267ea077caryclarkextern bool GenerateChecksums(); 245ef194c31ae498166bd9c468993514c5267ea077caryclark 255ef194c31ae498166bd9c468993514c5267ea077caryclark#if WHITELIST_DEBUG 265ef194c31ae498166bd9c468993514c5267ea077caryclarkstatic bool timesNewRomanSerializedNameOnly = false; 275ef194c31ae498166bd9c468993514c5267ea077caryclark#endif 285ef194c31ae498166bd9c468993514c5267ea077caryclark 295ef194c31ae498166bd9c468993514c5267ea077caryclark#define SUBNAME_PREFIX "sk_" 305ef194c31ae498166bd9c468993514c5267ea077caryclark 31ee6a9919a362e16c1d84a870ce867d1ad7b8a141mbocstatic bool font_name_is_local(const char* fontName, SkFontStyle style) { 325ef194c31ae498166bd9c468993514c5267ea077caryclark if (!strcmp(fontName, "DejaVu Sans")) { 335ef194c31ae498166bd9c468993514c5267ea077caryclark return true; 345ef194c31ae498166bd9c468993514c5267ea077caryclark } 3513b9c95295f4c5732e34574789e721a6bc08f7b4bungeman sk_sp<SkTypeface> defaultFace(SkTypeface::MakeFromName(nullptr, style)); 3613b9c95295f4c5732e34574789e721a6bc08f7b4bungeman sk_sp<SkTypeface> foundFace(SkTypeface::MakeFromName(fontName, style)); 375ef194c31ae498166bd9c468993514c5267ea077caryclark return defaultFace != foundFace; 385ef194c31ae498166bd9c468993514c5267ea077caryclark} 395ef194c31ae498166bd9c468993514c5267ea077caryclark 405ef194c31ae498166bd9c468993514c5267ea077caryclarkstatic int whitelist_name_index(const SkTypeface* tf) { 414f588b5b617da169914e3829389f02883ca70b7ccaryclark 425ef194c31ae498166bd9c468993514c5267ea077caryclark SkString fontNameStr; 4367b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkTypeface::LocalizedStrings> nameIter( 444f588b5b617da169914e3829389f02883ca70b7ccaryclark SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*tf)); 454f588b5b617da169914e3829389f02883ca70b7ccaryclark SkTypeface::LocalizedString familyNameLocalized; 464f588b5b617da169914e3829389f02883ca70b7ccaryclark while (nameIter->next(&familyNameLocalized)) { 474f588b5b617da169914e3829389f02883ca70b7ccaryclark fontNameStr = familyNameLocalized.fString; 484f588b5b617da169914e3829389f02883ca70b7ccaryclark // check against permissible list of names 494f588b5b617da169914e3829389f02883ca70b7ccaryclark for (int i = 0; i < whitelistCount; ++i) { 504f588b5b617da169914e3829389f02883ca70b7ccaryclark if (fontNameStr.equals(whitelist[i].fFontName)) { 514f588b5b617da169914e3829389f02883ca70b7ccaryclark return i; 524f588b5b617da169914e3829389f02883ca70b7ccaryclark } 535ef194c31ae498166bd9c468993514c5267ea077caryclark } 545ef194c31ae498166bd9c468993514c5267ea077caryclark } 555ef194c31ae498166bd9c468993514c5267ea077caryclark#if WHITELIST_DEBUG 5667b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkTypeface::LocalizedStrings> debugIter( 574f588b5b617da169914e3829389f02883ca70b7ccaryclark SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*tf)); 584f588b5b617da169914e3829389f02883ca70b7ccaryclark while (debugIter->next(&familyNameLocalized)) { 594f588b5b617da169914e3829389f02883ca70b7ccaryclark SkDebugf("no match fontName=\"%s\"\n", familyNameLocalized.fString.c_str()); 605ef194c31ae498166bd9c468993514c5267ea077caryclark } 615ef194c31ae498166bd9c468993514c5267ea077caryclark#endif 625ef194c31ae498166bd9c468993514c5267ea077caryclark return -1; 635ef194c31ae498166bd9c468993514c5267ea077caryclark} 645ef194c31ae498166bd9c468993514c5267ea077caryclark 655ef194c31ae498166bd9c468993514c5267ea077caryclarkstatic uint32_t compute_checksum(const SkTypeface* tf) { 66f93d71122e4fcfcdc674a0163455990b13855f2fbungeman std::unique_ptr<SkFontData> fontData = tf->makeFontData(); 675ef194c31ae498166bd9c468993514c5267ea077caryclark if (!fontData) { 685ef194c31ae498166bd9c468993514c5267ea077caryclark return 0; 695ef194c31ae498166bd9c468993514c5267ea077caryclark } 705ef194c31ae498166bd9c468993514c5267ea077caryclark SkStreamAsset* fontStream = fontData->getStream(); 715ef194c31ae498166bd9c468993514c5267ea077caryclark if (!fontStream) { 725ef194c31ae498166bd9c468993514c5267ea077caryclark return 0; 735ef194c31ae498166bd9c468993514c5267ea077caryclark } 745ef194c31ae498166bd9c468993514c5267ea077caryclark SkTDArray<char> data; 755ef194c31ae498166bd9c468993514c5267ea077caryclark size_t length = fontStream->getLength(); 765ef194c31ae498166bd9c468993514c5267ea077caryclark if (!length) { 775ef194c31ae498166bd9c468993514c5267ea077caryclark return 0; 785ef194c31ae498166bd9c468993514c5267ea077caryclark } 795ef194c31ae498166bd9c468993514c5267ea077caryclark data.setCount((int) length); 805ef194c31ae498166bd9c468993514c5267ea077caryclark if (!fontStream->peek(data.begin(), length)) { 815ef194c31ae498166bd9c468993514c5267ea077caryclark return 0; 825ef194c31ae498166bd9c468993514c5267ea077caryclark } 834e97607d9a1cef66fac16f347c5ca813ec4f9515mtklein return SkOpts::hash(data.begin(), length); 845ef194c31ae498166bd9c468993514c5267ea077caryclark} 855ef194c31ae498166bd9c468993514c5267ea077caryclark 86b8113780c3cfed640016b263194b7f1531d43312bungemanstatic void serialize_sub(const char* fontName, SkFontStyle style, SkWStream* wstream) { 87b8113780c3cfed640016b263194b7f1531d43312bungeman SkFontDescriptor desc; 885ef194c31ae498166bd9c468993514c5267ea077caryclark SkString subName(SUBNAME_PREFIX); 895ef194c31ae498166bd9c468993514c5267ea077caryclark subName.append(fontName); 905ef194c31ae498166bd9c468993514c5267ea077caryclark const char* familyName = subName.c_str(); 915ef194c31ae498166bd9c468993514c5267ea077caryclark desc.setFamilyName(familyName); 92b8113780c3cfed640016b263194b7f1531d43312bungeman desc.setStyle(style); 935ef194c31ae498166bd9c468993514c5267ea077caryclark desc.serialize(wstream); 945ef194c31ae498166bd9c468993514c5267ea077caryclark#if WHITELIST_DEBUG 955ef194c31ae498166bd9c468993514c5267ea077caryclark for (int i = 0; i < whitelistCount; ++i) { 965ef194c31ae498166bd9c468993514c5267ea077caryclark if (!strcmp(fontName, whitelist[i].fFontName)) { 975ef194c31ae498166bd9c468993514c5267ea077caryclark if (!whitelist[i].fSerializedSub) { 985ef194c31ae498166bd9c468993514c5267ea077caryclark whitelist[i].fSerializedSub = true; 995ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("%s %s\n", __FUNCTION__, familyName); 1005ef194c31ae498166bd9c468993514c5267ea077caryclark } 1015ef194c31ae498166bd9c468993514c5267ea077caryclark break; 1025ef194c31ae498166bd9c468993514c5267ea077caryclark } 1035ef194c31ae498166bd9c468993514c5267ea077caryclark } 1045ef194c31ae498166bd9c468993514c5267ea077caryclark#endif 1055ef194c31ae498166bd9c468993514c5267ea077caryclark} 1065ef194c31ae498166bd9c468993514c5267ea077caryclark 1075ef194c31ae498166bd9c468993514c5267ea077caryclarkstatic bool is_local(const SkTypeface* tf) { 1085ef194c31ae498166bd9c468993514c5267ea077caryclark bool isLocal = false; 109b8113780c3cfed640016b263194b7f1531d43312bungeman SkFontDescriptor desc; 1105ef194c31ae498166bd9c468993514c5267ea077caryclark tf->getFontDescriptor(&desc, &isLocal); 1115ef194c31ae498166bd9c468993514c5267ea077caryclark return isLocal; 1125ef194c31ae498166bd9c468993514c5267ea077caryclark} 1135ef194c31ae498166bd9c468993514c5267ea077caryclark 1145ef194c31ae498166bd9c468993514c5267ea077caryclarkstatic void serialize_full(const SkTypeface* tf, SkWStream* wstream) { 1155ef194c31ae498166bd9c468993514c5267ea077caryclark bool isLocal = false; 116b8113780c3cfed640016b263194b7f1531d43312bungeman SkFontDescriptor desc; 1175ef194c31ae498166bd9c468993514c5267ea077caryclark tf->getFontDescriptor(&desc, &isLocal); 1185ef194c31ae498166bd9c468993514c5267ea077caryclark 1195ef194c31ae498166bd9c468993514c5267ea077caryclark // Embed font data if it's a local font. 1205ef194c31ae498166bd9c468993514c5267ea077caryclark if (isLocal && !desc.hasFontData()) { 121f93d71122e4fcfcdc674a0163455990b13855f2fbungeman desc.setFontData(tf->makeFontData()); 1225ef194c31ae498166bd9c468993514c5267ea077caryclark } 1235ef194c31ae498166bd9c468993514c5267ea077caryclark desc.serialize(wstream); 1245ef194c31ae498166bd9c468993514c5267ea077caryclark} 1255ef194c31ae498166bd9c468993514c5267ea077caryclark 1265ef194c31ae498166bd9c468993514c5267ea077caryclarkstatic void serialize_name_only(const SkTypeface* tf, SkWStream* wstream) { 1275ef194c31ae498166bd9c468993514c5267ea077caryclark bool isLocal = false; 128b8113780c3cfed640016b263194b7f1531d43312bungeman SkFontDescriptor desc; 1295ef194c31ae498166bd9c468993514c5267ea077caryclark tf->getFontDescriptor(&desc, &isLocal); 1305ef194c31ae498166bd9c468993514c5267ea077caryclark SkASSERT(!isLocal); 1315ef194c31ae498166bd9c468993514c5267ea077caryclark#if WHITELIST_DEBUG 1325ef194c31ae498166bd9c468993514c5267ea077caryclark const char* familyName = desc.getFamilyName(); 1335ef194c31ae498166bd9c468993514c5267ea077caryclark if (familyName) { 1345ef194c31ae498166bd9c468993514c5267ea077caryclark if (!strcmp(familyName, "Times New Roman")) { 1355ef194c31ae498166bd9c468993514c5267ea077caryclark if (!timesNewRomanSerializedNameOnly) { 1365ef194c31ae498166bd9c468993514c5267ea077caryclark timesNewRomanSerializedNameOnly = true; 1375ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("%s %s\n", __FUNCTION__, familyName); 1385ef194c31ae498166bd9c468993514c5267ea077caryclark } 1395ef194c31ae498166bd9c468993514c5267ea077caryclark } else { 1405ef194c31ae498166bd9c468993514c5267ea077caryclark for (int i = 0; i < whitelistCount; ++i) { 1415ef194c31ae498166bd9c468993514c5267ea077caryclark if (!strcmp(familyName, whitelist[i].fFontName)) { 1425ef194c31ae498166bd9c468993514c5267ea077caryclark if (!whitelist[i].fSerializedNameOnly) { 1435ef194c31ae498166bd9c468993514c5267ea077caryclark whitelist[i].fSerializedNameOnly = true; 1445ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("%s %s\n", __FUNCTION__, familyName); 1455ef194c31ae498166bd9c468993514c5267ea077caryclark } 1465ef194c31ae498166bd9c468993514c5267ea077caryclark break; 1475ef194c31ae498166bd9c468993514c5267ea077caryclark } 1485ef194c31ae498166bd9c468993514c5267ea077caryclark } 1495ef194c31ae498166bd9c468993514c5267ea077caryclark } 1505ef194c31ae498166bd9c468993514c5267ea077caryclark } 1515ef194c31ae498166bd9c468993514c5267ea077caryclark#endif 1525ef194c31ae498166bd9c468993514c5267ea077caryclark desc.serialize(wstream); 1535ef194c31ae498166bd9c468993514c5267ea077caryclark} 1545ef194c31ae498166bd9c468993514c5267ea077caryclark 1555ef194c31ae498166bd9c468993514c5267ea077caryclarkvoid WhitelistSerializeTypeface(const SkTypeface* tf, SkWStream* wstream) { 1565ef194c31ae498166bd9c468993514c5267ea077caryclark if (!is_local(tf)) { 1575ef194c31ae498166bd9c468993514c5267ea077caryclark serialize_name_only(tf, wstream); 1585ef194c31ae498166bd9c468993514c5267ea077caryclark return; 1595ef194c31ae498166bd9c468993514c5267ea077caryclark } 1605ef194c31ae498166bd9c468993514c5267ea077caryclark int whitelistIndex = whitelist_name_index(tf); 1615ef194c31ae498166bd9c468993514c5267ea077caryclark if (whitelistIndex < 0) { 1625ef194c31ae498166bd9c468993514c5267ea077caryclark serialize_full(tf, wstream); 1635ef194c31ae498166bd9c468993514c5267ea077caryclark return; 1645ef194c31ae498166bd9c468993514c5267ea077caryclark } 1655ef194c31ae498166bd9c468993514c5267ea077caryclark const char* fontName = whitelist[whitelistIndex].fFontName; 166ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc if (!font_name_is_local(fontName, tf->fontStyle())) { 1675ef194c31ae498166bd9c468993514c5267ea077caryclark#if WHITELIST_DEBUG 1685ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("name not found locally \"%s\" style=%d\n", fontName, tf->style()); 1695ef194c31ae498166bd9c468993514c5267ea077caryclark#endif 1705ef194c31ae498166bd9c468993514c5267ea077caryclark serialize_full(tf, wstream); 1715ef194c31ae498166bd9c468993514c5267ea077caryclark return; 1725ef194c31ae498166bd9c468993514c5267ea077caryclark } 1735ef194c31ae498166bd9c468993514c5267ea077caryclark uint32_t checksum = compute_checksum(tf); 1745ef194c31ae498166bd9c468993514c5267ea077caryclark if (whitelist[whitelistIndex].fChecksum != checksum) { 1755ef194c31ae498166bd9c468993514c5267ea077caryclark#if WHITELIST_DEBUG 1765ef194c31ae498166bd9c468993514c5267ea077caryclark if (whitelist[whitelistIndex].fChecksum) { 1775ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("!!! checksum changed !!!\n"); 1785ef194c31ae498166bd9c468993514c5267ea077caryclark } 1795ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("checksum updated\n"); 1805ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf(" { \"%s\", 0x%08x },\n", fontName, checksum); 1815ef194c31ae498166bd9c468993514c5267ea077caryclark#endif 1825ef194c31ae498166bd9c468993514c5267ea077caryclark whitelist[whitelistIndex].fChecksum = checksum; 1835ef194c31ae498166bd9c468993514c5267ea077caryclark } 184b8113780c3cfed640016b263194b7f1531d43312bungeman serialize_sub(fontName, tf->fontStyle(), wstream); 1855ef194c31ae498166bd9c468993514c5267ea077caryclark} 1865ef194c31ae498166bd9c468993514c5267ea077caryclark 18713b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> WhitelistDeserializeTypeface(SkStream* stream) { 1883552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips SkFontDescriptor desc; 1893552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips if (!SkFontDescriptor::Deserialize(stream, &desc)) { 1903552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips return nullptr; 1913552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips } 1923552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips 193f93d71122e4fcfcdc674a0163455990b13855f2fbungeman std::unique_ptr<SkFontData> data = desc.detachFontData(); 1945ef194c31ae498166bd9c468993514c5267ea077caryclark if (data) { 195f93d71122e4fcfcdc674a0163455990b13855f2fbungeman sk_sp<SkTypeface> typeface(SkTypeface::MakeFromFontData(std::move(data))); 1965ef194c31ae498166bd9c468993514c5267ea077caryclark if (typeface) { 1975ef194c31ae498166bd9c468993514c5267ea077caryclark return typeface; 1985ef194c31ae498166bd9c468993514c5267ea077caryclark } 1995ef194c31ae498166bd9c468993514c5267ea077caryclark } 2005ef194c31ae498166bd9c468993514c5267ea077caryclark const char* familyName = desc.getFamilyName(); 2015ef194c31ae498166bd9c468993514c5267ea077caryclark if (!strncmp(SUBNAME_PREFIX, familyName, sizeof(SUBNAME_PREFIX) - 1)) { 2025ef194c31ae498166bd9c468993514c5267ea077caryclark familyName += sizeof(SUBNAME_PREFIX) - 1; 2035ef194c31ae498166bd9c468993514c5267ea077caryclark } 204b8113780c3cfed640016b263194b7f1531d43312bungeman return SkTypeface::MakeFromName(familyName, desc.getStyle()); 2055ef194c31ae498166bd9c468993514c5267ea077caryclark} 2065ef194c31ae498166bd9c468993514c5267ea077caryclark 2075ef194c31ae498166bd9c468993514c5267ea077caryclarkbool CheckChecksums() { 2085ef194c31ae498166bd9c468993514c5267ea077caryclark for (int i = 0; i < whitelistCount; ++i) { 2095ef194c31ae498166bd9c468993514c5267ea077caryclark const char* fontName = whitelist[i].fFontName; 210ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc sk_sp<SkTypeface> tf(SkTypeface::MakeFromName(fontName, SkFontStyle())); 21113b9c95295f4c5732e34574789e721a6bc08f7b4bungeman uint32_t checksum = compute_checksum(tf.get()); 2125ef194c31ae498166bd9c468993514c5267ea077caryclark if (whitelist[i].fChecksum != checksum) { 2135ef194c31ae498166bd9c468993514c5267ea077caryclark return false; 2145ef194c31ae498166bd9c468993514c5267ea077caryclark } 2155ef194c31ae498166bd9c468993514c5267ea077caryclark } 2165ef194c31ae498166bd9c468993514c5267ea077caryclark return true; 2175ef194c31ae498166bd9c468993514c5267ea077caryclark} 2185ef194c31ae498166bd9c468993514c5267ea077caryclark 219cb571e11480e929a1fa18c47ffa2c0ee22f87afbbenjaminwagnerconst char checksumFileName[] = "SkWhitelistChecksums.inc"; 2205ef194c31ae498166bd9c468993514c5267ea077caryclark 2215ef194c31ae498166bd9c468993514c5267ea077caryclarkconst char checksumHeader[] = 2225ef194c31ae498166bd9c468993514c5267ea077caryclark"/*" "\n" 2235ef194c31ae498166bd9c468993514c5267ea077caryclark" * Copyright 2015 Google Inc." "\n" 2245ef194c31ae498166bd9c468993514c5267ea077caryclark" *" "\n" 2255ef194c31ae498166bd9c468993514c5267ea077caryclark" * Use of this source code is governed by a BSD-style license that can be" "\n" 2265ef194c31ae498166bd9c468993514c5267ea077caryclark" * found in the LICENSE file." "\n" 2275ef194c31ae498166bd9c468993514c5267ea077caryclark" *" "\n" 2285ef194c31ae498166bd9c468993514c5267ea077caryclark" * %s() in %s generated %s." "\n" 2295ef194c31ae498166bd9c468993514c5267ea077caryclark" * Run 'whitelist_typefaces --generate' to create anew." "\n" 2305ef194c31ae498166bd9c468993514c5267ea077caryclark" */" "\n" 2315ef194c31ae498166bd9c468993514c5267ea077caryclark"" "\n" 2325ef194c31ae498166bd9c468993514c5267ea077caryclark"#include \"SkTDArray.h\"" "\n" 2335ef194c31ae498166bd9c468993514c5267ea077caryclark"" "\n" 2345ef194c31ae498166bd9c468993514c5267ea077caryclark"struct Whitelist {" "\n" 2355ef194c31ae498166bd9c468993514c5267ea077caryclark" const char* fFontName;" "\n" 2365ef194c31ae498166bd9c468993514c5267ea077caryclark" uint32_t fChecksum;" "\n" 2375ef194c31ae498166bd9c468993514c5267ea077caryclark" bool fSerializedNameOnly;" "\n" 2385ef194c31ae498166bd9c468993514c5267ea077caryclark" bool fSerializedSub;" "\n" 2395ef194c31ae498166bd9c468993514c5267ea077caryclark"};" "\n" 2405ef194c31ae498166bd9c468993514c5267ea077caryclark"" "\n" 2415ef194c31ae498166bd9c468993514c5267ea077caryclark"static Whitelist whitelist[] = {" "\n"; 2425ef194c31ae498166bd9c468993514c5267ea077caryclark 2435ef194c31ae498166bd9c468993514c5267ea077caryclarkconst char checksumEntry[] = 2445ef194c31ae498166bd9c468993514c5267ea077caryclark" { \"%s\", 0x%08x, false, false }," "\n"; 2455ef194c31ae498166bd9c468993514c5267ea077caryclark 2465ef194c31ae498166bd9c468993514c5267ea077caryclarkconst char checksumTrailer[] = 2475ef194c31ae498166bd9c468993514c5267ea077caryclark"};" "\n" 2485ef194c31ae498166bd9c468993514c5267ea077caryclark"" "\n" 2495ef194c31ae498166bd9c468993514c5267ea077caryclark"static const int whitelistCount = (int) SK_ARRAY_COUNT(whitelist);" "\n"; 2505ef194c31ae498166bd9c468993514c5267ea077caryclark 2515ef194c31ae498166bd9c468993514c5267ea077caryclark 2525ef194c31ae498166bd9c468993514c5267ea077caryclark#include "SkOSFile.h" 2535ef194c31ae498166bd9c468993514c5267ea077caryclark 2545ef194c31ae498166bd9c468993514c5267ea077caryclarkbool GenerateChecksums() { 255d76be9c79baa1530d3dc95c58022e83607a1bb2ahalcanary FILE* file = sk_fopen(checksumFileName, kWrite_SkFILE_Flag); 2565ef194c31ae498166bd9c468993514c5267ea077caryclark if (!file) { 2575ef194c31ae498166bd9c468993514c5267ea077caryclark SkDebugf("Can't open %s for writing.\n", checksumFileName); 2585ef194c31ae498166bd9c468993514c5267ea077caryclark return false; 2595ef194c31ae498166bd9c468993514c5267ea077caryclark } 2605ef194c31ae498166bd9c468993514c5267ea077caryclark SkString line; 2615ef194c31ae498166bd9c468993514c5267ea077caryclark line.printf(checksumHeader, __FUNCTION__, __FILE__, checksumFileName); 2625ef194c31ae498166bd9c468993514c5267ea077caryclark sk_fwrite(line.c_str(), line.size(), file); 2635ef194c31ae498166bd9c468993514c5267ea077caryclark for (int i = 0; i < whitelistCount; ++i) { 2645ef194c31ae498166bd9c468993514c5267ea077caryclark const char* fontName = whitelist[i].fFontName; 265ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc sk_sp<SkTypeface> tf(SkTypeface::MakeFromName(fontName, SkFontStyle())); 26613b9c95295f4c5732e34574789e721a6bc08f7b4bungeman uint32_t checksum = compute_checksum(tf.get()); 2675ef194c31ae498166bd9c468993514c5267ea077caryclark line.printf(checksumEntry, fontName, checksum); 2685ef194c31ae498166bd9c468993514c5267ea077caryclark sk_fwrite(line.c_str(), line.size(), file); 2695ef194c31ae498166bd9c468993514c5267ea077caryclark } 2705ef194c31ae498166bd9c468993514c5267ea077caryclark sk_fwrite(checksumTrailer, sizeof(checksumTrailer) - 1, file); 2715ef194c31ae498166bd9c468993514c5267ea077caryclark sk_fclose(file); 2725ef194c31ae498166bd9c468993514c5267ea077caryclark return true; 2735ef194c31ae498166bd9c468993514c5267ea077caryclark} 274