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: 103994aa84f7b18466806fe552ea57da1852b909f24Seigo Nonaka FontFamily(); 1047b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 105198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka FontFamily(int variant); 106198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 1076b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka FontFamily(uint32_t langId, int variant) 1086b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka : mLangId(langId), 1096b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka mVariant(variant), 1106b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka mHasVSTable(false), 1116b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka mCoverageValid(false) { 1127b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien } 1137b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 114b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien ~FontFamily(); 115b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien 1169cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // Add font to family, extracting style information from the font 117bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien bool addFont(MinikinFont* typeface); 1189cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 119bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien void addFont(MinikinFont* typeface, FontStyle style); 1209a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FakedFont getClosestMatch(FontStyle style) const; 1219cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 122198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t langId() const { return mLangId; } 1237b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int variant() const { return mVariant; } 1247b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 1259cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // API's for enumerating the fonts in a family. These don't guarantee any particular order 1269cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien size_t getNumFonts() const; 127bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* getFont(size_t index) const; 1289cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle getStyle(size_t index) const; 129994aa84f7b18466806fe552ea57da1852b909f24Seigo Nonaka bool isColorEmojiFamily() const; 13013f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien 131cb20a2f0b366bfc16db3a489a60156dec7a9fe21Andreas Gampe // Get Unicode coverage. Lifetime of returned bitset is same as receiver. May return nullptr on 132cb20a2f0b366bfc16db3a489a60156dec7a9fe21Andreas Gampe // error. 13313f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien const SparseBitSet* getCoverage(); 1340f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1350f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Returns true if the font has a glyph for the code point and variation selector pair. 1360f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Caller should acquire a lock before calling the method. 137994aa84f7b18466806fe552ea57da1852b909f24Seigo Nonaka bool hasGlyph(uint32_t codepoint, uint32_t variationSelector); 1380f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1396b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka // Returns true if this font family has a variaion sequence table (cmap format 14 subtable). 1406b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka bool hasVSTable() const; 1416b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka 1429cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 143c31e3883456e018d742e9f29815ba5ff8b315ea1Raph Levien void addFontLocked(MinikinFont* typeface, FontStyle style); 144c31e3883456e018d742e9f29815ba5ff8b315ea1Raph Levien 1459cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien class Font { 1469cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien public: 147bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien Font(MinikinFont* typeface, FontStyle style) : 1489cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien typeface(typeface), style(style) { } 149bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien MinikinFont* typeface; 1509cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FontStyle style; 1519cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien }; 152198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t mLangId; 1537b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int mVariant; 1549cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien std::vector<Font> mFonts; 15513f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien 15613f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien SparseBitSet mCoverage; 1576b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka bool mHasVSTable; 15813f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien bool mCoverageValid; 1599cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 1609cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1619cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} // namespace android 1629cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1639cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#endif // MINIKIN_FONT_FAMILY_H 164