Home | History | Annotate | Download | only in ports
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      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 "SkFontArguments.h"
      9 #include "SkFontDescriptor.h"
     10 #include "SkFontHost_FreeType_common.h"
     11 #include "SkFontMgr.h"
     12 #include "SkFontMgr_custom.h"
     13 #include "SkFontStyle.h"
     14 #include "SkMakeUnique.h"
     15 #include "SkRefCnt.h"
     16 #include "SkStream.h"
     17 #include "SkString.h"
     18 #include "SkTArray.h"
     19 #include "SkTemplates.h"
     20 #include "SkTypeface.h"
     21 #include "SkTypes.h"
     22 
     23 #include <limits>
     24 #include <memory>
     25 
     26 class SkData;
     27 
     28 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
     29                                      bool sysFont, const SkString familyName, int index)
     30     : INHERITED(style, isFixedPitch)
     31     , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
     32 { }
     33 
     34 bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
     35 
     36 void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
     37     *familyName = fFamilyName;
     38 }
     39 
     40 void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
     41     desc->setFamilyName(fFamilyName.c_str());
     42     desc->setStyle(this->fontStyle());
     43     *isLocal = !this->isSysFont();
     44 }
     45 
     46 int SkTypeface_Custom::getIndex() const { return fIndex; }
     47 
     48 
     49 SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
     50 
     51 SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
     52 
     53 
     54 SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
     55                                      const SkFontStyle& style, bool isFixedPitch, bool sysFont,
     56                                      const SkString familyName)
     57     : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
     58     , fData(std::move(fontData))
     59 { }
     60 
     61 SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
     62     *ttcIndex = fData->getIndex();
     63     return fData->getStream()->duplicate().release();
     64 }
     65 
     66 std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
     67     return skstd::make_unique<SkFontData>(*fData);
     68 }
     69 
     70 
     71 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
     72                                  const SkString familyName, const char path[], int index)
     73     : INHERITED(style, isFixedPitch, sysFont, familyName, index)
     74     , fPath(path)
     75 { }
     76 
     77 SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
     78     *ttcIndex = this->getIndex();
     79     return SkStream::MakeFromFile(fPath.c_str()).release();
     80 }
     81 
     82 ///////////////////////////////////////////////////////////////////////////////
     83 
     84 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
     85 
     86 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
     87     fStyles.emplace_back(std::move(typeface));
     88 }
     89 
     90 int SkFontStyleSet_Custom::count() {
     91     return fStyles.count();
     92 }
     93 
     94 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
     95     SkASSERT(index < fStyles.count());
     96     if (style) {
     97         *style = fStyles[index]->fontStyle();
     98     }
     99     if (name) {
    100         name->reset();
    101     }
    102 }
    103 
    104 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
    105     SkASSERT(index < fStyles.count());
    106     return SkRef(fStyles[index].get());
    107 }
    108 
    109 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
    110     return this->matchStyleCSS3(pattern);
    111 }
    112 
    113 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
    114 
    115 
    116 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
    117     loader.loadSystemFonts(fScanner, &fFamilies);
    118 
    119     // Try to pick a default font.
    120     static const char* defaultNames[] = {
    121         "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
    122     };
    123     for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
    124         sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
    125         if (nullptr == set) {
    126             continue;
    127         }
    128 
    129         sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
    130                                                          SkFontStyle::kNormal_Width,
    131                                                          SkFontStyle::kUpright_Slant)));
    132         if (nullptr == tf) {
    133             continue;
    134         }
    135 
    136         fDefaultFamily = set.get();
    137         break;
    138     }
    139     if (nullptr == fDefaultFamily) {
    140         fDefaultFamily = fFamilies[0].get();
    141     }
    142 }
    143 
    144 int SkFontMgr_Custom::onCountFamilies() const {
    145     return fFamilies.count();
    146 }
    147 
    148 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
    149     SkASSERT(index < fFamilies.count());
    150     familyName->set(fFamilies[index]->getFamilyName());
    151 }
    152 
    153 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
    154     SkASSERT(index < fFamilies.count());
    155     return SkRef(fFamilies[index].get());
    156 }
    157 
    158 SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
    159     for (int i = 0; i < fFamilies.count(); ++i) {
    160         if (fFamilies[i]->getFamilyName().equals(familyName)) {
    161             return SkRef(fFamilies[i].get());
    162         }
    163     }
    164     return nullptr;
    165 }
    166 
    167 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
    168                                 const SkFontStyle& fontStyle) const
    169 {
    170     sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
    171     return sset->matchStyle(fontStyle);
    172 }
    173 
    174 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
    175                                                           const SkFontStyle&,
    176                                                           const char* bcp47[], int bcp47Count,
    177                                                           SkUnichar character) const
    178 {
    179     return nullptr;
    180 }
    181 
    182 SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
    183                                                const SkFontStyle& fontStyle) const
    184 {
    185     for (int i = 0; i < fFamilies.count(); ++i) {
    186         for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
    187             if (fFamilies[i]->fStyles[j].get() == familyMember) {
    188                 return fFamilies[i]->matchStyle(fontStyle);
    189             }
    190         }
    191     }
    192     return nullptr;
    193 }
    194 
    195 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
    196     return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
    197 }
    198 
    199 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
    200                                                           int ttcIndex) const {
    201     return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
    202 }
    203 
    204 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
    205                                                          const SkFontArguments& args) const {
    206     using Scanner = SkTypeface_FreeType::Scanner;
    207     bool isFixedPitch;
    208     SkFontStyle style;
    209     SkString name;
    210     Scanner::AxisDefinitions axisDefinitions;
    211     if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
    212                             &name, &style, &isFixedPitch, &axisDefinitions))
    213     {
    214         return nullptr;
    215     }
    216 
    217     const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
    218     SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
    219     Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
    220 
    221     auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
    222                                                axisValues.get(), axisDefinitions.count());
    223     return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
    224 }
    225 
    226 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const {
    227     bool isFixedPitch;
    228     SkFontStyle style;
    229     SkString name;
    230     if (!fScanner.scanFont(data->getStream(), data->getIndex(),
    231                             &name, &style, &isFixedPitch, nullptr)) {
    232         return nullptr;
    233     }
    234     return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
    235 }
    236 
    237 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
    238     std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
    239     return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
    240 }
    241 
    242 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
    243                                                          SkFontStyle style) const {
    244     sk_sp<SkTypeface> tf;
    245 
    246     if (familyName) {
    247         tf.reset(this->onMatchFamilyStyle(familyName, style));
    248     }
    249 
    250     if (nullptr == tf) {
    251         tf.reset(fDefaultFamily->matchStyle(style));
    252     }
    253 
    254     return tf;
    255 }
    256