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_FAMILY_H 18 #define MINIKIN_FONT_FAMILY_H 19 20 #include <memory> 21 #include <string> 22 #include <unordered_set> 23 #include <vector> 24 25 #include <hb.h> 26 27 #include <utils/TypeHelpers.h> 28 29 #include <minikin/SparseBitSet.h> 30 31 namespace minikin { 32 33 class MinikinFont; 34 35 // FontStyle represents all style information needed to select an actual font 36 // from a collection. The implementation is packed into two 32-bit words 37 // so it can be efficiently copied, embedded in other objects, etc. 38 class FontStyle { 39 public: 40 FontStyle() : FontStyle(0 /* variant */, 4 /* weight */, false /* italic */) {} 41 FontStyle(int weight, bool italic) : FontStyle(0 /* variant */, weight, italic) {} 42 FontStyle(uint32_t langListId) // NOLINT(implicit) 43 : FontStyle(langListId, 0 /* variant */, 4 /* weight */, false /* italic */) {} 44 45 FontStyle(int variant, int weight, bool italic); 46 FontStyle(uint32_t langListId, int variant, int weight, bool italic); 47 48 int getWeight() const { return bits & kWeightMask; } 49 bool getItalic() const { return (bits & kItalicMask) != 0; } 50 int getVariant() const { return (bits >> kVariantShift) & kVariantMask; } 51 uint32_t getLanguageListId() const { return mLanguageListId; } 52 53 bool operator==(const FontStyle other) const { 54 return bits == other.bits && mLanguageListId == other.mLanguageListId; 55 } 56 57 android::hash_t hash() const; 58 59 // Looks up a language list from an internal cache and returns its ID. 60 // If the passed language list is not in the cache, registers it and returns newly assigned ID. 61 static uint32_t registerLanguageList(const std::string& languages); 62 private: 63 static const uint32_t kWeightMask = (1 << 4) - 1; 64 static const uint32_t kItalicMask = 1 << 4; 65 static const int kVariantShift = 5; 66 static const uint32_t kVariantMask = (1 << 2) - 1; 67 68 static uint32_t pack(int variant, int weight, bool italic); 69 70 uint32_t bits; 71 uint32_t mLanguageListId; 72 }; 73 74 enum FontVariant { 75 VARIANT_DEFAULT = 0, 76 VARIANT_COMPACT = 1, 77 VARIANT_ELEGANT = 2, 78 }; 79 80 inline android::hash_t hash_type(const FontStyle &style) { 81 return style.hash(); 82 } 83 84 // attributes representing transforms (fake bold, fake italic) to match styles 85 class FontFakery { 86 public: 87 FontFakery() : mFakeBold(false), mFakeItalic(false) { } 88 FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) { } 89 // TODO: want to support graded fake bolding 90 bool isFakeBold() { return mFakeBold; } 91 bool isFakeItalic() { return mFakeItalic; } 92 private: 93 bool mFakeBold; 94 bool mFakeItalic; 95 }; 96 97 struct FakedFont { 98 // ownership is the enclosing FontCollection 99 MinikinFont* font; 100 FontFakery fakery; 101 }; 102 103 typedef uint32_t AxisTag; 104 105 struct Font { 106 Font(const std::shared_ptr<MinikinFont>& typeface, FontStyle style); 107 Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style); 108 Font(Font&& o); 109 Font(const Font& o); 110 111 std::shared_ptr<MinikinFont> typeface; 112 FontStyle style; 113 114 std::unordered_set<AxisTag> getSupportedAxesLocked() const; 115 }; 116 117 struct FontVariation { 118 FontVariation(AxisTag axisTag, float value) : axisTag(axisTag), value(value) {} 119 AxisTag axisTag; 120 float value; 121 }; 122 123 class FontFamily { 124 public: 125 explicit FontFamily(std::vector<Font>&& fonts); 126 FontFamily(int variant, std::vector<Font>&& fonts); 127 FontFamily(uint32_t langId, int variant, std::vector<Font>&& fonts); 128 129 // TODO: Good to expose FontUtil.h. 130 static bool analyzeStyle(const std::shared_ptr<MinikinFont>& typeface, int* weight, 131 bool* italic); 132 FakedFont getClosestMatch(FontStyle style) const; 133 134 uint32_t langId() const { return mLangId; } 135 int variant() const { return mVariant; } 136 137 // API's for enumerating the fonts in a family. These don't guarantee any particular order 138 size_t getNumFonts() const { return mFonts.size(); } 139 const std::shared_ptr<MinikinFont>& getFont(size_t index) const { 140 return mFonts[index].typeface; 141 } 142 FontStyle getStyle(size_t index) const { return mFonts[index].style; } 143 bool isColorEmojiFamily() const; 144 const std::unordered_set<AxisTag>& supportedAxes() const { return mSupportedAxes; } 145 146 // Get Unicode coverage. 147 const SparseBitSet& getCoverage() const { return mCoverage; } 148 149 // Returns true if the font has a glyph for the code point and variation selector pair. 150 // Caller should acquire a lock before calling the method. 151 bool hasGlyph(uint32_t codepoint, uint32_t variationSelector) const; 152 153 // Returns true if this font family has a variaion sequence table (cmap format 14 subtable). 154 bool hasVSTable() const { return !mCmapFmt14Coverage.empty(); } 155 156 // Creates new FontFamily based on this family while applying font variations. Returns nullptr 157 // if none of variations apply to this family. 158 std::shared_ptr<FontFamily> createFamilyWithVariation( 159 const std::vector<FontVariation>& variations) const; 160 161 private: 162 void computeCoverage(); 163 164 uint32_t mLangId; 165 int mVariant; 166 std::vector<Font> mFonts; 167 std::unordered_set<AxisTag> mSupportedAxes; 168 169 SparseBitSet mCoverage; 170 std::vector<std::unique_ptr<SparseBitSet>> mCmapFmt14Coverage; 171 172 // Forbid copying and assignment. 173 FontFamily(const FontFamily&) = delete; 174 void operator=(const FontFamily&) = delete; 175 }; 176 177 } // namespace minikin 178 179 #endif // MINIKIN_FONT_FAMILY_H 180