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 <vector> 21 #include <string> 22 23 #include <utils/TypeHelpers.h> 24 25 #include <minikin/MinikinRefCounted.h> 26 #include <minikin/SparseBitSet.h> 27 28 namespace android { 29 30 class MinikinFont; 31 32 // FontLanguage is a compact representation of a bcp-47 language tag. It 33 // does not capture all possible information, only what directly affects 34 // font rendering. 35 class FontLanguage { 36 friend class FontStyle; 37 public: 38 FontLanguage() : mBits(0) { } 39 40 // Parse from string 41 FontLanguage(const char* buf, size_t size); 42 43 bool operator==(const FontLanguage other) const { return mBits == other.mBits; } 44 operator bool() const { return mBits != 0; } 45 46 std::string getString() const; 47 48 // 0 = no match, 1 = language matches, 2 = language and script match 49 int match(const FontLanguage other) const; 50 51 private: 52 explicit FontLanguage(uint32_t bits) : mBits(bits) { } 53 54 uint32_t bits() const { return mBits; } 55 56 static const uint32_t kBaseLangMask = 0xffff; 57 static const uint32_t kScriptMask = (1 << 18) - (1 << 16); 58 static const uint32_t kHansFlag = 1 << 16; 59 static const uint32_t kHantFlag = 1 << 17; 60 uint32_t mBits; 61 }; 62 63 // FontStyle represents all style information needed to select an actual font 64 // from a collection. The implementation is packed into a single 32-bit word 65 // so it can be efficiently copied, embedded in other objects, etc. 66 class FontStyle { 67 public: 68 FontStyle(int weight = 4, bool italic = false) { 69 bits = (weight & kWeightMask) | (italic ? kItalicMask : 0); 70 } 71 FontStyle(FontLanguage lang, int variant = 0, int weight = 4, bool italic = false) { 72 bits = (weight & kWeightMask) | (italic ? kItalicMask : 0) 73 | (variant << kVariantShift) | (lang.bits() << kLangShift); 74 } 75 int getWeight() const { return bits & kWeightMask; } 76 bool getItalic() const { return (bits & kItalicMask) != 0; } 77 int getVariant() const { return (bits >> kVariantShift) & kVariantMask; } 78 FontLanguage getLanguage() const { return FontLanguage(bits >> kLangShift); } 79 80 bool operator==(const FontStyle other) const { return bits == other.bits; } 81 82 hash_t hash() const { return bits; } 83 private: 84 static const uint32_t kWeightMask = (1 << 4) - 1; 85 static const uint32_t kItalicMask = 1 << 4; 86 static const int kVariantShift = 5; 87 static const uint32_t kVariantMask = (1 << 2) - 1; 88 static const int kLangShift = 7; 89 uint32_t bits; 90 }; 91 92 enum FontVariant { 93 VARIANT_DEFAULT = 0, 94 VARIANT_COMPACT = 1, 95 VARIANT_ELEGANT = 2, 96 }; 97 98 inline hash_t hash_type(const FontStyle &style) { 99 return style.hash(); 100 } 101 102 // attributes representing transforms (fake bold, fake italic) to match styles 103 class FontFakery { 104 public: 105 FontFakery() : mFakeBold(false), mFakeItalic(false) { } 106 FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) { } 107 // TODO: want to support graded fake bolding 108 bool isFakeBold() { return mFakeBold; } 109 bool isFakeItalic() { return mFakeItalic; } 110 private: 111 bool mFakeBold; 112 bool mFakeItalic; 113 }; 114 115 struct FakedFont { 116 // ownership is the enclosing FontCollection 117 MinikinFont* font; 118 FontFakery fakery; 119 }; 120 121 class FontFamily : public MinikinRefCounted { 122 public: 123 FontFamily() { } 124 125 FontFamily(FontLanguage lang, int variant) : mLang(lang), mVariant(variant) { 126 } 127 128 ~FontFamily(); 129 130 // Add font to family, extracting style information from the font 131 bool addFont(MinikinFont* typeface); 132 133 void addFont(MinikinFont* typeface, FontStyle style); 134 FakedFont getClosestMatch(FontStyle style) const; 135 136 FontLanguage lang() const { return mLang; } 137 int variant() const { return mVariant; } 138 139 // API's for enumerating the fonts in a family. These don't guarantee any particular order 140 size_t getNumFonts() const; 141 MinikinFont* getFont(size_t index) const; 142 FontStyle getStyle(size_t index) const; 143 144 // Get Unicode coverage. Lifetime of returned bitset is same as receiver. 145 const SparseBitSet* getCoverage(); 146 private: 147 void addFontLocked(MinikinFont* typeface, FontStyle style); 148 149 class Font { 150 public: 151 Font(MinikinFont* typeface, FontStyle style) : 152 typeface(typeface), style(style) { } 153 MinikinFont* typeface; 154 FontStyle style; 155 }; 156 FontLanguage mLang; 157 int mVariant; 158 std::vector<Font> mFonts; 159 160 SparseBitSet mCoverage; 161 bool mCoverageValid; 162 }; 163 164 } // namespace android 165 166 #endif // MINIKIN_FONT_FAMILY_H 167