1 /*
2  * Copyright (C) 2018 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_H
18 #define MINIKIN_FONT_H
19 
20 #include <memory>
21 #include <unordered_set>
22 
23 #include "minikin/FontStyle.h"
24 #include "minikin/FontVariation.h"
25 #include "minikin/HbUtils.h"
26 #include "minikin/Macros.h"
27 #include "minikin/MinikinFont.h"
28 
29 namespace minikin {
30 
31 class Font;
32 
33 // attributes representing transforms (fake bold, fake italic) to match styles
34 class FontFakery {
35 public:
FontFakery()36     FontFakery() : mFakeBold(false), mFakeItalic(false) {}
FontFakery(bool fakeBold,bool fakeItalic)37     FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) {}
38     // TODO: want to support graded fake bolding
isFakeBold()39     bool isFakeBold() { return mFakeBold; }
isFakeItalic()40     bool isFakeItalic() { return mFakeItalic; }
41     inline bool operator==(const FontFakery& o) const {
42         return mFakeBold == o.mFakeBold && mFakeItalic == o.mFakeItalic;
43     }
44     inline bool operator!=(const FontFakery& o) const { return !(*this == o); }
45 
46 private:
47     bool mFakeBold;
48     bool mFakeItalic;
49 };
50 
51 struct FakedFont {
52     inline bool operator==(const FakedFont& o) const {
53         return font == o.font && fakery == o.fakery;
54     }
55     inline bool operator!=(const FakedFont& o) const { return !(*this == o); }
56 
57     // ownership is the enclosing FontCollection
58     const Font* font;
59     FontFakery fakery;
60 };
61 
62 // Represents a single font file.
63 class Font {
64 public:
65     class Builder {
66     public:
Builder(const std::shared_ptr<MinikinFont> & typeface)67         Builder(const std::shared_ptr<MinikinFont>& typeface) : mTypeface(typeface) {}
68 
69         // Override the font style. If not called, info from OS/2 table is used.
setStyle(FontStyle style)70         Builder& setStyle(FontStyle style) {
71             mWeight = style.weight();
72             mSlant = style.slant();
73             mIsWeightSet = mIsSlantSet = true;
74             return *this;
75         }
76 
77         // Override the font weight. If not called, info from OS/2 table is used.
setWeight(uint16_t weight)78         Builder& setWeight(uint16_t weight) {
79             mWeight = weight;
80             mIsWeightSet = true;
81             return *this;
82         }
83 
84         // Override the font slant. If not called, info from OS/2 table is used.
setSlant(FontStyle::Slant slant)85         Builder& setSlant(FontStyle::Slant slant) {
86             mSlant = slant;
87             mIsSlantSet = true;
88             return *this;
89         }
90 
91         Font build();
92 
93     private:
94         std::shared_ptr<MinikinFont> mTypeface;
95         uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL);
96         FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT;
97         bool mIsWeightSet = false;
98         bool mIsSlantSet = false;
99     };
100 
101     Font(Font&& o) = default;
102     Font& operator=(Font&& o) = default;
103 
104     Font& operator=(const Font& o) {
105         mTypeface = o.mTypeface;
106         mStyle = o.mStyle;
107         mBaseFont = HbFontUniquePtr(hb_font_reference(o.mBaseFont.get()));
108         return *this;
109     }
Font(const Font & o)110     Font(const Font& o) { *this = o; }
111 
typeface()112     inline const std::shared_ptr<MinikinFont>& typeface() const { return mTypeface; }
style()113     inline FontStyle style() const { return mStyle; }
baseFont()114     inline const HbFontUniquePtr& baseFont() const { return mBaseFont; }
115 
116     std::unordered_set<AxisTag> getSupportedAxes() const;
117 
118 private:
119     // Use Builder instead.
Font(std::shared_ptr<MinikinFont> && typeface,FontStyle style,HbFontUniquePtr && baseFont)120     Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont)
121             : mTypeface(std::move(typeface)), mStyle(style), mBaseFont(std::move(baseFont)) {}
122 
123     static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface);
124     static FontStyle analyzeStyle(const HbFontUniquePtr& font);
125 
126     std::shared_ptr<MinikinFont> mTypeface;
127     FontStyle mStyle;
128     HbFontUniquePtr mBaseFont;
129 };
130 
131 }  // namespace minikin
132 
133 #endif  // MINIKIN_FONT_H
134