FontFamily.h revision 198b46f1fea3f47ef8eb6317799c0d77aaec52f6
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> 21a5bb91190edbea0be0e78a8511b3c920b6e99c4eBehdad Esfahbod#include <string> 220f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka#include <hb.h> 239cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 244d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien#include <utils/TypeHelpers.h> 254d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 26b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien#include <minikin/MinikinRefCounted.h> 2713f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien#include <minikin/SparseBitSet.h> 28b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien 299cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Leviennamespace android { 309cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 317b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienclass MinikinFont; 327b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 339cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// FontStyle represents all style information needed to select an actual font 346d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka// from a collection. The implementation is packed into two 32-bit words 359cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// so it can be efficiently copied, embedded in other objects, etc. 369cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienclass FontStyle { 379cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienpublic: 386d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle() : FontStyle(0 /* variant */, 4 /* weight */, false /* italic */) {} 396d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(int weight, bool italic) : FontStyle(0 /* variant */, weight, italic) {} 406d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(uint32_t langListId) 416d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka : FontStyle(langListId, 0 /* variant */, 4 /* weight */, false /* italic */) {} 426d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 436d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(int variant, int weight, bool italic); 446d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(uint32_t langListId, int variant, int weight, bool italic); 456d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 464d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien int getWeight() const { return bits & kWeightMask; } 474d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien bool getItalic() const { return (bits & kItalicMask) != 0; } 487b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int getVariant() const { return (bits >> kVariantShift) & kVariantMask; } 496d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka uint32_t getLanguageListId() const { return mLanguageListId; } 507b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 516d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka bool operator==(const FontStyle other) const { 526d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka return bits == other.bits && mLanguageListId == other.mLanguageListId; 536d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka } 546d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 556d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka hash_t hash() const; 564d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 576d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka // Looks up a language list from an internal cache and returns its ID. 586d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka // If the passed language list is not in the cache, registers it and returns newly assigned ID. 596d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka static uint32_t registerLanguageList(const std::string& languages); 609cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 617b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kWeightMask = (1 << 4) - 1; 627b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kItalicMask = 1 << 4; 637b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const int kVariantShift = 5; 647b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kVariantMask = (1 << 2) - 1; 656d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 666d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka static uint32_t pack(int variant, int weight, bool italic); 676d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 689cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien uint32_t bits; 696d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka uint32_t mLanguageListId; 709cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 719cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 727b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienenum FontVariant { 737b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_DEFAULT = 0, 747b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_COMPACT = 1, 757b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_ELEGANT = 2, 767b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien}; 777b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 784d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levieninline hash_t hash_type(const FontStyle &style) { 794d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien return style.hash(); 804d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien} 814d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 829a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien// attributes representing transforms (fake bold, fake italic) to match styles 839a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienclass FontFakery { 849a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienpublic: 859a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FontFakery() : mFakeBold(false), mFakeItalic(false) { } 869a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) { } 879a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien // TODO: want to support graded fake bolding 889a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool isFakeBold() { return mFakeBold; } 899a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool isFakeItalic() { return mFakeItalic; } 909a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienprivate: 919a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool mFakeBold; 929a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool mFakeItalic; 939a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien}; 949a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien 959a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienstruct FakedFont { 969a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien // ownership is the enclosing FontCollection 979a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien MinikinFont* font; 989a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FontFakery fakery; 999a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien}; 1009a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien 101b80c1f19c58b927820a8a24bf2218e5645724608Raph Levienclass FontFamily : public MinikinRefCounted { 1029cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienpublic: 1030f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka FontFamily() : mHbFont(nullptr) { } 1047b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 105198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka FontFamily(int variant); 106198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 107198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka FontFamily(uint32_t langId, int variant) : mLangId(langId), mVariant(variant), mHbFont(nullptr) { 1087b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien } 1097b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 110b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien ~FontFamily(); 111b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien 1129cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // Add font to family, extracting style information from the font 113bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien bool addFont(MinikinFont* typeface); 1149cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 115bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien void addFont(MinikinFont* typeface, FontStyle style); 1169a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FakedFont getClosestMatch(FontStyle style) const; 1179cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 118198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t langId() const { return mLangId; } 1197b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int variant() const { return mVariant; } 1207b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 1219cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // API's for enumerating the fonts in a family. These don't guarantee any particular order 1229cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien size_t getNumFonts() const; 123bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* getFont(size_t index) const; 1249cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle getStyle(size_t index) const; 12513f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien 126cb20a2f0b366bfc16db3a489a60156dec7a9fe21Andreas Gampe // Get Unicode coverage. Lifetime of returned bitset is same as receiver. May return nullptr on 127cb20a2f0b366bfc16db3a489a60156dec7a9fe21Andreas Gampe // error. 12813f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien const SparseBitSet* getCoverage(); 1290f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1300f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Returns true if the font has a glyph for the code point and variation selector pair. 1310f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Caller should acquire a lock before calling the method. 1320f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka bool hasVariationSelector(uint32_t codepoint, uint32_t variationSelector); 1330f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1340f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Purges cached mHbFont. 1350f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // hb_font_t keeps a reference to hb_face_t which is managed by HbFaceCache. Thus, 1360f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // it is good to purge hb_font_t once it is no longer necessary. 1370f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Caller should acquire a lock before calling the method. 1380f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka void purgeHbFontCache(); 1399cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 140c31e3883456e018d742e9f29815ba5ff8b315ea1Raph Levien void addFontLocked(MinikinFont* typeface, FontStyle style); 141c31e3883456e018d742e9f29815ba5ff8b315ea1Raph Levien 1429cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien class Font { 1439cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien public: 144bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien Font(MinikinFont* typeface, FontStyle style) : 1459cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien typeface(typeface), style(style) { } 146bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* typeface; 1479cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle style; 1489cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien }; 149198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t mLangId; 1507b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int mVariant; 1519cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien std::vector<Font> mFonts; 15213f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien 15313f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien SparseBitSet mCoverage; 15413f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien bool mCoverageValid; 1550f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1560f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka hb_font_t* mHbFont; 1579cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 1589cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1599cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} // namespace android 1609cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1619cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#endif // MINIKIN_FONT_FAMILY_H 162