1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkFontMgr.h"
9#include "SkLazyPtr.h"
10#include "SkStream.h"
11#include "SkTypes.h"
12
13class SkFontStyle;
14class SkTypeface;
15
16class SkEmptyFontStyleSet : public SkFontStyleSet {
17public:
18    int count() override { return 0; }
19    void getStyle(int, SkFontStyle*, SkString*) override {
20        SkDEBUGFAIL("SkFontStyleSet::getStyle called on empty set");
21    }
22    SkTypeface* createTypeface(int index) override {
23        SkDEBUGFAIL("SkFontStyleSet::createTypeface called on empty set");
24        return NULL;
25    }
26    SkTypeface* matchStyle(const SkFontStyle&) override {
27        return NULL;
28    }
29};
30
31SkFontStyleSet* SkFontStyleSet::CreateEmpty() {
32    return SkNEW(SkEmptyFontStyleSet);
33}
34
35///////////////////////////////////////////////////////////////////////////////
36
37class SkEmptyFontMgr : public SkFontMgr {
38protected:
39    int onCountFamilies() const override {
40        return 0;
41    }
42    void onGetFamilyName(int index, SkString* familyName) const override {
43        SkDEBUGFAIL("onGetFamilyName called with bad index");
44    }
45    SkFontStyleSet* onCreateStyleSet(int index) const override {
46        SkDEBUGFAIL("onCreateStyleSet called with bad index");
47        return NULL;
48    }
49    SkFontStyleSet* onMatchFamily(const char[]) const override {
50        return SkFontStyleSet::CreateEmpty();
51    }
52
53    virtual SkTypeface* onMatchFamilyStyle(const char[],
54                                           const SkFontStyle&) const override {
55        return NULL;
56    }
57    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
58                                                    const SkFontStyle& style,
59                                                    const char* bcp47[],
60                                                    int bcp47Count,
61                                                    SkUnichar character) const override {
62        return NULL;
63    }
64    virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
65                                         const SkFontStyle&) const override {
66        return NULL;
67    }
68    SkTypeface* onCreateFromData(SkData*, int) const override {
69        return NULL;
70    }
71    SkTypeface* onCreateFromStream(SkStreamAsset* stream, int) const override {
72        SkDELETE(stream);
73        return NULL;
74    }
75    SkTypeface* onCreateFromFile(const char[], int) const override {
76        return NULL;
77    }
78    SkTypeface* onLegacyCreateTypeface(const char [], unsigned) const override {
79        return NULL;
80    }
81};
82
83static SkFontStyleSet* emptyOnNull(SkFontStyleSet* fsset) {
84    if (NULL == fsset) {
85        fsset = SkFontStyleSet::CreateEmpty();
86    }
87    return fsset;
88}
89
90int SkFontMgr::countFamilies() const {
91    return this->onCountFamilies();
92}
93
94void SkFontMgr::getFamilyName(int index, SkString* familyName) const {
95    this->onGetFamilyName(index, familyName);
96}
97
98SkFontStyleSet* SkFontMgr::createStyleSet(int index) const {
99    return emptyOnNull(this->onCreateStyleSet(index));
100}
101
102SkFontStyleSet* SkFontMgr::matchFamily(const char familyName[]) const {
103    return emptyOnNull(this->onMatchFamily(familyName));
104}
105
106SkTypeface* SkFontMgr::matchFamilyStyle(const char familyName[],
107                                        const SkFontStyle& fs) const {
108    return this->onMatchFamilyStyle(familyName, fs);
109}
110
111SkTypeface* SkFontMgr::matchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style,
112                                                 const char* bcp47[], int bcp47Count,
113                                                 SkUnichar character) const {
114    return this->onMatchFamilyStyleCharacter(familyName, style, bcp47, bcp47Count, character);
115}
116
117SkTypeface* SkFontMgr::matchFaceStyle(const SkTypeface* face,
118                                      const SkFontStyle& fs) const {
119    return this->onMatchFaceStyle(face, fs);
120}
121
122SkTypeface* SkFontMgr::createFromData(SkData* data, int ttcIndex) const {
123    if (NULL == data) {
124        return NULL;
125    }
126    return this->onCreateFromData(data, ttcIndex);
127}
128
129SkTypeface* SkFontMgr::createFromStream(SkStreamAsset* stream, int ttcIndex) const {
130    if (NULL == stream) {
131        return NULL;
132    }
133    return this->onCreateFromStream(stream, ttcIndex);
134}
135
136SkTypeface* SkFontMgr::createFromFile(const char path[], int ttcIndex) const {
137    if (NULL == path) {
138        return NULL;
139    }
140    return this->onCreateFromFile(path, ttcIndex);
141}
142
143SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[],
144                                            unsigned styleBits) const {
145    return this->onLegacyCreateTypeface(familyName, styleBits);
146}
147
148// As a template argument this must have external linkage.
149SkFontMgr* sk_fontmgr_create_default() {
150    SkFontMgr* fm = SkFontMgr::Factory();
151    return fm ? fm : SkNEW(SkEmptyFontMgr);
152}
153
154SK_DECLARE_STATIC_LAZY_PTR(SkFontMgr, singleton, sk_fontmgr_create_default);
155
156SkFontMgr* SkFontMgr::RefDefault() {
157    return SkRef(singleton.get());
158}
159