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 20dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka#include <memory> 21a5bb91190edbea0be0e78a8511b3c920b6e99c4eBehdad Esfahbod#include <string> 22065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka#include <unordered_set> 23dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka#include <vector> 24dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka 250f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka#include <hb.h> 269cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 274d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien#include <utils/TypeHelpers.h> 284d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 2913f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien#include <minikin/SparseBitSet.h> 30b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien 3114e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonakanamespace minikin { 329cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 337b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienclass MinikinFont; 347b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 359cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// FontStyle represents all style information needed to select an actual font 366d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka// from a collection. The implementation is packed into two 32-bit words 379cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// so it can be efficiently copied, embedded in other objects, etc. 389cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienclass FontStyle { 399cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienpublic: 406d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle() : FontStyle(0 /* variant */, 4 /* weight */, false /* italic */) {} 416d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(int weight, bool italic) : FontStyle(0 /* variant */, weight, italic) {} 4247b905f6840ea6776d6f6778915e7408a1ff8be4Chih-Hung Hsieh FontStyle(uint32_t langListId) // NOLINT(implicit) 436d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka : FontStyle(langListId, 0 /* variant */, 4 /* weight */, false /* italic */) {} 446d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 456d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(int variant, int weight, bool italic); 466d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka FontStyle(uint32_t langListId, int variant, int weight, bool italic); 476d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 484d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien int getWeight() const { return bits & kWeightMask; } 494d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien bool getItalic() const { return (bits & kItalicMask) != 0; } 507b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int getVariant() const { return (bits >> kVariantShift) & kVariantMask; } 516d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka uint32_t getLanguageListId() const { return mLanguageListId; } 527b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 536d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka bool operator==(const FontStyle other) const { 546d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka return bits == other.bits && mLanguageListId == other.mLanguageListId; 556d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka } 566d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 5714e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonaka android::hash_t hash() const; 584d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 596d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka // Looks up a language list from an internal cache and returns its ID. 606d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka // If the passed language list is not in the cache, registers it and returns newly assigned ID. 616d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka static uint32_t registerLanguageList(const std::string& languages); 629cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 637b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kWeightMask = (1 << 4) - 1; 647b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kItalicMask = 1 << 4; 657b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const int kVariantShift = 5; 667b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien static const uint32_t kVariantMask = (1 << 2) - 1; 676d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 686d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka static uint32_t pack(int variant, int weight, bool italic); 696d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka 709cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien uint32_t bits; 716d9dcd2cf3d3ed26a886e02d94c907311e7b1f83Seigo Nonaka uint32_t mLanguageListId; 729cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 739cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 747b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levienenum FontVariant { 757b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_DEFAULT = 0, 767b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_COMPACT = 1, 777b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien VARIANT_ELEGANT = 2, 787b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien}; 797b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 8014e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonakainline android::hash_t hash_type(const FontStyle &style) { 814d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien return style.hash(); 824d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien} 834d4e6bc8118d15542f1f2a9218f0f7a91a29474fRaph Levien 849a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien// attributes representing transforms (fake bold, fake italic) to match styles 859a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienclass FontFakery { 869a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienpublic: 879a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FontFakery() : mFakeBold(false), mFakeItalic(false) { } 889a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) { } 899a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien // TODO: want to support graded fake bolding 909a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool isFakeBold() { return mFakeBold; } 919a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool isFakeItalic() { return mFakeItalic; } 929a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienprivate: 939a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool mFakeBold; 949a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien bool mFakeItalic; 959a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien}; 969a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien 979a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levienstruct FakedFont { 989a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien // ownership is the enclosing FontCollection 999a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien MinikinFont* font; 1009a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FontFakery fakery; 1019a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien}; 1029a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien 103065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonakatypedef uint32_t AxisTag; 104065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka 10541718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonakastruct Font { 106dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka Font(const std::shared_ptr<MinikinFont>& typeface, FontStyle style); 107dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style); 10841718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka Font(Font&& o); 10941718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka Font(const Font& o); 11041718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka 111dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka std::shared_ptr<MinikinFont> typeface; 11241718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka FontStyle style; 11341718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka 1141adbccfd0f40ef416e4f76ea16cbc0bae549d669Seigo Nonaka std::unordered_set<AxisTag> getSupportedAxesLocked() const; 11541718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka}; 11641718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka 117065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonakastruct FontVariation { 118065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka FontVariation(AxisTag axisTag, float value) : axisTag(axisTag), value(value) {} 119065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka AxisTag axisTag; 120065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka float value; 121065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka}; 122065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka 123dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonakaclass FontFamily { 1249cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienpublic: 12541718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka explicit FontFamily(std::vector<Font>&& fonts); 12641718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka FontFamily(int variant, std::vector<Font>&& fonts); 12741718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka FontFamily(uint32_t langId, int variant, std::vector<Font>&& fonts); 1287b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 12941718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka // TODO: Good to expose FontUtil.h. 130dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka static bool analyzeStyle(const std::shared_ptr<MinikinFont>& typeface, int* weight, 131dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka bool* italic); 1329a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien FakedFont getClosestMatch(FontStyle style) const; 1339cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 134198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t langId() const { return mLangId; } 1357b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int variant() const { return mVariant; } 1367b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien 1379cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // API's for enumerating the fonts in a family. These don't guarantee any particular order 13841718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka size_t getNumFonts() const { return mFonts.size(); } 139dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka const std::shared_ptr<MinikinFont>& getFont(size_t index) const { 140dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka return mFonts[index].typeface; 141dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka } 14241718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka FontStyle getStyle(size_t index) const { return mFonts[index].style; } 143994aa84f7b18466806fe552ea57da1852b909f24Seigo Nonaka bool isColorEmojiFamily() const; 144065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka const std::unordered_set<AxisTag>& supportedAxes() const { return mSupportedAxes; } 14513f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien 14641718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka // Get Unicode coverage. 14741718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka const SparseBitSet& getCoverage() const { return mCoverage; } 1480f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1490f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Returns true if the font has a glyph for the code point and variation selector pair. 1500f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka // Caller should acquire a lock before calling the method. 15141718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka bool hasGlyph(uint32_t codepoint, uint32_t variationSelector) const; 1520f2a025d135f9ca52cc3cf917fffc29d6c126094Seigo Nonaka 1536b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka // Returns true if this font family has a variaion sequence table (cmap format 14 subtable). 1549196194d76e4325c5bb0c23f22a5787a717067edSeigo Nonaka bool hasVSTable() const { return !mCmapFmt14Coverage.empty(); } 1556b1c227da6492a435f0341d7fe95d9992669920eSeigo Nonaka 156065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka // Creates new FontFamily based on this family while applying font variations. Returns nullptr 157065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka // if none of variations apply to this family. 158dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka std::shared_ptr<FontFamily> createFamilyWithVariation( 159dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka const std::vector<FontVariation>& variations) const; 160065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka 1619cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienprivate: 16241718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka void computeCoverage(); 1631adbccfd0f40ef416e4f76ea16cbc0bae549d669Seigo Nonaka 164198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t mLangId; 1657b221d97b7b64dc5ce457e19666d55d042e22e62Raph Levien int mVariant; 1669cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien std::vector<Font> mFonts; 167065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka std::unordered_set<AxisTag> mSupportedAxes; 16813f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien 16913f1aae02bacd475722bc8ea3fc2cf6abc1a82e3Raph Levien SparseBitSet mCoverage; 1709196194d76e4325c5bb0c23f22a5787a717067edSeigo Nonaka std::vector<std::unique_ptr<SparseBitSet>> mCmapFmt14Coverage; 17141718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka 17241718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka // Forbid copying and assignment. 17341718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka FontFamily(const FontFamily&) = delete; 17441718c770d0ae12133270a4ee4a8dbd27851480dSeigo Nonaka void operator=(const FontFamily&) = delete; 1759cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien}; 1769cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 17714e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonaka} // namespace minikin 1789cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1799cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#endif // MINIKIN_FONT_FAMILY_H 180