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