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 * 2021.9.9 SkFontMgr on previewer of ohos. 7cb93a386Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. 8cb93a386Sopenharmony_ci */ 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/ports/SkFontMgr_preview.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "src/core/SkTSearch.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ciSkFontMgr_Preview::SkFontMgr_Preview() 15cb93a386Sopenharmony_ci{ 16cb93a386Sopenharmony_ci SkTDArray<FontFamily*> families; 17cb93a386Sopenharmony_ci SkFontMgr_Config_Parser::GetInstance().GetSystemFontFamilies(families); 18cb93a386Sopenharmony_ci this->buildNameToFamilyMap(families); 19cb93a386Sopenharmony_ci this->findDefaultStyleSet(); 20cb93a386Sopenharmony_ci families.deleteAll(); 21cb93a386Sopenharmony_ci} 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciint SkFontMgr_Preview::onCountFamilies() const 24cb93a386Sopenharmony_ci{ 25cb93a386Sopenharmony_ci return fNameToFamilyMap.count(); 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_civoid SkFontMgr_Preview::onGetFamilyName(int index, SkString* familyName) const 29cb93a386Sopenharmony_ci{ 30cb93a386Sopenharmony_ci if (index < 0 || fNameToFamilyMap.count() <= index) { 31cb93a386Sopenharmony_ci familyName->reset(); 32cb93a386Sopenharmony_ci return; 33cb93a386Sopenharmony_ci } 34cb93a386Sopenharmony_ci familyName->set(fNameToFamilyMap[index].name); 35cb93a386Sopenharmony_ci} 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ciSkFontStyleSet* SkFontMgr_Preview::onCreateStyleSet(int index) const 38cb93a386Sopenharmony_ci{ 39cb93a386Sopenharmony_ci if (index < 0 || fNameToFamilyMap.count() <= index) { 40cb93a386Sopenharmony_ci return nullptr; 41cb93a386Sopenharmony_ci } 42cb93a386Sopenharmony_ci return SkRef(fNameToFamilyMap[index].styleSet); 43cb93a386Sopenharmony_ci} 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ciSkFontStyleSet* SkFontMgr_Preview::onMatchFamily(const char familyName[]) const 46cb93a386Sopenharmony_ci{ 47cb93a386Sopenharmony_ci if (!familyName) { 48cb93a386Sopenharmony_ci return nullptr; 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci SkAutoAsciiToLC tolc(familyName); 51cb93a386Sopenharmony_ci for (int i = 0; i < fNameToFamilyMap.count(); ++i) { 52cb93a386Sopenharmony_ci if (fNameToFamilyMap[i].name.equals(tolc.lc())) { 53cb93a386Sopenharmony_ci return SkRef(fNameToFamilyMap[i].styleSet); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci // TODO: eventually we should not need to name fallback families. 57cb93a386Sopenharmony_ci for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { 58cb93a386Sopenharmony_ci if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { 59cb93a386Sopenharmony_ci return SkRef(fFallbackNameToFamilyMap[i].styleSet); 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci return nullptr; 63cb93a386Sopenharmony_ci} 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ciSkTypeface* SkFontMgr_Preview::onMatchFamilyStyle(const char familyName[], const SkFontStyle& style) const 66cb93a386Sopenharmony_ci{ 67cb93a386Sopenharmony_ci sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName)); 68cb93a386Sopenharmony_ci return sset->matchStyle(style); 69cb93a386Sopenharmony_ci} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ciSkTypeface* SkFontMgr_Preview::onMatchFaceStyle(const SkTypeface* typeface, const SkFontStyle& style) const 72cb93a386Sopenharmony_ci{ 73cb93a386Sopenharmony_ci for (int i = 0; i < fStyleSets.count(); ++i) { 74cb93a386Sopenharmony_ci for (int j = 0; j < fStyleSets[i]->fStyles.count(); ++j) { 75cb93a386Sopenharmony_ci if (fStyleSets[i]->fStyles[j].get() == typeface) { 76cb93a386Sopenharmony_ci return fStyleSets[i]->matchStyle(style); 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci return nullptr; 81cb93a386Sopenharmony_ci} 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_cisk_sp<SkTypeface_PreviewSystem> SkFontMgr_Preview::find_family_style_character( 84cb93a386Sopenharmony_ci const SkString& familyName, 85cb93a386Sopenharmony_ci const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap, 86cb93a386Sopenharmony_ci const SkFontStyle& style, bool elegant, 87cb93a386Sopenharmony_ci const SkString& langTag, SkUnichar character) 88cb93a386Sopenharmony_ci{ 89cb93a386Sopenharmony_ci for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) { 90cb93a386Sopenharmony_ci SkFontStyleSet_Preview* family = fallbackNameToFamilyMap[i].styleSet; 91cb93a386Sopenharmony_ci if (familyName != family->fFallbackFor) { 92cb93a386Sopenharmony_ci continue; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci sk_sp<SkTypeface_PreviewSystem> face(family->matchStyle(style)); 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci if (!langTag.isEmpty() && 97cb93a386Sopenharmony_ci std::none_of(face->fLang.begin(), face->fLang.end(), [&](SkLanguage lang) { 98cb93a386Sopenharmony_ci return lang.getTag().startsWith(langTag.c_str()); })) { 99cb93a386Sopenharmony_ci continue; 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) { 103cb93a386Sopenharmony_ci continue; 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci if (face->unicharToGlyph(character) != 0) { 107cb93a386Sopenharmony_ci return face; 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci return nullptr; 111cb93a386Sopenharmony_ci} 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ciSkTypeface* SkFontMgr_Preview::onMatchFamilyStyleCharacter(const char familyName[], 114cb93a386Sopenharmony_ci const SkFontStyle& style, 115cb93a386Sopenharmony_ci const char* bcp47[], 116cb93a386Sopenharmony_ci int bcp47Count, 117cb93a386Sopenharmony_ci SkUnichar character) const 118cb93a386Sopenharmony_ci{ 119cb93a386Sopenharmony_ci // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'. 120cb93a386Sopenharmony_ci // The variant 'default' means 'compact and elegant'. 121cb93a386Sopenharmony_ci // As a result, it is not possible to know the variant context from the font alone. 122cb93a386Sopenharmony_ci // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request. 123cb93a386Sopenharmony_ci SkString familyNameString(familyName); 124cb93a386Sopenharmony_ci for (const SkString& currentFamilyName : { familyNameString, SkString() }) { 125cb93a386Sopenharmony_ci // The first time match anything elegant, second time anything not elegant. 126cb93a386Sopenharmony_ci for (int elegant = 2; elegant-- > 0;) { 127cb93a386Sopenharmony_ci for (int bcp47Index = bcp47Count; bcp47Index-- > 0;) { 128cb93a386Sopenharmony_ci SkLanguage lang(bcp47[bcp47Index]); 129cb93a386Sopenharmony_ci while (!lang.getTag().isEmpty()) { 130cb93a386Sopenharmony_ci sk_sp<SkTypeface_PreviewSystem> matchingTypeface = 131cb93a386Sopenharmony_ci find_family_style_character(currentFamilyName, fFallbackNameToFamilyMap, 132cb93a386Sopenharmony_ci style, SkToBool(elegant), 133cb93a386Sopenharmony_ci lang.getTag(), character); 134cb93a386Sopenharmony_ci if (matchingTypeface) { 135cb93a386Sopenharmony_ci return matchingTypeface.release(); 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci lang = lang.getParent(); 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci sk_sp<SkTypeface_PreviewSystem> matchingTypeface = 141cb93a386Sopenharmony_ci find_family_style_character(currentFamilyName, fFallbackNameToFamilyMap, 142cb93a386Sopenharmony_ci style, SkToBool(elegant), 143cb93a386Sopenharmony_ci SkString(), character); 144cb93a386Sopenharmony_ci if (matchingTypeface) { 145cb93a386Sopenharmony_ci return matchingTypeface.release(); 146cb93a386Sopenharmony_ci } 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci return nullptr; 150cb93a386Sopenharmony_ci} 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Preview::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const 153cb93a386Sopenharmony_ci{ 154cb93a386Sopenharmony_ci return this->makeFromStream(std::unique_ptr<SkStreamAsset>(new SkMemoryStream(std::move(data))), 155cb93a386Sopenharmony_ci ttcIndex); 156cb93a386Sopenharmony_ci} 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Preview::onMakeFromFile(const char path[], int ttcIndex) const 159cb93a386Sopenharmony_ci{ 160cb93a386Sopenharmony_ci std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path); 161cb93a386Sopenharmony_ci return stream.get() ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr; 162cb93a386Sopenharmony_ci} 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Preview::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, int ttcIndex) const 165cb93a386Sopenharmony_ci{ 166cb93a386Sopenharmony_ci bool isFixedPitch; 167cb93a386Sopenharmony_ci SkFontStyle style; 168cb93a386Sopenharmony_ci SkString name; 169cb93a386Sopenharmony_ci if (!fScanner.scanFont(stream.get(), ttcIndex, &name, &style, &isFixedPitch, nullptr)) { 170cb93a386Sopenharmony_ci return nullptr; 171cb93a386Sopenharmony_ci } 172cb93a386Sopenharmony_ci auto data = std::make_unique<SkFontData>(std::move(stream), ttcIndex, nullptr, 0); 173cb93a386Sopenharmony_ci return sk_sp<SkTypeface>(new SkTypeface_PreviewStream(std::move(data), style, isFixedPitch, name)); 174cb93a386Sopenharmony_ci} 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Preview::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream, 177cb93a386Sopenharmony_ci const SkFontArguments& args) const 178cb93a386Sopenharmony_ci{ 179cb93a386Sopenharmony_ci using Scanner = SkTypeface_FreeType::Scanner; 180cb93a386Sopenharmony_ci bool isFixedPitch; 181cb93a386Sopenharmony_ci SkFontStyle style; 182cb93a386Sopenharmony_ci SkString name; 183cb93a386Sopenharmony_ci Scanner::AxisDefinitions axisDefinitions; 184cb93a386Sopenharmony_ci if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), 185cb93a386Sopenharmony_ci &name, &style, &isFixedPitch, &axisDefinitions)) { 186cb93a386Sopenharmony_ci return nullptr; 187cb93a386Sopenharmony_ci } 188cb93a386Sopenharmony_ci SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); 189cb93a386Sopenharmony_ci Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), 190cb93a386Sopenharmony_ci axisValues, name); 191cb93a386Sopenharmony_ci auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), 192cb93a386Sopenharmony_ci axisValues.get(), axisDefinitions.count()); 193cb93a386Sopenharmony_ci return sk_sp<SkTypeface>(new SkTypeface_PreviewStream(std::move(data), style, isFixedPitch, name)); 194cb93a386Sopenharmony_ci} 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_cisk_sp<SkTypeface> SkFontMgr_Preview::onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const 197cb93a386Sopenharmony_ci{ 198cb93a386Sopenharmony_ci if (familyName) { 199cb93a386Sopenharmony_ci return sk_sp<SkTypeface>(this->onMatchFamilyStyle(familyName, style)); 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci return sk_sp<SkTypeface>(fDefaultStyleSet->matchStyle(style)); 202cb93a386Sopenharmony_ci} 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_civoid SkFontMgr_Preview::addFamily(FontFamily& family, int familyIndex) 205cb93a386Sopenharmony_ci{ 206cb93a386Sopenharmony_ci SkTArray<NameToFamily, true>* nameToFamily = &fNameToFamilyMap; 207cb93a386Sopenharmony_ci if (family.fIsFallbackFont) { 208cb93a386Sopenharmony_ci nameToFamily = &fFallbackNameToFamilyMap; 209cb93a386Sopenharmony_ci if (0 == family.fNames.count()) { 210cb93a386Sopenharmony_ci SkString& fallbackName = family.fNames.push_back(); 211cb93a386Sopenharmony_ci fallbackName.printf("%.2x##fallback", familyIndex); 212cb93a386Sopenharmony_ci } 213cb93a386Sopenharmony_ci } 214cb93a386Sopenharmony_ci sk_sp<SkFontStyleSet_Preview> newSet = 215cb93a386Sopenharmony_ci sk_make_sp<SkFontStyleSet_Preview>(family, fScanner); 216cb93a386Sopenharmony_ci if (0 == newSet->count()) { 217cb93a386Sopenharmony_ci return; 218cb93a386Sopenharmony_ci } 219cb93a386Sopenharmony_ci for (const SkString& name : family.fNames) { 220cb93a386Sopenharmony_ci nameToFamily->emplace_back(NameToFamily { name, newSet.get() }); 221cb93a386Sopenharmony_ci } 222cb93a386Sopenharmony_ci fStyleSets.emplace_back(std::move(newSet)); 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_civoid SkFontMgr_Preview::buildNameToFamilyMap(SkTDArray<FontFamily*> families) 226cb93a386Sopenharmony_ci{ 227cb93a386Sopenharmony_ci int familyIndex = 0; 228cb93a386Sopenharmony_ci for (FontFamily* family : families) { 229cb93a386Sopenharmony_ci addFamily(*family, familyIndex++); 230cb93a386Sopenharmony_ci family->fallbackFamilies.foreach([this, &familyIndex] 231cb93a386Sopenharmony_ci (SkString, std::unique_ptr<FontFamily>* fallbackFamily) { 232cb93a386Sopenharmony_ci addFamily(*(*fallbackFamily).get(), familyIndex++); 233cb93a386Sopenharmony_ci } 234cb93a386Sopenharmony_ci ); 235cb93a386Sopenharmony_ci } 236cb93a386Sopenharmony_ci} 237cb93a386Sopenharmony_ci 238cb93a386Sopenharmony_civoid SkFontMgr_Preview::findDefaultStyleSet() 239cb93a386Sopenharmony_ci{ 240cb93a386Sopenharmony_ci SkASSERT(!fStyleSets.empty()); 241cb93a386Sopenharmony_ci static const char* defaultNames[] = { "sans-serif" }; 242cb93a386Sopenharmony_ci for (const char* defaultName : defaultNames) { 243cb93a386Sopenharmony_ci fDefaultStyleSet.reset(this->onMatchFamily(defaultName)); 244cb93a386Sopenharmony_ci if (fDefaultStyleSet) { 245cb93a386Sopenharmony_ci break; 246cb93a386Sopenharmony_ci } 247cb93a386Sopenharmony_ci } 248cb93a386Sopenharmony_ci if (nullptr == fDefaultStyleSet) { 249cb93a386Sopenharmony_ci fDefaultStyleSet = fStyleSets[0]; 250cb93a386Sopenharmony_ci } 251cb93a386Sopenharmony_ci SkASSERT(fDefaultStyleSet); 252cb93a386Sopenharmony_ci} 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_cisk_sp<SkFontMgr> SkFontMgr_New_Preview() 255cb93a386Sopenharmony_ci{ 256cb93a386Sopenharmony_ci return sk_make_sp<SkFontMgr_Preview>(); 257cb93a386Sopenharmony_ci}