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