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