1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkFontMgr.h"
9cb93a386Sopenharmony_ci#include "include/core/SkFontStyle.h"
10cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h"
11cb93a386Sopenharmony_ci#include "include/core/SkStream.h"
12cb93a386Sopenharmony_ci#include "include/core/SkString.h"
13cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h"
14cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
15cb93a386Sopenharmony_ci#include "include/ports/SkFontMgr_indirect.h"
16cb93a386Sopenharmony_ci#include "include/ports/SkRemotableFontMgr.h"
17cb93a386Sopenharmony_ci#include "include/private/SkMutex.h"
18cb93a386Sopenharmony_ci#include "include/private/SkOnce.h"
19cb93a386Sopenharmony_ci#include "include/private/SkTArray.h"
20cb93a386Sopenharmony_ci#include "include/private/SkTemplates.h"
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_ciclass SkData;
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ciclass SkStyleSet_Indirect : public SkFontStyleSet {
25cb93a386Sopenharmony_cipublic:
26cb93a386Sopenharmony_ci    /** Takes ownership of the SkRemotableFontIdentitySet. */
27cb93a386Sopenharmony_ci    SkStyleSet_Indirect(const SkFontMgr_Indirect* owner, int familyIndex,
28cb93a386Sopenharmony_ci                        SkRemotableFontIdentitySet* data)
29cb93a386Sopenharmony_ci        : fOwner(SkRef(owner)), fFamilyIndex(familyIndex), fData(data)
30cb93a386Sopenharmony_ci    { }
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    int count() override { return fData->count(); }
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci    void getStyle(int index, SkFontStyle* fs, SkString* style) override {
35cb93a386Sopenharmony_ci        if (fs) {
36cb93a386Sopenharmony_ci            *fs = fData->at(index).fFontStyle;
37cb93a386Sopenharmony_ci        }
38cb93a386Sopenharmony_ci        if (style) {
39cb93a386Sopenharmony_ci            // TODO: is this useful? Current locale?
40cb93a386Sopenharmony_ci            style->reset();
41cb93a386Sopenharmony_ci        }
42cb93a386Sopenharmony_ci    }
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci    SkTypeface* createTypeface(int index) override {
45cb93a386Sopenharmony_ci        return fOwner->createTypefaceFromFontId(fData->at(index));
46cb93a386Sopenharmony_ci    }
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci    SkTypeface* matchStyle(const SkFontStyle& pattern) override {
49cb93a386Sopenharmony_ci        if (fFamilyIndex >= 0) {
50cb93a386Sopenharmony_ci            SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pattern);
51cb93a386Sopenharmony_ci            return fOwner->createTypefaceFromFontId(id);
52cb93a386Sopenharmony_ci        }
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci        return this->matchStyleCSS3(pattern);
55cb93a386Sopenharmony_ci    }
56cb93a386Sopenharmony_ciprivate:
57cb93a386Sopenharmony_ci    sk_sp<const SkFontMgr_Indirect> fOwner;
58cb93a386Sopenharmony_ci    int fFamilyIndex;
59cb93a386Sopenharmony_ci    sk_sp<SkRemotableFontIdentitySet> fData;
60cb93a386Sopenharmony_ci};
61cb93a386Sopenharmony_ci
62cb93a386Sopenharmony_ciint SkFontMgr_Indirect::onCountFamilies() const {
63cb93a386Sopenharmony_ci    return 0;
64cb93a386Sopenharmony_ci}
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_civoid SkFontMgr_Indirect::onGetFamilyName(int index, SkString* familyName) const {
67cb93a386Sopenharmony_ci    SK_ABORT("Not implemented");
68cb93a386Sopenharmony_ci}
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ciSkFontStyleSet* SkFontMgr_Indirect::onCreateStyleSet(int index) const {
71cb93a386Sopenharmony_ci    SK_ABORT("Not implemented");
72cb93a386Sopenharmony_ci}
73cb93a386Sopenharmony_ci
74cb93a386Sopenharmony_ciSkFontStyleSet* SkFontMgr_Indirect::onMatchFamily(const char familyName[]) const {
75cb93a386Sopenharmony_ci    return new SkStyleSet_Indirect(this, -1, fProxy->matchName(familyName));
76cb93a386Sopenharmony_ci}
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ciSkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const {
79cb93a386Sopenharmony_ci    if (id.fDataId == SkFontIdentity::kInvalidDataId) {
80cb93a386Sopenharmony_ci        return nullptr;
81cb93a386Sopenharmony_ci    }
82cb93a386Sopenharmony_ci
83cb93a386Sopenharmony_ci    SkAutoMutexExclusive ama(fDataCacheMutex);
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci    sk_sp<SkTypeface> dataTypeface;
86cb93a386Sopenharmony_ci    int dataTypefaceIndex = 0;
87cb93a386Sopenharmony_ci    for (int i = 0; i < fDataCache.count(); ++i) {
88cb93a386Sopenharmony_ci        const DataEntry& entry = fDataCache[i];
89cb93a386Sopenharmony_ci        if (entry.fDataId == id.fDataId) {
90cb93a386Sopenharmony_ci            if (entry.fTtcIndex == id.fTtcIndex &&
91cb93a386Sopenharmony_ci                !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref())
92cb93a386Sopenharmony_ci            {
93cb93a386Sopenharmony_ci                return entry.fTypeface;
94cb93a386Sopenharmony_ci            }
95cb93a386Sopenharmony_ci            if (dataTypeface.get() == nullptr &&
96cb93a386Sopenharmony_ci                !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref())
97cb93a386Sopenharmony_ci            {
98cb93a386Sopenharmony_ci                dataTypeface.reset(entry.fTypeface);
99cb93a386Sopenharmony_ci                dataTypefaceIndex = entry.fTtcIndex;
100cb93a386Sopenharmony_ci            }
101cb93a386Sopenharmony_ci        }
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci        if (entry.fTypeface->weak_expired()) {
104cb93a386Sopenharmony_ci            fDataCache.removeShuffle(i);
105cb93a386Sopenharmony_ci            --i;
106cb93a386Sopenharmony_ci        }
107cb93a386Sopenharmony_ci    }
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ci    // No exact match, but did find a data match.
110cb93a386Sopenharmony_ci    if (dataTypeface.get() != nullptr) {
111cb93a386Sopenharmony_ci        std::unique_ptr<SkStreamAsset> stream(dataTypeface->openStream(nullptr));
112cb93a386Sopenharmony_ci        if (stream.get() != nullptr) {
113cb93a386Sopenharmony_ci            return fImpl->makeFromStream(std::move(stream), dataTypefaceIndex).release();
114cb93a386Sopenharmony_ci        }
115cb93a386Sopenharmony_ci    }
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    // No data match, request data and add entry.
118cb93a386Sopenharmony_ci    std::unique_ptr<SkStreamAsset> stream(fProxy->getData(id.fDataId));
119cb93a386Sopenharmony_ci    if (stream.get() == nullptr) {
120cb93a386Sopenharmony_ci        return nullptr;
121cb93a386Sopenharmony_ci    }
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci    sk_sp<SkTypeface> typeface(fImpl->makeFromStream(std::move(stream), id.fTtcIndex));
124cb93a386Sopenharmony_ci    if (typeface.get() == nullptr) {
125cb93a386Sopenharmony_ci        return nullptr;
126cb93a386Sopenharmony_ci    }
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ci    DataEntry& newEntry = fDataCache.push_back();
129cb93a386Sopenharmony_ci    typeface->weak_ref();
130cb93a386Sopenharmony_ci    newEntry.fDataId = id.fDataId;
131cb93a386Sopenharmony_ci    newEntry.fTtcIndex = id.fTtcIndex;
132cb93a386Sopenharmony_ci    newEntry.fTypeface = typeface.get();  // weak reference passed to new entry.
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_ci    return typeface.release();
135cb93a386Sopenharmony_ci}
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_ciSkTypeface* SkFontMgr_Indirect::onMatchFamilyStyle(const char familyName[],
138cb93a386Sopenharmony_ci                                                   const SkFontStyle& fontStyle) const {
139cb93a386Sopenharmony_ci    SkFontIdentity id = fProxy->matchNameStyle(familyName, fontStyle);
140cb93a386Sopenharmony_ci    return this->createTypefaceFromFontId(id);
141cb93a386Sopenharmony_ci}
142cb93a386Sopenharmony_ci
143cb93a386Sopenharmony_ciSkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[],
144cb93a386Sopenharmony_ci                                                            const SkFontStyle& style,
145cb93a386Sopenharmony_ci                                                            const char* bcp47[],
146cb93a386Sopenharmony_ci                                                            int bcp47Count,
147cb93a386Sopenharmony_ci                                                            SkUnichar character) const {
148cb93a386Sopenharmony_ci    SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47,
149cb93a386Sopenharmony_ci                                                        bcp47Count, character);
150cb93a386Sopenharmony_ci    return this->createTypefaceFromFontId(id);
151cb93a386Sopenharmony_ci}
152cb93a386Sopenharmony_ci
153cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
154cb93a386Sopenharmony_ci                                                            int ttcIndex) const {
155cb93a386Sopenharmony_ci    return fImpl->makeFromStream(std::move(stream), ttcIndex);
156cb93a386Sopenharmony_ci}
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
159cb93a386Sopenharmony_ci                                                           const SkFontArguments& args) const {
160cb93a386Sopenharmony_ci    return fImpl->makeFromStream(std::move(stream), args);
161cb93a386Sopenharmony_ci}
162cb93a386Sopenharmony_ci
163cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromFile(const char path[], int ttcIndex) const {
164cb93a386Sopenharmony_ci    return fImpl->makeFromFile(path, ttcIndex);
165cb93a386Sopenharmony_ci}
166cb93a386Sopenharmony_ci
167cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
168cb93a386Sopenharmony_ci    return fImpl->makeFromData(std::move(data), ttcIndex);
169cb93a386Sopenharmony_ci}
170cb93a386Sopenharmony_ci
171cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Indirect::onLegacyMakeTypeface(const char familyName[],
172cb93a386Sopenharmony_ci                                                           SkFontStyle style) const {
173cb93a386Sopenharmony_ci    sk_sp<SkTypeface> face(this->matchFamilyStyle(familyName, style));
174cb93a386Sopenharmony_ci
175cb93a386Sopenharmony_ci    if (nullptr == face.get()) {
176cb93a386Sopenharmony_ci        face.reset(this->matchFamilyStyle(nullptr, style));
177cb93a386Sopenharmony_ci    }
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_ci    if (nullptr == face.get()) {
180cb93a386Sopenharmony_ci        SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style);
181cb93a386Sopenharmony_ci        face.reset(this->createTypefaceFromFontId(fontId));
182cb93a386Sopenharmony_ci    }
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci    return face;
185cb93a386Sopenharmony_ci}
186