18d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman/*
28d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * Copyright 2014 Google Inc.
38d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *
48d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * Use of this source code is governed by a BSD-style license that can be
58d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * found in the LICENSE file.
68d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman */
78d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
81ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include "SkTypes.h"
91ee76510f5dbf632d30975fc3509ef4f609156d2mtklein
10ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar#include "SkData.h"
11f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkFixed.h"
128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontDescriptor.h"
138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontHost_FreeType_common.h"
148d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontMgr.h"
157fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman#include "SkFontMgr_android.h"
16c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman#include "SkFontMgr_android_parser.h"
178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontStyle.h"
18ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar#include "SkOSFile.h"
1924a104d94696bc4b5170e82a28ef05053b302a2dbungeman#include "SkPaint.h"
20f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkRefCnt.h"
21f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkString.h"
228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkStream.h"
23f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTArray.h"
248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkTDArray.h"
258d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkTSearch.h"
26f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTemplates.h"
278d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkTypefaceCache.h"
288d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
298d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include <limits>
308d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
31f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungemanclass SkData;
32f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman
338d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkTypeface_Android : public SkTypeface_FreeType {
348d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic:
3541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    SkTypeface_Android(const SkFontStyle& style,
368d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                       bool isFixedPitch,
374b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman                       const SkString& familyName)
388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
3941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        , fFamilyName(familyName)
4041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        { }
418d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
428d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprotected:
4336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onGetFamilyName(SkString* familyName) const override {
44b374d6a62c0259387d90cad74753d8bad9ee1beabungeman        *familyName = fFamilyName;
45b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    }
46b374d6a62c0259387d90cad74753d8bad9ee1beabungeman
478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkString fFamilyName;
488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
498d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprivate:
508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    typedef SkTypeface_FreeType INHERITED;
518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman};
528d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
538d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkTypeface_AndroidSystem : public SkTypeface_Android {
548d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic:
554b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman    SkTypeface_AndroidSystem(const SkString& pathName,
56ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar                             const bool cacheFontFiles,
578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                             int index,
5841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman                             const SkFixed* axes, int axesCount,
59a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman                             const SkFontStyle& style,
608d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                             bool isFixedPitch,
614b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman                             const SkString& familyName,
6265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                             const SkLanguage& lang,
633b6255493e458c6b2c1412af908581f0bf3f6b70djsollen                             FontVariant variantStyle)
6441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        : INHERITED(style, isFixedPitch, familyName)
6565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        , fPathName(pathName)
6641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        , fIndex(index)
6741868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        , fAxes(axes, axesCount)
6865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        , fLang(lang)
69ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        , fVariantStyle(variantStyle)
70ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        , fFile(cacheFontFiles ? sk_fopen(fPathName.c_str(), kRead_SkFILE_Flag) : nullptr) {
71ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        if (cacheFontFiles) {
72ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar            SkASSERT(fFile);
73ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        }
74ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar    }
75ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar
76ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar    SkStreamAsset* createStream() const {
77ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        if (fFile) {
78ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar            SkData* data = SkData::NewFromFILE(fFile);
79ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar            return data ? new SkMemoryStream(data) : nullptr;
80ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        }
81ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        return SkStream::NewFromFile(fPathName.c_str());
82ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar    }
838d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
8441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
858d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(desc);
868d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(serialize);
878d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        desc->setFamilyName(fFamilyName.c_str());
888d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        *serialize = false;
898d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
9036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkStreamAsset* onOpenStream(int* ttcIndex) const override {
918d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        *ttcIndex = fIndex;
92ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        return this->createStream();
938d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
9441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    SkFontData* onCreateFontData() const override {
95ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        return new SkFontData(this->createStream(), fIndex, fAxes.begin(), fAxes.count());
9641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    }
978d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
9865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    const SkString fPathName;
9941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    int fIndex;
10041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    const SkSTArray<4, SkFixed, true> fAxes;
10165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    const SkLanguage fLang;
1023b6255493e458c6b2c1412af908581f0bf3f6b70djsollen    const FontVariant fVariantStyle;
103ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar    SkAutoTCallVProc<FILE, sk_fclose> fFile;
1048d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
1058d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    typedef SkTypeface_Android INHERITED;
1068d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman};
1078d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
1088d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkTypeface_AndroidStream : public SkTypeface_Android {
1098d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic:
11041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    SkTypeface_AndroidStream(SkFontData* data,
111a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman                             const SkFontStyle& style,
1128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                             bool isFixedPitch,
1134b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman                             const SkString& familyName)
11441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        : INHERITED(style, isFixedPitch, familyName)
11541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        , fData(data)
11641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    { }
1178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
1188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    virtual void onGetFontDescriptor(SkFontDescriptor* desc,
11936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                                     bool* serialize) const override {
1208d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(desc);
1218d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(serialize);
1228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        desc->setFamilyName(fFamilyName.c_str());
1238d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        *serialize = true;
1248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
1258d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
12636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkStreamAsset* onOpenStream(int* ttcIndex) const override {
12741868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        *ttcIndex = fData->getIndex();
12841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        return fData->duplicateStream();
1293489ee0f4fa34f124f9de090d12bdc2107d52aa9bungeman    }
1305ae1312c9faa25531c07e591b4dff6804020f121bungeman
13141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    SkFontData* onCreateFontData() const override {
13241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        return new SkFontData(*fData.get());
13341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    }
134465706820d0d373f76ab4831c286115ee0d86b7arobertphillips
13541868fe5625fc3bd70daa3f461c881b5db6a9265bungemanprivate:
13641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    const SkAutoTDelete<const SkFontData> fData;
1378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    typedef SkTypeface_Android INHERITED;
1388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman};
1398d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
1408d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkFontStyleSet_Android : public SkFontStyleSet {
14141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    typedef SkTypeface_FreeType::Scanner Scanner;
14241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman
1438d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic:
144ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar    explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& scanner,
145ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar                                    const bool cacheFontFiles) {
14696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        const SkString* cannonicalFamilyName = nullptr;
14765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        if (family.fNames.count() > 0) {
14865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            cannonicalFamilyName = &family.fNames[0];
14965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        }
1508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        // TODO? make this lazy
151d3ddea284ec6611a93a6b75e64de39d0bc7e083ctomhudson        for (int i = 0; i < family.fFonts.count(); ++i) {
152d3ddea284ec6611a93a6b75e64de39d0bc7e083ctomhudson            const FontFileInfo& fontFile = family.fFonts[i];
1538d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
1547fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman            SkString pathName(family.fBasePath);
1557fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman            pathName.append(fontFile.fFileName);
1568d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
157a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo            SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(pathName.c_str()));
1588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            if (!stream.get()) {
1597fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                SkDEBUGF(("Requested font file %s does not exist or cannot be opened.\n",
1607fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                          pathName.c_str()));
1618d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                continue;
1628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
1638d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
16465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            const int ttcIndex = fontFile.fIndex;
16565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            SkString familyName;
166a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman            SkFontStyle style;
1678d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            bool isFixedWidth;
16841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman            Scanner::AxisDefinitions axisDefinitions;
16941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman            if (!scanner.scanFont(stream.get(), ttcIndex,
17041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman                                  &familyName, &style, &isFixedWidth, &axisDefinitions))
17141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman            {
1727fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                SkDEBUGF(("Requested font file %s exists, but is not a valid font.\n",
1737fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                          pathName.c_str()));
1748d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                continue;
1758d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
1768d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
177e85a754a4ce9b279159270faa6717932f7a8548fbungeman            int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight();
178e85a754a4ce9b279159270faa6717932f7a8548fbungeman            SkFontStyle::Slant slant = style.slant();
179e85a754a4ce9b279159270faa6717932f7a8548fbungeman            switch (fontFile.fStyle) {
180e85a754a4ce9b279159270faa6717932f7a8548fbungeman                case FontFileInfo::Style::kAuto: slant = style.slant(); break;
181e85a754a4ce9b279159270faa6717932f7a8548fbungeman                case FontFileInfo::Style::kNormal: slant = SkFontStyle::kUpright_Slant; break;
182e85a754a4ce9b279159270faa6717932f7a8548fbungeman                case FontFileInfo::Style::kItalic: slant = SkFontStyle::kItalic_Slant; break;
183e85a754a4ce9b279159270faa6717932f7a8548fbungeman                default: SkASSERT(false); break;
1844b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman            }
185e85a754a4ce9b279159270faa6717932f7a8548fbungeman            style = SkFontStyle(weight, style.width(), slant);
1864b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman
1873b6255493e458c6b2c1412af908581f0bf3f6b70djsollen            const SkLanguage& lang = family.fLanguage;
1883b6255493e458c6b2c1412af908581f0bf3f6b70djsollen            uint32_t variant = family.fVariant;
1893b6255493e458c6b2c1412af908581f0bf3f6b70djsollen            if (kDefault_FontVariant == variant) {
1903b6255493e458c6b2c1412af908581f0bf3f6b70djsollen                variant = kCompact_FontVariant | kElegant_FontVariant;
19165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            }
19265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
19365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            // The first specified family name overrides the family name found in the font.
19465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return
19565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            // all of the specified family names in addition to the names found in the font.
19696fcdcc219d2a0d3579719b84b28bede76efba64halcanary            if (cannonicalFamilyName != nullptr) {
19765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                familyName = *cannonicalFamilyName;
19865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            }
19965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
20041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman            SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
20147a1e96b957b50662274360f1a390d76ab3d02ccbungeman            Scanner::computeAxisValues(axisDefinitions,
20247a1e96b957b50662274360f1a390d76ab3d02ccbungeman                                       fontFile.fAxes.begin(), fontFile.fAxes.count(),
20347a1e96b957b50662274360f1a390d76ab3d02ccbungeman                                       axisValues, familyName);
20441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman
205f6c7107d0385cc2b556802354b93b7dcff61570dbungeman            fStyles.push_back().reset(new SkTypeface_AndroidSystem(
206ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar                    pathName, cacheFontFiles, ttcIndex, axisValues.get(), axisDefinitions.count(),
207ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar                    style, isFixedWidth, familyName, lang, variant));
2088d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
2098d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
2108d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
21136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int count() override {
2128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return fStyles.count();
2138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
21436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void getStyle(int index, SkFontStyle* style, SkString* name) override {
2158d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (index < 0 || fStyles.count() <= index) {
2168d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            return;
2178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
2188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (style) {
2198d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            *style = this->style(index);
2208d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
2218d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (name) {
2228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            name->reset();
2238d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
2248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
22536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface_AndroidSystem* createTypeface(int index) override {
2268d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (index < 0 || fStyles.count() <= index) {
22796fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
2288d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
2298d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return SkRef(fStyles[index].get());
2308d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
2318d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
2328d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    /** Find the typeface in this style set that most closely matches the given pattern.
2338d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman     *  TODO: consider replacing with SkStyleSet_Indirect::matchStyle();
2348d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman     *  this simpler version using match_score() passes all our tests.
2358d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman     */
23636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) override {
2378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (0 == fStyles.count()) {
23896fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
2398d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
24065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        SkTypeface_AndroidSystem* closest = fStyles[0];
2418d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        int minScore = std::numeric_limits<int>::max();
2428d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        for (int i = 0; i < fStyles.count(); ++i) {
2438d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            SkFontStyle style = this->style(i);
2448d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            int score = match_score(pattern, style);
2458d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            if (score < minScore) {
2468d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                closest = fStyles[i];
2478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                minScore = score;
2488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
2498d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
2508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return SkRef(closest);
2518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
2528d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
2538d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprivate:
2548d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkFontStyle style(int index) {
2554b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman        return fStyles[index]->fontStyle();
2568d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
2578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) {
2588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        int score = 0;
259f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman        score += SkTAbs((pattern.width() - candidate.width()) * 100);
260f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman        score += SkTAbs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000);
261f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman        score += SkTAbs(pattern.weight() - candidate.weight());
2628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return score;
2638d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
2648d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
26565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles;
2668d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
2678d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    friend struct NameToFamily;
2688d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    friend class SkFontMgr_Android;
2698d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
2708d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    typedef SkFontStyleSet INHERITED;
2718d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman};
2728d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
2738d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman/** On Android a single family can have many names, but our API assumes unique names.
2748d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *  Map names to the back end so that all names for a given family refer to the same
2758d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *  (non-replicated) set of typefaces.
2768d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *  SkTDict<> doesn't let us do index-based lookup, so we write our own mapping.
2778d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman */
2788d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanstruct NameToFamily {
2798d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkString name;
2808d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkFontStyleSet_Android* styleSet;
2818d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman};
2828d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
2838d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkFontMgr_Android : public SkFontMgr {
2848d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic:
2857fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman    SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom) {
2867fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        SkTDArray<FontFamily*> families;
2877fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fSystemFontUse) {
2887fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman            SkString base(custom->fBasePath);
289c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman            SkFontMgr_Android_Parser::GetCustomFontFamilies(
290c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman                families, base, custom->fFontsXml, custom->fFallbackFontsXml);
2917fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        }
2927fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        if (!custom ||
2937fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman            (custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSystemFontUse))
2947fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        {
295c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman            SkFontMgr_Android_Parser::GetSystemFontFamilies(families);
2967fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        }
2977fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem == custom->fSystemFontUse) {
2987fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman            SkString base(custom->fBasePath);
299c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman            SkFontMgr_Android_Parser::GetCustomFontFamilies(
300c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman                families, base, custom->fFontsXml, custom->fFallbackFontsXml);
3017fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        }
302ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar        this->buildNameToFamilyMap(families, custom ? custom->fIsolated : false);
3038d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        this->findDefaultFont();
3047fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        families.deleteAll();
3058d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3068d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
3078d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprotected:
3088d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    /** Returns not how many families we have, but how many unique names
3098d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman     *  exist among the families.
3108d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman     */
31136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int onCountFamilies() const override {
3128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return fNameToFamilyMap.count();
3138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3148d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
31536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onGetFamilyName(int index, SkString* familyName) const override {
3168d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (index < 0 || fNameToFamilyMap.count() <= index) {
3178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            familyName->reset();
3188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            return;
3198d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
3208d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        familyName->set(fNameToFamilyMap[index].name);
3218d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
32336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkFontStyleSet* onCreateStyleSet(int index) const override {
3248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (index < 0 || fNameToFamilyMap.count() <= index) {
32596fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
3268d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
3278d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return SkRef(fNameToFamilyMap[index].styleSet);
3288d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3298d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
33036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
3318d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        if (!familyName) {
33296fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
3338d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
3348d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkAutoAsciiToLC tolc(familyName);
3358d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        for (int i = 0; i < fNameToFamilyMap.count(); ++i) {
3368d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            if (fNameToFamilyMap[i].name.equals(tolc.lc())) {
3378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                return SkRef(fNameToFamilyMap[i].styleSet);
3388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
3398d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
34065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        // TODO: eventually we should not need to name fallback families.
34165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) {
34265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) {
34365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                return SkRef(fFallbackNameToFamilyMap[i].styleSet);
34465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            }
34565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        }
34696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
3478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
3498d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
35036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                                           const SkFontStyle& style) const override {
3518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
3528d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        return sset->matchStyle(style);
3538d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3548d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
3558d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
35636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                                         const SkFontStyle& style) const override {
3578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        for (int i = 0; i < fFontStyleSets.count(); ++i) {
3588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) {
3598d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                if (fFontStyleSets[i]->fStyles[j] == typeface) {
3608d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                    return fFontStyleSets[i]->matchStyle(style);
3618d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                }
3628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
3638d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
36496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
3658d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
3668d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
367c9232dcda016feb2d30abb51483b3b1862775f84bungeman    static SkTypeface_AndroidSystem* find_family_style_character(
368c9232dcda016feb2d30abb51483b3b1862775f84bungeman            const SkTDArray<NameToFamily>& fallbackNameToFamilyMap,
369c9232dcda016feb2d30abb51483b3b1862775f84bungeman            const SkFontStyle& style, bool elegant,
370c9232dcda016feb2d30abb51483b3b1862775f84bungeman            const SkString& langTag, SkUnichar character)
371c9232dcda016feb2d30abb51483b3b1862775f84bungeman    {
372c9232dcda016feb2d30abb51483b3b1862775f84bungeman        for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) {
373c9232dcda016feb2d30abb51483b3b1862775f84bungeman            SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet;
374c9232dcda016feb2d30abb51483b3b1862775f84bungeman            SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style));
375c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman
376c9232dcda016feb2d30abb51483b3b1862775f84bungeman            if (!langTag.isEmpty() && !face->fLang.getTag().startsWith(langTag.c_str())) {
377c9232dcda016feb2d30abb51483b3b1862775f84bungeman                continue;
378c9232dcda016feb2d30abb51483b3b1862775f84bungeman            }
379c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman
380c9232dcda016feb2d30abb51483b3b1862775f84bungeman            if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
381c9232dcda016feb2d30abb51483b3b1862775f84bungeman                continue;
382c9232dcda016feb2d30abb51483b3b1862775f84bungeman            }
383c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman
38424a104d94696bc4b5170e82a28ef05053b302a2dbungeman            SkPaint paint;
38524a104d94696bc4b5170e82a28ef05053b302a2dbungeman            paint.setTypeface(face);
38624a104d94696bc4b5170e82a28ef05053b302a2dbungeman            paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
38724a104d94696bc4b5170e82a28ef05053b302a2dbungeman
38824a104d94696bc4b5170e82a28ef05053b302a2dbungeman            uint16_t glyphID;
38924a104d94696bc4b5170e82a28ef05053b302a2dbungeman            paint.textToGlyphs(&character, sizeof(character), &glyphID);
39024a104d94696bc4b5170e82a28ef05053b302a2dbungeman            if (glyphID != 0) {
391c9232dcda016feb2d30abb51483b3b1862775f84bungeman                return face.detach();
392c9232dcda016feb2d30abb51483b3b1862775f84bungeman            }
393c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman        }
39496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
395c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman    }
396c9232dcda016feb2d30abb51483b3b1862775f84bungeman
39765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
39865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                                                    const SkFontStyle& style,
399c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                                                    const char* bcp47[],
400c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                                                    int bcp47Count,
40136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                                                    SkUnichar character) const override
40265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    {
40365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'.
40465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        // The variant 'default' means 'compact and elegant'.
40565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        // As a result, it is not possible to know the variant context from the font alone.
40665fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request.
40765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
408c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman        // The first time match anything elegant, second time anything not elegant.
409c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman        for (int elegant = 2; elegant --> 0;) {
410c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman            for (int bcp47Index = bcp47Count; bcp47Index --> 0;) {
411c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                SkLanguage lang(bcp47[bcp47Index]);
412c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                while (!lang.getTag().isEmpty()) {
413c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                    SkTypeface_AndroidSystem* matchingTypeface =
414c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                        find_family_style_character(fFallbackNameToFamilyMap,
415c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                                                    style, SkToBool(elegant),
416c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                                                    lang.getTag(), character);
417c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                    if (matchingTypeface) {
418c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                        return matchingTypeface;
41965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                    }
42065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
421c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                    lang = lang.getParent();
42265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                }
423c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman            }
424c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman            SkTypeface_AndroidSystem* matchingTypeface =
425c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                find_family_style_character(fFallbackNameToFamilyMap,
426c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                                            style, SkToBool(elegant),
427c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                                            SkString(), character);
428c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman            if (matchingTypeface) {
429c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman                return matchingTypeface;
430c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman            }
43165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman        }
43296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
43365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    }
43465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
43536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override {
436a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo        return this->createFromStream(new SkMemoryStream(data), ttcIndex);
4378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
4388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
43936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
4405f213d9627d2eefa7da81cd97f36754f75eb4ae9bungeman        SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path));
44196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : nullptr;
4428d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
4438d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
44436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override {
4455f213d9627d2eefa7da81cd97f36754f75eb4ae9bungeman        SkAutoTDelete<SkStreamAsset> stream(bareStream);
4468d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        bool isFixedPitch;
447a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman        SkFontStyle style;
4488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkString name;
44996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch, nullptr)) {
45096fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
45141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        }
45296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkFontData* data(new SkFontData(stream.detach(), ttcIndex, nullptr, 0));
453385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        return new SkTypeface_AndroidStream(data, style, isFixedPitch, name);
45441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    }
45541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman
456f6c7107d0385cc2b556802354b93b7dcff61570dbungeman    SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override {
457f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        using Scanner = SkTypeface_FreeType::Scanner;
458f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        SkAutoTDelete<SkStreamAsset> stream(s);
459f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        bool isFixedPitch;
460f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        SkFontStyle style;
461f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        SkString name;
462f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        Scanner::AxisDefinitions axisDefinitions;
463f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        if (!fScanner.scanFont(stream, params.getCollectionIndex(), &name, &style, &isFixedPitch,
464f6c7107d0385cc2b556802354b93b7dcff61570dbungeman                               &axisDefinitions))
465f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        {
466f6c7107d0385cc2b556802354b93b7dcff61570dbungeman            return nullptr;
467f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        }
468f6c7107d0385cc2b556802354b93b7dcff61570dbungeman
469f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        int paramAxisCount;
470f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
471f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
472f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name);
473f6c7107d0385cc2b556802354b93b7dcff61570dbungeman
474f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        SkFontData* data(new SkFontData(stream.detach(), params.getCollectionIndex(),
475f6c7107d0385cc2b556802354b93b7dcff61570dbungeman                                        axisValues.get(), axisDefinitions.count()));
476f6c7107d0385cc2b556802354b93b7dcff61570dbungeman        return new SkTypeface_AndroidStream(data, style, isFixedPitch, name);
477f6c7107d0385cc2b556802354b93b7dcff61570dbungeman    }
478f6c7107d0385cc2b556802354b93b7dcff61570dbungeman
47941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    SkTypeface* onCreateFromFontData(SkFontData* data) const override {
48041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        SkStreamAsset* stream(data->getStream());
48141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        bool isFixedPitch;
48241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        SkFontStyle style;
48341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman        SkString name;
48496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (!fScanner.scanFont(stream, data->getIndex(), &name, &style, &isFixedPitch, nullptr)) {
48596fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
4868d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
487385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        return new SkTypeface_AndroidStream(data, style, isFixedPitch, name);
4888d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
4898d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
4908d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
4918d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
49236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                                               unsigned styleBits) const override {
493a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman        SkFontStyle style = SkFontStyle(styleBits);
4948d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
49549f085dddff10473b6ebf832a974288300224e60bsalomon        if (familyName) {
49696fcdcc219d2a0d3579719b84b28bede76efba64halcanary            // On Android, we must return nullptr when we can't find the requested
4978d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            // named typeface so that the system/app can provide their own recovery
4988d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            // mechanism. On other platforms we'd provide a typeface from the
4998d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            // default family instead.
50007cfb20a0b9a14b8daeb56fcf21d810e91387fd1bungeman            return this->onMatchFamilyStyle(familyName, style);
5018d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
50207cfb20a0b9a14b8daeb56fcf21d810e91387fd1bungeman        return fDefaultFamily->matchStyle(style);
5038d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
5048d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5058d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5068d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprivate:
5078d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
50814df8339841f246a7337a8fb0d90f1b7ee689619bungeman    SkTypeface_FreeType::Scanner fScanner;
50914df8339841f246a7337a8fb0d90f1b7ee689619bungeman
5108d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets;
5118d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkFontStyleSet* fDefaultFamily;
5128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkTypeface* fDefaultTypeface;
5138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5148d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    SkTDArray<NameToFamily> fNameToFamilyMap;
51565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman    SkTDArray<NameToFamily> fFallbackNameToFamilyMap;
5168d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
517ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar    void buildNameToFamilyMap(SkTDArray<FontFamily*> families, const bool isolated) {
5188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        for (int i = 0; i < families.count(); i++) {
51965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            FontFamily& family = *families[i];
52065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
52165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap;
52265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            if (family.fIsFallbackFont) {
52365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                nameToFamily = &fFallbackNameToFamilyMap;
52465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
52565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                if (0 == family.fNames.count()) {
52665fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                    SkString& fallbackName = family.fNames.push_back();
52765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                    fallbackName.printf("%.2x##fallback", i);
52865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                }
52965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            }
53065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
531ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar            SkFontStyleSet_Android* newSet = new SkFontStyleSet_Android(family, fScanner, isolated);
53265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            if (0 == newSet->count()) {
533385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary                delete newSet;
53465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                continue;
53565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            }
53665fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            fFontStyleSets.push_back().reset(newSet);
53765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman
53865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman            for (int j = 0; j < family.fNames.count(); j++) {
53965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                NameToFamily* nextEntry = nameToFamily->append();
540385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary                new (&nextEntry->name) SkString(family.fNames[j]);
54165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman                nextEntry->styleSet = newSet;
5428d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
5438d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
5448d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
5458d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5468d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    void findDefaultFont() {
5478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(!fFontStyleSets.empty());
5488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5498d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        static const char* gDefaultNames[] = { "sans-serif" };
5508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) {
5518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]);
55296fcdcc219d2a0d3579719b84b28bede76efba64halcanary            if (nullptr == set) {
5538d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                continue;
5548d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
5558d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            SkTypeface* tf = set->matchStyle(SkFontStyle());
55696fcdcc219d2a0d3579719b84b28bede76efba64halcanary            if (nullptr == tf) {
5578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman                continue;
5588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            }
5598d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            fDefaultFamily = set;
5608d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            fDefaultTypeface = tf;
5618d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            break;
5628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
56396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == fDefaultTypeface) {
5648d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            fDefaultFamily = fFontStyleSets[0];
5658d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman            fDefaultTypeface = fDefaultFamily->createTypeface(0);
5668d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        }
5678d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(fDefaultFamily);
5688d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman        SkASSERT(fDefaultTypeface);
5698d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    }
5708d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5718d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman    typedef SkFontMgr INHERITED;
5728d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman};
5738d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman
5747fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman#ifdef SK_DEBUG
5757fa87cd09f49f1ee9bc27e263038d0f0ae706241bungemanstatic char const * const gSystemFontUseStrings[] = {
5767fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman    "OnlyCustom", "PreferCustom", "PreferSystem"
5777fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman};
5787fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman#endif
5797fa87cd09f49f1ee9bc27e263038d0f0ae706241bungemanSkFontMgr* SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom) {
5807fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman    if (custom) {
5817fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        SkASSERT(0 <= custom->fSystemFontUse);
5827fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings));
5837fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman        SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n",
5847fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                  gSystemFontUseStrings[custom->fSystemFontUse],
5857fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                  custom->fBasePath,
5867fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                  custom->fFontsXml,
5877fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman                  custom->fFallbackFontsXml));
5884e3523cf546df4079cf769b8ecc8011403420a45bungeman    }
5894e3523cf546df4079cf769b8ecc8011403420a45bungeman
590385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new SkFontMgr_Android(custom);
5918d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}
592