Home | History | Annotate | Download | only in minikin
      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 
     29 namespace android {
     30 
     31 class MinikinFont;
     32 
     33 // FontStyle represents all style information needed to select an actual font
     34 // from a collection. The implementation is packed into two 32-bit words
     35 // so it can be efficiently copied, embedded in other objects, etc.
     36 class FontStyle {
     37 public:
     38     FontStyle() : FontStyle(0 /* variant */, 4 /* weight */, false /* italic */) {}
     39     FontStyle(int weight, bool italic) : FontStyle(0 /* variant */, weight, italic) {}
     40     FontStyle(uint32_t langListId)
     41             : FontStyle(langListId, 0 /* variant */, 4 /* weight */, false /* italic */) {}
     42 
     43     FontStyle(int variant, int weight, bool italic);
     44     FontStyle(uint32_t langListId, int variant, int weight, bool italic);
     45 
     46     int getWeight() const { return bits & kWeightMask; }
     47     bool getItalic() const { return (bits & kItalicMask) != 0; }
     48     int getVariant() const { return (bits >> kVariantShift) & kVariantMask; }
     49     uint32_t getLanguageListId() const { return mLanguageListId; }
     50 
     51     bool operator==(const FontStyle other) const {
     52           return bits == other.bits && mLanguageListId == other.mLanguageListId;
     53     }
     54 
     55     hash_t hash() const;
     56 
     57     // Looks up a language list from an internal cache and returns its ID.
     58     // If the passed language list is not in the cache, registers it and returns newly assigned ID.
     59     static uint32_t registerLanguageList(const std::string& languages);
     60 private:
     61     static const uint32_t kWeightMask = (1 << 4) - 1;
     62     static const uint32_t kItalicMask = 1 << 4;
     63     static const int kVariantShift = 5;
     64     static const uint32_t kVariantMask = (1 << 2) - 1;
     65 
     66     static uint32_t pack(int variant, int weight, bool italic);
     67 
     68     uint32_t bits;
     69     uint32_t mLanguageListId;
     70 };
     71 
     72 enum FontVariant {
     73     VARIANT_DEFAULT = 0,
     74     VARIANT_COMPACT = 1,
     75     VARIANT_ELEGANT = 2,
     76 };
     77 
     78 inline hash_t hash_type(const FontStyle &style) {
     79     return style.hash();
     80 }
     81 
     82 // attributes representing transforms (fake bold, fake italic) to match styles
     83 class FontFakery {
     84 public:
     85     FontFakery() : mFakeBold(false), mFakeItalic(false) { }
     86     FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) { }
     87     // TODO: want to support graded fake bolding
     88     bool isFakeBold() { return mFakeBold; }
     89     bool isFakeItalic() { return mFakeItalic; }
     90 private:
     91     bool mFakeBold;
     92     bool mFakeItalic;
     93 };
     94 
     95 struct FakedFont {
     96     // ownership is the enclosing FontCollection
     97     MinikinFont* font;
     98     FontFakery fakery;
     99 };
    100 
    101 class FontFamily : public MinikinRefCounted {
    102 public:
    103     FontFamily();
    104 
    105     FontFamily(int variant);
    106 
    107     FontFamily(uint32_t langId, int variant)
    108         : mLangId(langId),
    109         mVariant(variant),
    110         mHasVSTable(false),
    111         mCoverageValid(false) {
    112     }
    113 
    114     ~FontFamily();
    115 
    116     // Add font to family, extracting style information from the font
    117     bool addFont(MinikinFont* typeface);
    118 
    119     void addFont(MinikinFont* typeface, FontStyle style);
    120     FakedFont getClosestMatch(FontStyle style) const;
    121 
    122     uint32_t langId() const { return mLangId; }
    123     int variant() const { return mVariant; }
    124 
    125     // API's for enumerating the fonts in a family. These don't guarantee any particular order
    126     size_t getNumFonts() const;
    127     MinikinFont* getFont(size_t index) const;
    128     FontStyle getStyle(size_t index) const;
    129     bool isColorEmojiFamily() const;
    130 
    131     // Get Unicode coverage. Lifetime of returned bitset is same as receiver. May return nullptr on
    132     // error.
    133     const SparseBitSet* getCoverage();
    134 
    135     // Returns true if the font has a glyph for the code point and variation selector pair.
    136     // Caller should acquire a lock before calling the method.
    137     bool hasGlyph(uint32_t codepoint, uint32_t variationSelector);
    138 
    139     // Returns true if this font family has a variaion sequence table (cmap format 14 subtable).
    140     bool hasVSTable() const;
    141 
    142 private:
    143     void addFontLocked(MinikinFont* typeface, FontStyle style);
    144 
    145     class Font {
    146     public:
    147         Font(MinikinFont* typeface, FontStyle style) :
    148             typeface(typeface), style(style) { }
    149         MinikinFont* typeface;
    150         FontStyle style;
    151     };
    152     uint32_t mLangId;
    153     int mVariant;
    154     std::vector<Font> mFonts;
    155 
    156     SparseBitSet mCoverage;
    157     bool mHasVSTable;
    158     bool mCoverageValid;
    159 };
    160 
    161 }  // namespace android
    162 
    163 #endif  // MINIKIN_FONT_FAMILY_H
    164