FontFamily.h 5.0 KB
Newer Older
R
Raph Levien 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MINIKIN_FONT_FAMILY_H
#define MINIKIN_FONT_FAMILY_H

#include <vector>
B
Behdad Esfahbod 已提交
21
#include <string>
22
#include <hb.h>
R
Raph Levien 已提交
23

24 25
#include <utils/TypeHelpers.h>

R
Raph Levien 已提交
26
#include <minikin/MinikinRefCounted.h>
27
#include <minikin/SparseBitSet.h>
R
Raph Levien 已提交
28

R
Raph Levien 已提交
29 30
namespace android {

R
Raph Levien 已提交
31 32
class MinikinFont;

R
Raph Levien 已提交
33
// FontStyle represents all style information needed to select an actual font
S
Seigo Nonaka 已提交
34
// from a collection. The implementation is packed into two 32-bit words
R
Raph Levien 已提交
35 36 37
// so it can be efficiently copied, embedded in other objects, etc.
class FontStyle {
public:
S
Seigo Nonaka 已提交
38 39 40 41 42 43 44 45
    FontStyle() : FontStyle(0 /* variant */, 4 /* weight */, false /* italic */) {}
    FontStyle(int weight, bool italic) : FontStyle(0 /* variant */, weight, italic) {}
    FontStyle(uint32_t langListId)
            : FontStyle(langListId, 0 /* variant */, 4 /* weight */, false /* italic */) {}

    FontStyle(int variant, int weight, bool italic);
    FontStyle(uint32_t langListId, int variant, int weight, bool italic);

46 47
    int getWeight() const { return bits & kWeightMask; }
    bool getItalic() const { return (bits & kItalicMask) != 0; }
R
Raph Levien 已提交
48
    int getVariant() const { return (bits >> kVariantShift) & kVariantMask; }
S
Seigo Nonaka 已提交
49
    uint32_t getLanguageListId() const { return mLanguageListId; }
R
Raph Levien 已提交
50

S
Seigo Nonaka 已提交
51 52 53 54 55
    bool operator==(const FontStyle other) const {
          return bits == other.bits && mLanguageListId == other.mLanguageListId;
    }

    hash_t hash() const;
56

S
Seigo Nonaka 已提交
57 58 59
    // Looks up a language list from an internal cache and returns its ID.
    // If the passed language list is not in the cache, registers it and returns newly assigned ID.
    static uint32_t registerLanguageList(const std::string& languages);
R
Raph Levien 已提交
60
private:
R
Raph Levien 已提交
61 62 63 64
    static const uint32_t kWeightMask = (1 << 4) - 1;
    static const uint32_t kItalicMask = 1 << 4;
    static const int kVariantShift = 5;
    static const uint32_t kVariantMask = (1 << 2) - 1;
S
Seigo Nonaka 已提交
65 66 67

    static uint32_t pack(int variant, int weight, bool italic);

R
Raph Levien 已提交
68
    uint32_t bits;
S
Seigo Nonaka 已提交
69
    uint32_t mLanguageListId;
R
Raph Levien 已提交
70 71
};

R
Raph Levien 已提交
72 73 74 75 76 77
enum FontVariant {
    VARIANT_DEFAULT = 0,
    VARIANT_COMPACT = 1,
    VARIANT_ELEGANT = 2,
};

78 79 80 81
inline hash_t hash_type(const FontStyle &style) {
    return style.hash();
}

R
Raph Levien 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
// attributes representing transforms (fake bold, fake italic) to match styles
class FontFakery {
public:
    FontFakery() : mFakeBold(false), mFakeItalic(false) { }
    FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) { }
    // TODO: want to support graded fake bolding
    bool isFakeBold() { return mFakeBold; }
    bool isFakeItalic() { return mFakeItalic; }
private:
    bool mFakeBold;
    bool mFakeItalic;
};

struct FakedFont {
    // ownership is the enclosing FontCollection
    MinikinFont* font;
    FontFakery fakery;
};

R
Raph Levien 已提交
101
class FontFamily : public MinikinRefCounted {
R
Raph Levien 已提交
102
public:
103
    FontFamily() {}
R
Raph Levien 已提交
104

105 106
    FontFamily(int variant);

107 108 109 110 111
    FontFamily(uint32_t langId, int variant)
        : mLangId(langId),
        mVariant(variant),
        mHasVSTable(false),
        mCoverageValid(false) {
R
Raph Levien 已提交
112 113
    }

R
Raph Levien 已提交
114 115
    ~FontFamily();

R
Raph Levien 已提交
116
    // Add font to family, extracting style information from the font
R
Raph Levien 已提交
117
    bool addFont(MinikinFont* typeface);
R
Raph Levien 已提交
118

R
Raph Levien 已提交
119
    void addFont(MinikinFont* typeface, FontStyle style);
R
Raph Levien 已提交
120
    FakedFont getClosestMatch(FontStyle style) const;
R
Raph Levien 已提交
121

122
    uint32_t langId() const { return mLangId; }
R
Raph Levien 已提交
123 124
    int variant() const { return mVariant; }

R
Raph Levien 已提交
125 126
    // API's for enumerating the fonts in a family. These don't guarantee any particular order
    size_t getNumFonts() const;
R
Raph Levien 已提交
127
    MinikinFont* getFont(size_t index) const;
R
Raph Levien 已提交
128
    FontStyle getStyle(size_t index) const;
129

130 131
    // Get Unicode coverage. Lifetime of returned bitset is same as receiver. May return nullptr on
    // error.
132
    const SparseBitSet* getCoverage();
133 134 135 136 137

    // Returns true if the font has a glyph for the code point and variation selector pair.
    // Caller should acquire a lock before calling the method.
    bool hasVariationSelector(uint32_t codepoint, uint32_t variationSelector);

138 139 140
    // Returns true if this font family has a variaion sequence table (cmap format 14 subtable).
    bool hasVSTable() const;

R
Raph Levien 已提交
141
private:
142 143
    void addFontLocked(MinikinFont* typeface, FontStyle style);

R
Raph Levien 已提交
144 145
    class Font {
    public:
R
Raph Levien 已提交
146
        Font(MinikinFont* typeface, FontStyle style) :
R
Raph Levien 已提交
147
            typeface(typeface), style(style) { }
R
Raph Levien 已提交
148
        MinikinFont* typeface;
R
Raph Levien 已提交
149 150
        FontStyle style;
    };
151
    uint32_t mLangId;
R
Raph Levien 已提交
152
    int mVariant;
R
Raph Levien 已提交
153
    std::vector<Font> mFonts;
154 155

    SparseBitSet mCoverage;
156
    bool mHasVSTable;
157
    bool mCoverageValid;
R
Raph Levien 已提交
158 159 160 161 162
};

}  // namespace android

#endif  // MINIKIN_FONT_FAMILY_H