xref: /aosp_15_r20/frameworks/minikin/include/minikin/Font.h (revision 834a2baab5fdfc28e9a428ee87c7ea8f6a06a53d)
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 #include <utils/LruCache.h>
22 
23 #include <atomic>
24 #include <functional>
25 #include <map>
26 #include <memory>
27 #include <mutex>
28 #include <unordered_set>
29 
30 #include "minikin/Buffer.h"
31 #include "minikin/FVarTable.h"
32 #include "minikin/FontFakery.h"
33 #include "minikin/FontStyle.h"
34 #include "minikin/FontVariation.h"
35 #include "minikin/HbUtils.h"
36 #include "minikin/LocaleList.h"
37 #include "minikin/Macros.h"
38 #include "minikin/MinikinFont.h"
39 
40 namespace minikin {
41 
42 // Represents a single font file.
43 class Font {
44 public:
45     class Builder {
46     public:
Builder(const std::shared_ptr<MinikinFont> & typeface)47         Builder(const std::shared_ptr<MinikinFont>& typeface) : mTypeface(typeface) {}
48 
49         // Override the font style. If not called, info from OS/2 table is used.
setStyle(FontStyle style)50         Builder& setStyle(FontStyle style) {
51             mWeight = style.weight();
52             mSlant = style.slant();
53             mIsWeightSet = mIsSlantSet = true;
54             return *this;
55         }
56 
57         // Override the font weight. If not called, info from OS/2 table is used.
setWeight(uint16_t weight)58         Builder& setWeight(uint16_t weight) {
59             mWeight = weight;
60             mIsWeightSet = true;
61             return *this;
62         }
63 
64         // Override the font slant. If not called, info from OS/2 table is used.
setSlant(FontStyle::Slant slant)65         Builder& setSlant(FontStyle::Slant slant) {
66             mSlant = slant;
67             mIsSlantSet = true;
68             return *this;
69         }
70 
setLocaleListId(uint32_t id)71         Builder& setLocaleListId(uint32_t id) {
72             mLocaleListId = id;
73             return *this;
74         }
75 
76         std::shared_ptr<Font> build();
77 
78     private:
79         std::shared_ptr<MinikinFont> mTypeface;
80         uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL);
81         FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT;
82         uint32_t mLocaleListId = kEmptyLocaleListId;
83         bool mIsWeightSet = false;
84         bool mIsSlantSet = false;
85     };
86 
87     explicit Font(BufferReader* reader);
88     void writeTo(BufferWriter* writer) const;
89 
90     // Create font instance with axes override.
91     Font(const std::shared_ptr<Font>& parent, const VariationSettings& axes);
92 
93     Font(Font&& o) noexcept;
94     Font& operator=(Font&& o) noexcept;
95     ~Font();
96     // This locale list is just for API compatibility. This is not used in font selection or family
97     // fallback.
getLocaleListId()98     uint32_t getLocaleListId() const { return mLocaleListId; }
style()99     inline FontStyle style() const { return mStyle; }
100 
101     const HbFontUniquePtr& baseFont() const;
102     const std::shared_ptr<MinikinFont>& baseTypeface() const;
103 
104     // Returns an adjusted hb_font_t instance and MinikinFont instance.
105     // Passing -1 each means do not override the current variation settings.
106     HbFontUniquePtr getAdjustedFont(int wght, int ital) const;
107     std::shared_ptr<MinikinFont> getAdjustedTypeface(int wght, int ital) const;
108 
109     HbFontUniquePtr getAdjustedFont(const VariationSettings& varSettings) const;
110     std::shared_ptr<MinikinFont> getAdjustedTypeface(const VariationSettings& varSettings) const;
111 
typefaceMetadataReader()112     BufferReader typefaceMetadataReader() const { return mTypefaceMetadataReader; }
113 
getSupportedAxesCount()114     uint16_t getSupportedAxesCount() const { return mSupportedAxesCount; }
getSupportedAxes()115     const AxisTag* getSupportedAxes() const { return mSupportedAxes.get(); }
116     bool isAxisSupported(uint32_t tag) const;
117 
118     const FVarTable& getFVarTable() const;
119 
120 private:
121     // ExternalRefs holds references to objects provided by external libraries.
122     // Because creating these external objects is costly,
123     // ExternalRefs is lazily created if Font was created by readFrom().
124     class ExternalRefs {
125     public:
ExternalRefs(std::shared_ptr<MinikinFont> && typeface,HbFontUniquePtr && baseFont)126         ExternalRefs(std::shared_ptr<MinikinFont>&& typeface, HbFontUniquePtr&& baseFont)
127                 : mTypeface(std::move(typeface)),
128                   mBaseFont(std::move(baseFont)),
129                   mVarTypefaceCache2(16),
130                   mVarFontCache2(16) {}
131 
132         std::shared_ptr<MinikinFont> mTypeface;
133         HbFontUniquePtr mBaseFont;
134 
135         // TODO: remove wght/ital only adjusted typeface pool once redesign typeface flag
136         //       is removed.
137         const std::shared_ptr<MinikinFont>& getAdjustedTypeface(int wght, int ital) const;
138         HbFontUniquePtr getAdjustedFont(int wght, int ital) const;
139         mutable std::mutex mMutex;
140         mutable std::map<uint16_t, std::shared_ptr<MinikinFont>> mVarTypefaceCache
141                 GUARDED_BY(mMutex);
142         mutable std::map<uint16_t, HbFontUniquePtr> mVarFontCache GUARDED_BY(mMutex);
143 
144         std::shared_ptr<MinikinFont> getAdjustedTypeface(const VariationSettings& varSettings,
145                                                          const FVarTable& fvarTable) const;
146         HbFontUniquePtr getAdjustedFont(const VariationSettings& varSettings,
147                                         const FVarTable& fvarTable) const;
148         mutable android::LruCache<VariationSettings, std::shared_ptr<MinikinFont>>
149                 mVarTypefaceCache2 GUARDED_BY(mMutex);
150         mutable android::LruCache<VariationSettings, HbFontUniquePtr*> mVarFontCache2
151                 GUARDED_BY(mMutex);
152     };
153 
154     // Use Builder instead.
Font(std::shared_ptr<MinikinFont> && typeface,FontStyle style,HbFontUniquePtr && baseFont,uint32_t localeListId)155     Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont,
156          uint32_t localeListId)
157             : mExternalRefsHolder(new ExternalRefs(std::move(typeface), std::move(baseFont))),
158               mExternalRefsBuilder(nullptr),
159               mStyle(style),
160               mLocaleListId(localeListId),
161               mTypefaceMetadataReader(nullptr) {
162         calculateSupportedAxes();
163     }
164 
165     void resetExternalRefs(ExternalRefs* refs);
166 
167     const ExternalRefs* getExternalRefs() const;
168     std::vector<FontVariation> getAdjustedVariations(int wght, int ital) const;
169 
170     static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface);
171     static FontStyle analyzeStyle(const HbFontUniquePtr& font);
172 
173     // Lazy-initialized if created by readFrom().
174     mutable std::atomic<ExternalRefs*> mExternalRefsHolder;
175     std::function<ExternalRefs*()> mExternalRefsBuilder;
176     FontStyle mStyle;
177     uint32_t mLocaleListId;
178     std::unique_ptr<AxisTag[]> mSupportedAxes;
179     uint16_t mSupportedAxesCount;
180 
181     void calculateSupportedAxes();
182 
183     mutable std::atomic<FVarTable*> mFVarTableHolder;
184 
185     // Non-null if created by readFrom().
186     BufferReader mTypefaceMetadataReader;
187 
188     // Stop copying.
189     Font(const Font& o) = delete;
190     Font& operator=(const Font& o) = delete;
191 
192     FRIEND_TEST(FontTest, MoveConstructorTest);
193     FRIEND_TEST(FontTest, MoveAssignmentTest);
194 };
195 
196 struct FakedFont {
197     inline bool operator==(const FakedFont& o) const {
198         return font == o.font && fakery == o.fakery;
199     }
200     inline bool operator!=(const FakedFont& o) const { return !(*this == o); }
201 
202     HbFontUniquePtr hbFont() const;
203     std::shared_ptr<MinikinFont> typeface() const;
204 
205     // ownership is the enclosing FontCollection
206     // FakedFont will be stored in the LayoutCache. It is not a good idea too keep font instance
207     // even if the enclosing FontCollection, i.e. Typeface is GC-ed. The layout cache is only
208     // purged when it is overflown, thus intentionally keep only reference.
209     const std::shared_ptr<Font>& font;
210     FontFakery fakery;
211 };
212 
213 }  // namespace minikin
214 
215 #endif  // MINIKIN_FONT_H
216