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 <gtest/gtest_prod.h> 21 22 #include <memory> 23 #include <unordered_map> 24 #include <vector> 25 26 #include "minikin/Buffer.h" 27 #include "minikin/Font.h" 28 #include "minikin/FontFamily.h" 29 #include "minikin/MinikinFont.h" 30 #include "minikin/U16StringPiece.h" 31 32 namespace minikin { 33 34 // The maximum number of font families. 35 constexpr uint32_t MAX_FAMILY_COUNT = 254; 36 37 class FontCollection { 38 public: 39 static std::shared_ptr<FontCollection> create( 40 const std::vector<std::shared_ptr<FontFamily>>& typefaces); 41 static std::shared_ptr<FontCollection> create(std::shared_ptr<FontFamily>&& typeface); 42 43 static std::vector<std::shared_ptr<FontCollection>> readVector(BufferReader* reader); 44 static void writeVector(BufferWriter* writer, 45 const std::vector<std::shared_ptr<FontCollection>>& fontCollections); 46 47 // Helper class for representing font family match result in packed bits. 48 struct FamilyMatchResult { 49 public: 50 struct Builder { 51 public: BuilderFamilyMatchResult::Builder52 Builder() : mSize(0), mBits(0) {} 53 addFamilyMatchResult::Builder54 Builder& add(uint8_t x) { 55 if (mSize >= 7) [[unlikely]] { 56 return *this; 57 } 58 mBits = mBits | (static_cast<uint64_t>(x) << (8 * mSize)); 59 mSize++; 60 return *this; 61 } 62 resetFamilyMatchResult::Builder63 Builder& reset() { 64 mSize = 0; 65 mBits = 0; 66 return *this; 67 } 68 sizeFamilyMatchResult::Builder69 uint8_t size() const { return mSize; } 70 emptyFamilyMatchResult::Builder71 bool empty() const { return size() == 0; } 72 buildFamilyMatchResult::Builder73 FamilyMatchResult build() { 74 return FamilyMatchResult(mBits | (static_cast<uint64_t>(mSize) << 56)); 75 } 76 77 private: 78 uint8_t mSize; 79 uint64_t mBits; 80 }; 81 82 // Helper class for iterating FamilyMatchResult 83 class iterator { 84 public: 85 inline bool operator==(const iterator& o) const { 86 return mOffset == o.mOffset && mResult == o.mResult; 87 } 88 89 inline bool operator!=(const iterator& o) const { return !(*this == o); } 90 inline uint8_t operator*() const { return mResult[mOffset]; } 91 inline iterator& operator++() { 92 mOffset++; 93 return *this; 94 } 95 96 private: 97 friend struct FamilyMatchResult; iteratorFamilyMatchResult98 iterator(const FamilyMatchResult& result, uint32_t offset) 99 : mResult(result), mOffset(offset) {} 100 const FamilyMatchResult& mResult; 101 uint32_t mOffset; 102 }; 103 104 // Create empty FamilyMatchResult. FamilyMatchResultFamilyMatchResult105 FamilyMatchResult() : mBits(0) {} 106 sizeFamilyMatchResult107 inline uint8_t size() const { return static_cast<uint8_t>(mBits >> 56); } 108 109 inline uint8_t operator[](uint32_t pos) const { 110 return static_cast<uint8_t>(mBits >> (pos * 8)); 111 } 112 emptyFamilyMatchResult113 inline bool empty() const { return size() == 0; } 114 115 inline bool operator==(const FamilyMatchResult& o) const { return mBits == o.mBits; } 116 117 // Returns the common family indices between l and r. 118 static FamilyMatchResult intersect(FamilyMatchResult l, FamilyMatchResult r); 119 120 // Iterator beginFamilyMatchResult121 inline iterator begin() const { return iterator(*this, 0); } endFamilyMatchResult122 inline iterator end() const { return iterator(*this, size()); } 123 124 FamilyMatchResult(const FamilyMatchResult& o) = default; 125 FamilyMatchResult& operator=(const FamilyMatchResult& o) = default; 126 127 private: FamilyMatchResultFamilyMatchResult128 explicit FamilyMatchResult(uint64_t bits) : mBits(bits) {} 129 uint64_t mBits; 130 }; 131 132 struct Run { 133 FamilyMatchResult familyMatch; 134 int start; 135 int end; 136 }; 137 138 FakedFont getBestFont(U16StringPiece textBuf, const Run& run, FontStyle style); 139 140 // Perform the itemization until given max runs. 141 std::vector<Run> itemize(U16StringPiece text, FontStyle style, uint32_t localeListId, 142 FamilyVariant familyVariant, uint32_t runMax) const; 143 144 // Perform the itemization until end of the text. itemize(U16StringPiece text,FontStyle style,uint32_t localeListId,FamilyVariant familyVariant)145 std::vector<Run> itemize(U16StringPiece text, FontStyle style, uint32_t localeListId, 146 FamilyVariant familyVariant) const { 147 return itemize(text, style, localeListId, familyVariant, text.size()); 148 } 149 150 // Returns true if there is a glyph for the code point and variation selector pair. 151 // Returns false if no fonts have a glyph for the code point and variation 152 // selector pair, or invalid variation selector is passed. 153 bool hasVariationSelector(uint32_t baseCodepoint, uint32_t variationSelector) const; 154 155 // Get base font with fakery information (fake bold could affect metrics) 156 FakedFont baseFontFaked(FontStyle style); 157 158 // Creates new FontCollection based on this collection while applying font variations. Returns 159 // nullptr if none of variations apply to this collection. 160 std::shared_ptr<FontCollection> createCollectionWithVariation( 161 const std::vector<FontVariation>& variations); 162 // Creates new FontCollection that uses the specified families as top families and 163 // families from this FontCollection as fallback. 164 std::shared_ptr<FontCollection> createCollectionWithFamilies( 165 std::vector<std::shared_ptr<FontFamily>>&& families) const; 166 getSupportedAxesCount()167 size_t getSupportedAxesCount() const { return mSupportedAxesCount; } getSupportedAxisAt(size_t index)168 AxisTag getSupportedAxisAt(size_t index) const { return mSupportedAxes[index]; } 169 170 uint32_t getId() const; 171 getFamilyCount()172 size_t getFamilyCount() const { return mFamilyCount; } 173 getFamilyAt(size_t index)174 const std::shared_ptr<FontFamily>& getFamilyAt(size_t index) const { 175 if (mFamilyIndices != nullptr) { 176 index = mFamilyIndices[index]; 177 } 178 return (*mMaybeSharedFamilies)[index]; 179 } 180 181 private: 182 FRIEND_TEST(FontCollectionTest, bufferTest); 183 184 explicit FontCollection(const std::vector<std::shared_ptr<FontFamily>>& typefaces); 185 FontCollection( 186 BufferReader* reader, 187 const std::shared_ptr<std::vector<std::shared_ptr<FontFamily>>>& allFontFamilies); 188 // Write fields of the instance, using fontFamilyToIndexMap for finding 189 // indices for FontFamily. 190 void writeTo(BufferWriter* writer, 191 const std::unordered_map<std::shared_ptr<FontFamily>, uint32_t>& 192 fontFamilyToIndexMap) const; 193 static void collectAllFontFamilies( 194 const std::vector<std::shared_ptr<FontCollection>>& fontCollections, 195 std::vector<std::shared_ptr<FontFamily>>* outAllFontFamilies, 196 std::unordered_map<std::shared_ptr<FontFamily>, uint32_t>* outFontFamilyToIndexMap); 197 198 static const int kLogCharsPerPage = 8; 199 static const int kPageMask = (1 << kLogCharsPerPage) - 1; 200 201 // mFamilyVec holds the indices of the family (as in getFamilyAt()) and 202 // mRanges holds the range of indices of mFamilyVec. 203 // The maximum number of pages is 0x10FF (U+10FFFF >> 8). The maximum number of 204 // the fonts is 0xFF. Thus, technically the maximum length of mFamilyVec is 0x10EE01 205 // (0x10FF * 0xFF). However, in practice, 16-bit integers are enough since most fonts supports 206 // only limited range of code points. 207 struct Range { 208 uint16_t start; 209 uint16_t end; 210 }; 211 212 // Initialize the FontCollection. 213 void init(const std::vector<std::shared_ptr<FontFamily>>& typefaces); 214 215 FamilyMatchResult getFamilyForChar(uint32_t ch, uint32_t vs, uint32_t localeListId, 216 FamilyVariant variant) const; 217 218 uint32_t calcFamilyScore(uint32_t ch, uint32_t vs, FamilyVariant variant, uint32_t localeListId, 219 const std::shared_ptr<FontFamily>& fontFamily) const; 220 221 uint32_t calcCoverageScore(uint32_t ch, uint32_t vs, uint32_t localeListId, 222 const std::shared_ptr<FontFamily>& fontFamily) const; 223 224 bool isPrimaryFamily(const std::shared_ptr<FontFamily>& fontFamily) const; 225 226 static uint32_t calcLocaleMatchingScore(uint32_t userLocaleListId, 227 const FontFamily& fontFamily); 228 229 static uint32_t calcVariantMatchingScore(FamilyVariant variant, const FontFamily& fontFamily); 230 231 // unique id for this font collection (suitable for cache key) 232 uint32_t mId; 233 234 // Highest UTF-32 code point that can be mapped 235 uint32_t mMaxChar; 236 237 // This vector has pointers to the all font family instances in this collection. 238 // This vector can't be empty. 239 // This vector may be shared with other font collections. 240 // (1) When shared, this vector is a union of all font family instances 241 // shared by multiple font collections. 242 // mFamilyIndices will be non-null in this case. 243 // The i-th family in this collection will be 244 // mMaybeSharedFamilies[mFamilyIndices[i]]. 245 // (2) When not shared, mFamilyIndices will be null and 246 // the i-th family in this collection will be mMaybeSharedFamilies[i]. 247 // Use getFamilyAt(i) to access the i-th font in this family. 248 std::shared_ptr<std::vector<std::shared_ptr<FontFamily>>> mMaybeSharedFamilies; 249 uint32_t mFamilyCount; 250 const uint32_t* mFamilyIndices; 251 252 // Following two vectors are pre-calculated tables for resolving coverage faster. 253 // For example, to iterate over all fonts which support Unicode code point U+XXYYZZ, 254 // iterate font families index from mFamilyVec[mRanges[0xXXYY].start] to 255 // mFamilyVec[mRange[0xXXYY].end] instead of whole mFamilies. 256 // This vector contains indices into mFamilies. 257 // This vector can't be empty. 258 uint32_t mRangesCount; 259 const Range* mRanges; 260 uint32_t mFamilyVecCount; 261 const uint8_t* mFamilyVec; 262 263 // This vector has pointers to the font family instances which have cmap 14 subtables. 264 std::vector<std::shared_ptr<FontFamily>> mVSFamilyVec; 265 266 // Set of supported axes in this collection. 267 uint32_t mSupportedAxesCount; 268 // mSupportedAxes is sorted. 269 std::unique_ptr<AxisTag[]> mSupportedAxes; 270 271 // Owns allocated memory if this class is created from font families, otherwise these are 272 // nullptr. 273 std::unique_ptr<Range[]> mOwnedRanges; 274 std::vector<uint8_t> mOwnedFamilyVec; 275 }; 276 277 } // namespace minikin 278 279 #endif // MINIKIN_FONT_COLLECTION_H 280