1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINIKIN_FONT_COLLECTION_H 18 #define MINIKIN_FONT_COLLECTION_H 19 20 #include <map> 21 #include <memory> 22 #include <unordered_set> 23 #include <vector> 24 25 #include <minikin/FontFamily.h> 26 #include <minikin/MinikinFont.h> 27 28 namespace minikin { 29 30 class FontCollection { 31 private: 32 explicit FontCollection(); 33 34 public: 35 static std::shared_ptr<minikin::FontCollection> Create( 36 const std::vector<std::shared_ptr<FontFamily>>& typefaces); 37 38 // libtxt extension: an interface for looking up fallback fonts for characters 39 // that do not match this collection's font families. 40 class FallbackFontProvider { 41 public: 42 virtual ~FallbackFontProvider() = default; 43 virtual const std::shared_ptr<FontFamily>& matchFallbackFont( 44 uint32_t ch, 45 std::string locale) = 0; 46 virtual const std::shared_ptr<FontFamily>& matchFallbackFontFromHwFont( 47 uint32_t ch, 48 std::string locale) = 0; 49 }; 50 51 struct Run { 52 FakedFont fakedFont; 53 int start; 54 int end; 55 }; 56 57 void itemize(const uint16_t* string, 58 size_t string_length, 59 FontStyle style, 60 std::vector<Run>* result) const; 61 62 // Returns true if there is a glyph for the code point and variation selector 63 // pair. Returns false if no fonts have a glyph for the code point and 64 // variation selector pair, or invalid variation selector is passed. 65 bool hasVariationSelector(uint32_t baseCodepoint, 66 uint32_t variationSelector) const; 67 68 // Get base font with fakery information (fake bold could affect metrics) 69 FakedFont baseFontFaked(FontStyle style); 70 71 // Creates new FontCollection based on this collection while applying font 72 // variations. Returns nullptr if none of variations apply to this collection. 73 std::shared_ptr<FontCollection> createCollectionWithVariation( 74 const std::vector<FontVariation>& variations); 75 getSupportedTags()76 const std::unordered_set<AxisTag>& getSupportedTags() const { 77 return mSupportedAxes; 78 } 79 80 uint32_t getId() const; 81 set_fallback_font_provider(std::unique_ptr<FallbackFontProvider> ffp)82 void set_fallback_font_provider(std::unique_ptr<FallbackFontProvider> ffp) { 83 mFallbackFontProvider = std::move(ffp); 84 } 85 SetIsZawgyiMyanmar(bool isZawgyiMyanmar)86 void SetIsZawgyiMyanmar(bool isZawgyiMyanmar) { 87 mIsZawgyiMyanmar = isZawgyiMyanmar; 88 } 89 90 private: 91 static const int kLogCharsPerPage = 8; 92 static const int kPageMask = (1 << kLogCharsPerPage) - 1; 93 94 // mFamilyVec holds the indices of the mFamilies and mRanges holds the range 95 // of indices of mFamilyVec. The maximum number of pages is 0x10FF (U+10FFFF 96 // >> 8). The maximum number of the fonts is 0xFF. Thus, technically the 97 // maximum length of mFamilyVec is 0x10EE01 (0x10FF * 0xFF). However, in 98 // practice, 16-bit integers are enough since most fonts supports only limited 99 // range of code points. 100 struct Range { 101 uint16_t start; 102 uint16_t end; 103 }; 104 105 // Initialize the FontCollection. 106 bool init(const std::vector<std::shared_ptr<FontFamily>>& typefaces); 107 108 const std::shared_ptr<FontFamily>& getFamilyForChar(uint32_t ch, 109 uint32_t vs, 110 uint32_t langListId, 111 int variant) const; 112 113 const std::shared_ptr<FontFamily>& 114 findFallbackFont(uint32_t ch, uint32_t vs, uint32_t langListId) const; 115 116 uint32_t calcFamilyScore(uint32_t ch, 117 uint32_t vs, 118 int variant, 119 uint32_t langListId, 120 const std::shared_ptr<FontFamily>& fontFamily) const; 121 122 uint32_t calcCoverageScore( 123 uint32_t ch, 124 uint32_t vs, 125 const std::shared_ptr<FontFamily>& fontFamily) const; 126 127 static uint32_t calcLanguageMatchingScore(uint32_t userLangListId, 128 const FontFamily& fontFamily); 129 130 static uint32_t calcVariantMatchingScore(int variant, 131 const FontFamily& fontFamily); 132 133 // static for allocating unique id's 134 static uint32_t sNextId; 135 136 // unique id for this font collection (suitable for cache key) 137 uint32_t mId; 138 139 // Highest UTF-32 code point that can be mapped 140 uint32_t mMaxChar; 141 142 // This vector has pointers to the all font family instances in this 143 // collection. This vector can't be empty. 144 std::vector<std::shared_ptr<FontFamily>> mFamilies; 145 146 // Following two vectors are pre-calculated tables for resolving coverage 147 // faster. For example, to iterate over all fonts which support Unicode code 148 // point U+XXYYZZ, iterate font families index from 149 // mFamilyVec[mRanges[0xXXYY].start] to mFamilyVec[mRange[0xXXYY].end] instead 150 // of whole mFamilies. This vector contains indices into mFamilies. This 151 // vector can't be empty. 152 std::vector<Range> mRanges; 153 std::vector<uint8_t> mFamilyVec; 154 155 // This vector has pointers to the font family instances which have cmap 14 156 // subtables. 157 std::vector<std::shared_ptr<FontFamily>> mVSFamilyVec; 158 159 // Set of supported axes in this collection. 160 std::unordered_set<AxisTag> mSupportedAxes; 161 162 // libtxt extension: Fallback font provider. 163 std::unique_ptr<FallbackFontProvider> mFallbackFontProvider; 164 165 // libtxt extension: Fallback fonts discovered after this font collection 166 // was constructed. 167 mutable std::map<std::string, std::vector<std::shared_ptr<FontFamily>>> 168 mCachedFallbackFamilies; 169 bool mIsZawgyiMyanmar = false; 170 }; 171 172 } // namespace minikin 173 174 #endif // MINIKIN_FONT_COLLECTION_H 175