• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest_prod.h>
21 
22 #include <atomic>
23 #include <memory>
24 #include <unordered_set>
25 
26 #include "minikin/Buffer.h"
27 #include "minikin/FontStyle.h"
28 #include "minikin/FontVariation.h"
29 #include "minikin/HbUtils.h"
30 #include "minikin/LocaleList.h"
31 #include "minikin/Macros.h"
32 #include "minikin/MinikinFont.h"
33 
34 namespace minikin {
35 
36 class Font;
37 
38 // attributes representing transforms (fake bold, fake italic) to match styles
39 class FontFakery {
40 public:
FontFakery()41     FontFakery() : mFakeBold(false), mFakeItalic(false) {}
FontFakery(bool fakeBold,bool fakeItalic)42     FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) {}
43     // TODO: want to support graded fake bolding
isFakeBold()44     bool isFakeBold() { return mFakeBold; }
isFakeItalic()45     bool isFakeItalic() { return mFakeItalic; }
46     inline bool operator==(const FontFakery& o) const {
47         return mFakeBold == o.mFakeBold && mFakeItalic == o.mFakeItalic;
48     }
49     inline bool operator!=(const FontFakery& o) const { return !(*this == o); }
50 
51 private:
52     bool mFakeBold;
53     bool mFakeItalic;
54 };
55 
56 struct FakedFont {
57     inline bool operator==(const FakedFont& o) const {
58         return font == o.font && fakery == o.fakery;
59     }
60     inline bool operator!=(const FakedFont& o) const { return !(*this == o); }
61 
62     // ownership is the enclosing FontCollection
63     // FakedFont will be stored in the LayoutCache. It is not a good idea too keep font instance
64     // even if the enclosing FontCollection, i.e. Typeface is GC-ed. The layout cache is only
65     // purged when it is overflown, thus intentionally keep only reference.
66     const std::shared_ptr<Font>& font;
67     FontFakery fakery;
68 };
69 
70 // Represents a single font file.
71 class Font {
72 public:
73     class Builder {
74     public:
Builder(const std::shared_ptr<MinikinFont> & typeface)75         Builder(const std::shared_ptr<MinikinFont>& typeface) : mTypeface(typeface) {}
76 
77         // Override the font style. If not called, info from OS/2 table is used.
setStyle(FontStyle style)78         Builder& setStyle(FontStyle style) {
79             mWeight = style.weight();
80             mSlant = style.slant();
81             mIsWeightSet = mIsSlantSet = true;
82             return *this;
83         }
84 
85         // Override the font weight. If not called, info from OS/2 table is used.
setWeight(uint16_t weight)86         Builder& setWeight(uint16_t weight) {
87             mWeight = weight;
88             mIsWeightSet = true;
89             return *this;
90         }
91 
92         // Override the font slant. If not called, info from OS/2 table is used.
setSlant(FontStyle::Slant slant)93         Builder& setSlant(FontStyle::Slant slant) {
94             mSlant = slant;
95             mIsSlantSet = true;
96             return *this;
97         }
98 
setLocaleListId(uint32_t id)99         Builder& setLocaleListId(uint32_t id) {
100             mLocaleListId = id;
101             return *this;
102         }
103 
104         std::shared_ptr<Font> build();
105 
106     private:
107         std::shared_ptr<MinikinFont> mTypeface;
108         uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL);
109         FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT;
110         uint32_t mLocaleListId = kEmptyLocaleListId;
111         bool mIsWeightSet = false;
112         bool mIsSlantSet = false;
113     };
114 
115     explicit Font(BufferReader* reader);
116     void writeTo(BufferWriter* writer) const;
117 
118     Font(Font&& o) noexcept;
119     Font& operator=(Font&& o) noexcept;
120     ~Font();
121     // This locale list is just for API compatibility. This is not used in font selection or family
122     // fallback.
getLocaleListId()123     uint32_t getLocaleListId() const { return mLocaleListId; }
124     const std::shared_ptr<MinikinFont>& typeface() const;
style()125     inline FontStyle style() const { return mStyle; }
126     const HbFontUniquePtr& baseFont() const;
typefaceMetadataReader()127     BufferReader typefaceMetadataReader() const { return mTypefaceMetadataReader; }
128 
129     std::unordered_set<AxisTag> getSupportedAxes() const;
130 
131 private:
132     // ExternalRefs holds references to objects provided by external libraries.
133     // Because creating these external objects is costly,
134     // ExternalRefs is lazily created if Font was created by readFrom().
135     class ExternalRefs {
136     public:
ExternalRefs(std::shared_ptr<MinikinFont> && typeface,HbFontUniquePtr && baseFont)137         ExternalRefs(std::shared_ptr<MinikinFont>&& typeface, HbFontUniquePtr&& baseFont)
138                 : mTypeface(std::move(typeface)), mBaseFont(std::move(baseFont)) {}
139 
140         std::shared_ptr<MinikinFont> mTypeface;
141         HbFontUniquePtr mBaseFont;
142     };
143 
144     // Use Builder instead.
Font(std::shared_ptr<MinikinFont> && typeface,FontStyle style,HbFontUniquePtr && baseFont,uint32_t localeListId)145     Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont,
146          uint32_t localeListId)
147             : mExternalRefsHolder(new ExternalRefs(std::move(typeface), std::move(baseFont))),
148               mStyle(style),
149               mLocaleListId(localeListId),
150               mTypefaceMetadataReader(nullptr) {}
151 
152     void resetExternalRefs(ExternalRefs* refs);
153 
154     const ExternalRefs* getExternalRefs() const;
155 
156     static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface);
157     static FontStyle analyzeStyle(const HbFontUniquePtr& font);
158 
159     // Lazy-initialized if created by readFrom().
160     mutable std::atomic<ExternalRefs*> mExternalRefsHolder;
161     FontStyle mStyle;
162     uint32_t mLocaleListId;
163 
164     // Non-null if created by readFrom().
165     BufferReader mTypefaceMetadataReader;
166 
167     // Stop copying.
168     Font(const Font& o) = delete;
169     Font& operator=(const Font& o) = delete;
170 
171     FRIEND_TEST(FontTest, MoveConstructorTest);
172     FRIEND_TEST(FontTest, MoveAssignmentTest);
173 };
174 
175 }  // namespace minikin
176 
177 #endif  // MINIKIN_FONT_H
178