FontFamily.h revision 7b221d97b7b64dc5ce457e19666d55d042e22e62
19cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien/* 29cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * Copyright (C) 2013 The Android Open Source Project 39cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * 49cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 59cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * you may not use this file except in compliance with the License. 69cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * You may obtain a copy of the License at 79cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * 89cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * http://www.apache.org/licenses/LICENSE-2.0 99cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * 109cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * Unless required by applicable law or agreed to in writing, software 119cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * distributed under the License is distributed on an "AS IS" BASIS, 129cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * See the License for the specific language governing permissions and 149cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien * limitations under the License. 159cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien */ 169cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 179cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#ifndef MINIKIN_FONT_FAMILY_H 189cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#define MINIKIN_FONT_FAMILY_H 199cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 209cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include <vector> 219cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 224d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien#include <utils/TypeHelpers.h> 234d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 24b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien#include <minikin/MinikinRefCounted.h> 25b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien 269cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Leviennamespace android { 279cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 287b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienclass MinikinFont; 297b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 307b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien// FontLanguage is a compact representation of a bcp-47 language tag. It 317b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien// does not capture all possible information, only what directly affects 327b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien// font rendering. 337b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienclass FontLanguage { 347b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien friend class FontStyle; 357b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienpublic: 367b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontLanguage() : mBits(0) { } 377b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 387b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien // Parse from string 397b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontLanguage(const char* buf, size_t size); 407b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 417b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien bool operator==(const FontLanguage other) const { return mBits == other.mBits; } 427b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 437b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien // 0 = no match, 1 = language matches, 2 = language and script match 447b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int match(const FontLanguage other) const; 457b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 467b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienprivate: 477b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien explicit FontLanguage(uint32_t bits) : mBits(bits) { } 487b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 497b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien uint32_t bits() const { return mBits; } 507b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 517b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kBaseLangMask = 0xffff; 527b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kScriptMask = (1 << 18) - (1 << 16); 537b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kHansFlag = 1 << 16; 547b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kHantFlag = 1 << 17; 557b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien uint32_t mBits; 567b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien}; 577b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 589cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// FontStyle represents all style information needed to select an actual font 599cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// from a collection. The implementation is packed into a single 32-bit word 609cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// so it can be efficiently copied, embedded in other objects, etc. 619cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienclass FontStyle { 629cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienpublic: 639cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle(int weight = 4, bool italic = false) { 649cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien bits = (weight & kWeightMask) | (italic ? kItalicMask : 0); 659cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien } 667b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontStyle(FontLanguage lang, int variant = 0, int weight = 4, bool italic = false) { 677b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien bits = (weight & kWeightMask) | (italic ? kItalicMask : 0) 687b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien | (variant << kVariantShift) | (lang.bits() << kLangShift); 697b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien } 704d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien int getWeight() const { return bits & kWeightMask; } 714d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien bool getItalic() const { return (bits & kItalicMask) != 0; } 727b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int getVariant() const { return (bits >> kVariantShift) & kVariantMask; } 737b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontLanguage getLanguage() const { return FontLanguage(bits >> kLangShift); } 747b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 754d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien bool operator==(const FontStyle other) const { return bits == other.bits; } 764d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 774d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien hash_t hash() const { return bits; } 789cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 797b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kWeightMask = (1 << 4) - 1; 807b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kItalicMask = 1 << 4; 817b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const int kVariantShift = 5; 827b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kVariantMask = (1 << 2) - 1; 837b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const int kLangShift = 7; 849cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien uint32_t bits; 859cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 869cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 877b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienenum FontVariant { 887b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_DEFAULT = 0, 897b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_COMPACT = 1, 907b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_ELEGANT = 2, 917b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien}; 927b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 934d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levieninline hash_t hash_type(const FontStyle &style) { 944d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien return style.hash(); 954d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien} 964d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 97b80c1f19c58b927820a8a24bf2218e5645724608Raph Levienclass FontFamily : public MinikinRefCounted { 989cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienpublic: 997b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontFamily() { } 1007b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 1017b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontFamily(FontLanguage lang, int variant) : mLang(lang), mVariant(variant) { 1027b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien } 1037b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 104b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien ~FontFamily(); 105b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien 1069cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // Add font to family, extracting style information from the font 107bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien bool addFont(MinikinFont* typeface); 1089cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 109bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien void addFont(MinikinFont* typeface, FontStyle style); 110bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* getClosestMatch(FontStyle style) const; 1119cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1127b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontLanguage lang() const { return mLang; } 1137b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int variant() const { return mVariant; } 1147b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 1159cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // API's for enumerating the fonts in a family. These don't guarantee any particular order 1169cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien size_t getNumFonts() const; 117bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* getFont(size_t index) const; 1189cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle getStyle(size_t index) const; 1199cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 120c31e3883456e018d742e9f29815ba5ff8b315ea1Raph Levien void addFontLocked(MinikinFont* typeface, FontStyle style); 121c31e3883456e018d742e9f29815ba5ff8b315ea1Raph Levien 1229cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien class Font { 1239cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien public: 124bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien Font(MinikinFont* typeface, FontStyle style) : 1259cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien typeface(typeface), style(style) { } 126bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* typeface; 1279cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle style; 1289cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien }; 1297b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien FontLanguage mLang; 1307b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int mVariant; 1319cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien std::vector<Font> mFonts; 1329cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 1339cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1349cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} // namespace android 1359cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1369cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#endif // MINIKIN_FONT_FAMILY_H 137