FontFamily.h 5.7 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 <unordered_set>
23
#include <hb.h>
R
Raph Levien 已提交
24

25 26
#include <utils/TypeHelpers.h>

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

S
Seigo Nonaka 已提交
30
namespace minikin {
R
Raph Levien 已提交
31

R
Raph Levien 已提交
32 33
class MinikinFont;

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

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

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

S
Seigo Nonaka 已提交
56
    android::hash_t hash() const;
57

S
Seigo Nonaka 已提交
58 59 60
    // 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 已提交
61
private:
R
Raph Levien 已提交
62 63 64 65
    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 已提交
66 67 68

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

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

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

S
Seigo Nonaka 已提交
79
inline android::hash_t hash_type(const FontStyle &style) {
80 81 82
    return style.hash();
}

R
Raph Levien 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
// 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;
};

102 103
typedef uint32_t AxisTag;

104 105 106 107 108 109 110 111
struct Font {
    Font(MinikinFont* typeface, FontStyle style);
    Font(Font&& o);
    Font(const Font& o);
    ~Font();

    MinikinFont* typeface;
    FontStyle style;
112 113 114 115 116 117 118
    std::unordered_set<AxisTag> supportedAxes;
};

struct FontVariation {
    FontVariation(AxisTag axisTag, float value) : axisTag(axisTag), value(value) {}
    AxisTag axisTag;
    float value;
119 120
};

R
Raph Levien 已提交
121
class FontFamily : public MinikinRefCounted {
R
Raph Levien 已提交
122
public:
123 124 125
    explicit FontFamily(std::vector<Font>&& fonts);
    FontFamily(int variant, std::vector<Font>&& fonts);
    FontFamily(uint32_t langId, int variant, std::vector<Font>&& fonts);
R
Raph Levien 已提交
126

R
Raph Levien 已提交
127 128
    ~FontFamily();

129 130
    // TODO: Good to expose FontUtil.h.
    static bool analyzeStyle(MinikinFont* typeface, int* weight, bool* italic);
R
Raph Levien 已提交
131

R
Raph Levien 已提交
132
    FakedFont getClosestMatch(FontStyle style) const;
R
Raph Levien 已提交
133

134
    uint32_t langId() const { return mLangId; }
R
Raph Levien 已提交
135 136
    int variant() const { return mVariant; }

R
Raph Levien 已提交
137
    // API's for enumerating the fonts in a family. These don't guarantee any particular order
138 139 140
    size_t getNumFonts() const { return mFonts.size(); }
    MinikinFont* getFont(size_t index) const { return mFonts[index].typeface; }
    FontStyle getStyle(size_t index) const { return mFonts[index].style; }
141
    bool isColorEmojiFamily() const;
142
    const std::unordered_set<AxisTag>& supportedAxes() const { return mSupportedAxes; }
143

144 145
    // Get Unicode coverage.
    const SparseBitSet& getCoverage() const { return mCoverage; }
146 147 148

    // 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.
149
    bool hasGlyph(uint32_t codepoint, uint32_t variationSelector) const;
150

151
    // Returns true if this font family has a variaion sequence table (cmap format 14 subtable).
152
    bool hasVSTable() const { return mHasVSTable; }
153

154 155 156 157
    // Creates new FontFamily based on this family while applying font variations. Returns nullptr
    // if none of variations apply to this family.
    FontFamily* createFamilyWithVariation(const std::vector<FontVariation>& variations) const;

R
Raph Levien 已提交
158
private:
159
    void computeCoverage();
160
    uint32_t mLangId;
R
Raph Levien 已提交
161
    int mVariant;
R
Raph Levien 已提交
162
    std::vector<Font> mFonts;
163
    std::unordered_set<AxisTag> mSupportedAxes;
164 165

    SparseBitSet mCoverage;
166
    bool mHasVSTable;
167 168 169 170

    // Forbid copying and assignment.
    FontFamily(const FontFamily&) = delete;
    void operator=(const FontFamily&) = delete;
R
Raph Levien 已提交
171 172
};

S
Seigo Nonaka 已提交
173
}  // namespace minikin
R
Raph Levien 已提交
174 175

#endif  // MINIKIN_FONT_FAMILY_H