Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_FONT_XLFONTCONTROLLER_H_
24 : #define XENOLITH_FONT_XLFONTCONTROLLER_H_
25 :
26 : #include "XLFontConfig.h"
27 : #include "XLEventHeader.h"
28 : #include "XLResourceCache.h"
29 : #include "XLApplicationExtension.h"
30 : #include <shared_mutex>
31 :
32 : namespace STAPPLER_VERSIONIZED stappler::xenolith::font {
33 :
34 : class FontExtension;
35 :
36 : struct FontUpdateRequest {
37 : Rc<FontFaceObject> object;
38 : Vector<char32_t> chars;
39 : bool persistent = false;
40 : };
41 :
42 : class FontController : public ApplicationExtension {
43 : public:
44 : static EventHeader onLoaded;
45 : static EventHeader onFontSourceUpdated;
46 :
47 : struct FontSource {
48 : String fontFilePath;
49 : Bytes fontMemoryData;
50 : BytesView fontExternalData;
51 : Function<Bytes()> fontCallback;
52 : Rc<FontFaceData> data;
53 : FontLayoutParameters params;
54 : bool preconfiguredParams = true;
55 : };
56 :
57 : struct FamilyQuery {
58 : String family;
59 : Vector<const FontSource *> sources;
60 : bool addInFront = false;
61 : };
62 :
63 : struct FamilySpec {
64 : Vector<Rc<FontFaceData>> data;
65 : };
66 :
67 : class Builder {
68 : public:
69 : struct Data;
70 :
71 : ~Builder();
72 :
73 : Builder(StringView);
74 : Builder(FontController *);
75 :
76 : Builder(Builder &&);
77 : Builder &operator=(Builder &&);
78 :
79 : Builder(const Builder &) = delete;
80 : Builder &operator=(const Builder &) = delete;
81 :
82 : StringView getName() const;
83 : FontController *getTarget() const;
84 :
85 : const FontSource * addFontSource(StringView name, BytesView data);
86 : const FontSource * addFontSource(StringView name, Bytes && data);
87 : const FontSource * addFontSource(StringView name, FilePath data);
88 : const FontSource * addFontSource(StringView name, Function<Bytes()> &&cb);
89 :
90 : const FontSource * addFontSource(StringView name, BytesView data, FontLayoutParameters);
91 : const FontSource * addFontSource(StringView name, Bytes && data, FontLayoutParameters);
92 : const FontSource * addFontSource(StringView name, FilePath data, FontLayoutParameters);
93 : const FontSource * addFontSource(StringView name, Function<Bytes()> &&cb, FontLayoutParameters);
94 :
95 : const FontSource *getFontSource(StringView) const;
96 :
97 : const FamilyQuery * addFontFaceQuery(StringView family, const FontSource *, bool front = false);
98 : const FamilyQuery * addFontFaceQuery(StringView family, Vector<const FontSource *> &&, bool front = false);
99 :
100 : bool addAlias(StringView newAlias, StringView familyName);
101 :
102 : Vector<const FamilyQuery *> getFontFamily(StringView family) const;
103 :
104 : Map<String, FontSource> &getDataQueries();
105 : Map<String, FamilyQuery> &getFamilyQueries();
106 : Map<String, String> &getAliases();
107 :
108 : Data *getData() const { return _data; }
109 :
110 : protected:
111 : void addSources(FamilyQuery *, Vector<const FontSource *> &&, bool front);
112 :
113 : Data *_data;
114 : };
115 :
116 : virtual ~FontController();
117 :
118 : bool init(const Rc<FontExtension> &);
119 :
120 : void extend(const Callback<bool(FontController::Builder &)> &);
121 :
122 : virtual void initialize(Application *) override;
123 : virtual void invalidate(Application *) override;
124 :
125 1465 : bool isLoaded() const { return _loaded; }
126 : const Rc<core::DynamicImage> &getImage() const { return _image; }
127 1465 : const Rc<Texture> &getTexture() const { return _texture; }
128 :
129 : Rc<FontFaceSet> getLayout(FontParameters f);
130 : Rc<FontFaceSet> getLayoutForString(const FontParameters &f, const CharVector &);
131 :
132 : Rc<core::DependencyEvent> addTextureChars(const Rc<FontFaceSet> &, SpanView<CharLayoutData>);
133 :
134 : uint32_t getFamilyIndex(StringView) const;
135 : StringView getFamilyName(uint32_t idx) const;
136 :
137 : virtual void update(Application *, const UpdateTime &clock) override;
138 :
139 : protected:
140 : friend class FontExtension;
141 :
142 : void addFont(StringView family, Rc<FontFaceData> &&, bool front = false);
143 : void addFont(StringView family, Vector<Rc<FontFaceData>> &&, bool front = false);
144 :
145 : // replaces previous alias
146 : bool addAlias(StringView newAlias, StringView familyName);
147 :
148 : void setImage(Rc<core::DynamicImage> &&);
149 : void setLoaded(bool);
150 :
151 : void sendFontUpdatedEvent();
152 :
153 : // FontLayout * getFontLayout(const FontParameters &style);
154 :
155 : void setAliases(Map<String, String> &&);
156 :
157 : FontSpecializationVector findSpecialization(const FamilySpec &, const FontParameters &, Vector<Rc<FontFaceData>> *);
158 : void removeUnusedLayouts();
159 :
160 : bool _loaded = false;
161 : std::atomic<uint64_t> _clock;
162 : TimeInterval _unusedInterval = 100_msec;
163 : String _defaultFontFamily = "default";
164 : Rc<Texture> _texture;
165 : Rc<core::DynamicImage> _image;
166 : Rc<FontExtension> _ext;
167 :
168 : Map<String, String> _aliases;
169 : Vector<StringView> _familiesNames;
170 : Map<String, FamilySpec> _families;
171 : HashMap<StringView, Rc<FontFaceSet>> _layouts;
172 : Rc<core::DependencyEvent> _dependency;
173 :
174 : bool _dirty = false;
175 : mutable std::shared_mutex _layoutSharedMutex;
176 : };
177 :
178 : }
179 :
180 : #endif /* XENOLITH_FONT_XLFONTCONTROLLER_H_ */
|