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 <memory>
     21 #include <string>
     22 #include <unordered_set>
     23 #include <vector>
     24 
     25 #include "minikin/FontStyle.h"
     26 #include "minikin/HbUtils.h"
     27 #include "minikin/Macros.h"
     28 #include "minikin/SparseBitSet.h"
     29 
     30 namespace minikin {
     31 
     32 class Font;
     33 class MinikinFont;
     34 
     35 // attributes representing transforms (fake bold, fake italic) to match styles
     36 class FontFakery {
     37 public:
     38     FontFakery() : mFakeBold(false), mFakeItalic(false) {}
     39     FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) {}
     40     // TODO: want to support graded fake bolding
     41     bool isFakeBold() { return mFakeBold; }
     42     bool isFakeItalic() { return mFakeItalic; }
     43 
     44 private:
     45     bool mFakeBold;
     46     bool mFakeItalic;
     47 };
     48 
     49 struct FakedFont {
     50     // ownership is the enclosing FontCollection
     51     const Font* font;
     52     FontFakery fakery;
     53 };
     54 
     55 typedef uint32_t AxisTag;
     56 
     57 // Represents a single font file.
     58 class Font {
     59 public:
     60     class Builder {
     61     public:
     62         Builder(const std::shared_ptr<MinikinFont>& typeface) : mTypeface(typeface) {}
     63 
     64         // Override the font style. If not called, info from OS/2 table is used.
     65         Builder& setStyle(FontStyle style) {
     66             mWeight = style.weight();
     67             mSlant = style.slant();
     68             mIsWeightSet = mIsSlantSet = true;
     69             return *this;
     70         }
     71 
     72         // Override the font weight. If not called, info from OS/2 table is used.
     73         Builder& setWeight(uint16_t weight) {
     74             mWeight = weight;
     75             mIsWeightSet = true;
     76             return *this;
     77         }
     78 
     79         // Override the font slant. If not called, info from OS/2 table is used.
     80         Builder& setSlant(FontStyle::Slant slant) {
     81             mSlant = slant;
     82             mIsSlantSet = true;
     83             return *this;
     84         }
     85 
     86         Font build();
     87 
     88     private:
     89         std::shared_ptr<MinikinFont> mTypeface;
     90         uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL);
     91         FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT;
     92         bool mIsWeightSet = false;
     93         bool mIsSlantSet = false;
     94     };
     95 
     96     Font(Font&& o) = default;
     97     Font& operator=(Font&& o) = default;
     98 
     99     inline const std::shared_ptr<MinikinFont>& typeface() const { return mTypeface; }
    100     inline FontStyle style() const { return mStyle; }
    101     inline const HbFontUniquePtr& baseFont() const { return mBaseFont; }
    102 
    103     std::unordered_set<AxisTag> getSupportedAxes() const;
    104 
    105 private:
    106     // Use Builder instead.
    107     Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont)
    108             : mTypeface(std::move(typeface)), mStyle(style), mBaseFont(std::move(baseFont)) {}
    109 
    110     static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface);
    111     static FontStyle analyzeStyle(const HbFontUniquePtr& font);
    112 
    113     std::shared_ptr<MinikinFont> mTypeface;
    114     FontStyle mStyle;
    115     HbFontUniquePtr mBaseFont;
    116 
    117     MINIKIN_PREVENT_COPY_AND_ASSIGN(Font);
    118 };
    119 
    120 struct FontVariation {
    121     FontVariation(AxisTag axisTag, float value) : axisTag(axisTag), value(value) {}
    122     AxisTag axisTag;
    123     float value;
    124 };
    125 
    126 class FontFamily {
    127 public:
    128     // Must be the same value as FontConfig.java
    129     enum class Variant : uint8_t {
    130         DEFAULT = 0,  // Must be the same as FontConfig.VARIANT_DEFAULT
    131         COMPACT = 1,  // Must be the same as FontConfig.VARIANT_COMPACT
    132         ELEGANT = 2,  // Must be the same as FontConfig.VARIANT_ELEGANT
    133     };
    134 
    135     explicit FontFamily(std::vector<Font>&& fonts);
    136     FontFamily(Variant variant, std::vector<Font>&& fonts);
    137     FontFamily(uint32_t localeListId, Variant variant, std::vector<Font>&& fonts);
    138 
    139     FakedFont getClosestMatch(FontStyle style) const;
    140 
    141     uint32_t localeListId() const { return mLocaleListId; }
    142     Variant variant() const { return mVariant; }
    143 
    144     // API's for enumerating the fonts in a family. These don't guarantee any particular order
    145     size_t getNumFonts() const { return mFonts.size(); }
    146     const Font* getFont(size_t index) const { return &mFonts[index]; }
    147     FontStyle getStyle(size_t index) const { return mFonts[index].style(); }
    148     bool isColorEmojiFamily() const { return mIsColorEmoji; }
    149     const std::unordered_set<AxisTag>& supportedAxes() const { return mSupportedAxes; }
    150 
    151     // Get Unicode coverage.
    152     const SparseBitSet& getCoverage() const { return mCoverage; }
    153 
    154     // Returns true if the font has a glyph for the code point and variation selector pair.
    155     // Caller should acquire a lock before calling the method.
    156     bool hasGlyph(uint32_t codepoint, uint32_t variationSelector) const;
    157 
    158     // Returns true if this font family has a variaion sequence table (cmap format 14 subtable).
    159     bool hasVSTable() const { return !mCmapFmt14Coverage.empty(); }
    160 
    161     // Creates new FontFamily based on this family while applying font variations. Returns nullptr
    162     // if none of variations apply to this family.
    163     std::shared_ptr<FontFamily> createFamilyWithVariation(
    164             const std::vector<FontVariation>& variations) const;
    165 
    166 private:
    167     void computeCoverage();
    168 
    169     uint32_t mLocaleListId;
    170     Variant mVariant;
    171     std::vector<Font> mFonts;
    172     std::unordered_set<AxisTag> mSupportedAxes;
    173     bool mIsColorEmoji;
    174 
    175     SparseBitSet mCoverage;
    176     std::vector<std::unique_ptr<SparseBitSet>> mCmapFmt14Coverage;
    177 
    178     MINIKIN_PREVENT_COPY_AND_ASSIGN(FontFamily);
    179 };
    180 
    181 }  // namespace minikin
    182 
    183 #endif  // MINIKIN_FONT_FAMILY_H
    184