Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023-2024 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef CORE_FONT_SPFONTSTYLE_H_
25 : #define CORE_FONT_SPFONTSTYLE_H_
26 :
27 : #include "SPFont.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::font {
30 :
31 : using EnumSize = uint8_t;
32 :
33 : enum class FontVariableAxis {
34 : None,
35 : Weight = 1 << 0, // wght
36 : Width = 1 << 1, // wdth
37 : Italic = 1 << 2, // ital
38 : Slant = 1 << 3, // slnt
39 : OpticalSize = 1 << 4, // opsz
40 : Grade = 1 << 5, // GRAD
41 :
42 : Stretch = Width,
43 : };
44 :
45 : SP_DEFINE_ENUM_AS_MASK(FontVariableAxis)
46 :
47 : enum class Autofit : EnumSize {
48 : None,
49 : Width,
50 : Height,
51 : Cover,
52 : Contain,
53 : };
54 :
55 : enum class TextTransform : EnumSize {
56 : None,
57 : Uppercase,
58 : Lowercase,
59 : };
60 :
61 : enum class TextDecoration : EnumSize {
62 : None,
63 : LineThrough,
64 : Overline,
65 : Underline,
66 : };
67 :
68 : enum class TextAlign : EnumSize {
69 : Left,
70 : Center,
71 : Right,
72 : Justify,
73 : };
74 :
75 : enum class WhiteSpace : EnumSize {
76 : Normal,
77 : Nowrap,
78 : Pre,
79 : PreLine,
80 : PreWrap,
81 : };
82 :
83 : enum class Hyphens : EnumSize {
84 : None,
85 : Manual,
86 : Auto,
87 : };
88 :
89 : enum class VerticalAlign : EnumSize {
90 : Baseline,
91 : Middle,
92 : Sub,
93 : Super,
94 : Top,
95 : Bottom
96 : };
97 :
98 : // slnt axis or special value for Italic
99 : struct FontStyle : ValueWrapper<int16_t, class FontStyleFlag> {
100 : static const FontStyle Normal;
101 : static const FontStyle Italic;
102 : static const FontStyle Oblique;
103 :
104 64 : static constexpr FontStyle FromDegrees(float d) {
105 64 : return FontStyle(std::floor(d * 64.0f));
106 : }
107 :
108 : using ValueWrapper::ValueWrapper;
109 : };
110 :
111 : struct FontWeight : ValueWrapper<uint16_t, class FontWeightFlag> {
112 : static const FontWeight Thin;
113 : static const FontWeight ExtraLight;
114 : static const FontWeight Light;
115 : static const FontWeight Normal;
116 : static const FontWeight Regular;
117 : static const FontWeight Medium;
118 : static const FontWeight SemiBold;
119 : static const FontWeight Bold;
120 : static const FontWeight ExtraBold;
121 : static const FontWeight Heavy;
122 : static const FontWeight Black;
123 :
124 : using ValueWrapper::ValueWrapper;
125 : };
126 :
127 : struct FontStretch : ValueWrapper<uint16_t, class FontStretchFlag> {
128 : static const FontStretch UltraCondensed;
129 : static const FontStretch ExtraCondensed;
130 : static const FontStretch Condensed;
131 : static const FontStretch SemiCondensed;
132 : static const FontStretch Normal;
133 : static const FontStretch SemiExpanded;
134 : static const FontStretch Expanded;
135 : static const FontStretch ExtraExpanded;
136 : static const FontStretch UltraExpanded;
137 :
138 : using ValueWrapper::ValueWrapper;
139 : };
140 :
141 : struct FontGrade : ValueWrapper<int16_t, class FontGradeFlag> {
142 : static const FontGrade Thin;
143 : static const FontGrade Reduced;
144 : static const FontGrade Normal;
145 : static const FontGrade Heavy;
146 :
147 : using ValueWrapper::ValueWrapper;
148 : };
149 :
150 : enum class FontVariant : EnumSize {
151 : Normal,
152 : SmallCaps,
153 : };
154 :
155 : enum class ListStyleType : EnumSize {
156 : None,
157 : Circle,
158 : Disc,
159 : Square,
160 : XMdash,
161 : Decimal,
162 : DecimalLeadingZero,
163 : LowerAlpha,
164 : LowerGreek,
165 : LowerRoman,
166 : UpperAlpha,
167 : UpperRoman
168 : };
169 :
170 : struct FontSize {
171 : static const FontSize XXSmall;
172 : static const FontSize XSmall;
173 : static const FontSize Small;
174 : static const FontSize Medium;
175 : static const FontSize Large;
176 : static const FontSize XLarge;
177 : static const FontSize XXLarge;
178 :
179 160 : static FontSize progress(FontSize source, FontSize target, float p) {
180 160 : auto v = source.val() * (1.0f - p) + target.val() * p;
181 160 : return make(v);
182 : }
183 :
184 13204 : static constexpr FontSize make(float v) {
185 13204 : FontSize ret;
186 13204 : ret.value = static_cast<uint16_t>(std::floor(v * 16.0f));
187 13204 : return ret;
188 : }
189 :
190 10 : inline constexpr FontSize() = default;
191 : inline constexpr FontSize(const FontSize &) = default;
192 :
193 2212 : inline explicit constexpr FontSize(uint16_t val) : value(val << 4) { }
194 :
195 15305 : constexpr FontSize scale(float density) const { return FontSize::make(val() * density); }
196 :
197 10559 : constexpr FontSize operator*(float v) const { return scale(v); }
198 0 : constexpr FontSize operator/(float v) const { return scale(1.0f / v); }
199 :
200 30383 : constexpr uint16_t get() const { return value >> 4; }
201 13364 : constexpr float val() const { return static_cast<float>(value) / 16.0f; }
202 :
203 0 : constexpr FontSize &operator-=(FontSize v) { value -= v.value; return *this; }
204 :
205 260 : constexpr bool operator==(const FontSize &) const = default;
206 : constexpr bool operator!=(const FontSize &) const = default;
207 :
208 260 : uint16_t value = 0;
209 : };
210 :
211 : struct TextParameters {
212 260 : TextTransform textTransform = TextTransform::None;
213 260 : TextDecoration textDecoration = TextDecoration::None;
214 260 : WhiteSpace whiteSpace = WhiteSpace::Normal;
215 260 : Hyphens hyphens = Hyphens::Manual;
216 260 : VerticalAlign verticalAlign = VerticalAlign::Baseline;
217 260 : geom::Color3B color = geom::Color3B::BLACK;
218 260 : uint8_t opacity = 222;
219 :
220 260 : inline bool operator == (const TextParameters &other) const = default;
221 : inline bool operator != (const TextParameters &other) const = default;
222 : };
223 :
224 : struct FontLayoutParameters {
225 : FontStyle fontStyle = FontStyle::Normal;
226 : FontWeight fontWeight = FontWeight::Normal;
227 : FontStretch fontStretch = FontStretch::Normal;
228 : FontGrade fontGrade = FontGrade::Normal;
229 :
230 260 : inline bool operator == (const FontLayoutParameters &other) const = default;
231 : inline bool operator != (const FontLayoutParameters &other) const = default;
232 : };
233 :
234 260 : struct FontSpecializationVector : FontLayoutParameters {
235 260 : FontSize fontSize = FontSize(14);
236 260 : float density = 1.0f;
237 :
238 : template <typename Interface>
239 : auto getSpecializationArgs() const -> typename Interface::StringType;
240 :
241 260 : inline bool operator == (const FontSpecializationVector &other) const = default;
242 : inline bool operator != (const FontSpecializationVector &other) const = default;
243 : };
244 :
245 260 : struct FontParameters : FontSpecializationVector {
246 : static FontParameters create(StringView, memory::pool_t * = nullptr);
247 :
248 : template <typename Interface>
249 : static auto getFontConfigName(StringView fontFamily, FontSize fontSize, FontStyle fontStyle, FontWeight fontWeight,
250 : FontStretch fontStretch, FontGrade fontGrade, FontVariant fontVariant, bool caps) -> typename Interface::StringType;
251 :
252 260 : FontVariant fontVariant = FontVariant::Normal;
253 260 : ListStyleType listStyleType = ListStyleType::None;
254 260 : StringView fontFamily;
255 260 : bool persistent = false;
256 :
257 : template <typename Interface>
258 130 : auto getConfigName(bool caps = false) const -> typename Interface::StringType {
259 130 : return getFontConfigName<Interface>(fontFamily, fontSize, fontStyle, fontWeight, fontStretch, fontGrade, fontVariant, caps);
260 : }
261 :
262 : FontParameters getSmallCaps() const;
263 :
264 260 : inline bool operator == (const FontParameters &other) const = default;
265 : inline bool operator != (const FontParameters &other) const = default;
266 : };
267 :
268 : struct FontVariations {
269 : template <typename T>
270 : struct Variations {
271 : T min;
272 : T max;
273 :
274 1200 : Variations &operator=(const T &v) {
275 1200 : min = v;
276 1200 : max = v;
277 1200 : return *this;
278 : }
279 :
280 36969 : T clamp(T val) const {
281 36969 : return math::clamp(val, min, max);
282 : }
283 : };
284 :
285 : FontVariableAxis axisMask = FontVariableAxis::None;
286 : Variations<FontWeight> weight = Variations<FontWeight>{FontWeight::Normal, FontWeight::Normal};
287 : Variations<FontStretch> stretch = Variations<FontStretch>{FontStretch::Normal, FontStretch::Normal};
288 : Variations<FontStyle> slant = Variations<FontStyle>{FontStyle::Normal, FontStyle::Normal};
289 : Variations<uint32_t> opticalSize = Variations<uint32_t>{0, 0};
290 : Variations<uint32_t> italic = Variations<uint32_t>{0, 0};
291 : Variations<FontGrade> grade = Variations<FontGrade>{FontGrade::Normal, FontGrade::Normal};
292 :
293 : FontSpecializationVector getSpecialization(const FontSpecializationVector &vec) const;
294 : };
295 :
296 : #ifndef __LCC__
297 :
298 : constexpr FontStretch FontStretch::UltraCondensed = FontStretch(50 << 1);
299 : constexpr FontStretch FontStretch::ExtraCondensed = FontStretch((62 << 1) | 1);
300 : constexpr FontStretch FontStretch::Condensed = FontStretch(75 << 1);
301 : constexpr FontStretch FontStretch::SemiCondensed = FontStretch((87 << 1) | 1);
302 : constexpr FontStretch FontStretch::Normal = FontStretch(100 << 1);
303 : constexpr FontStretch FontStretch::SemiExpanded = FontStretch((112 << 1) | 1);
304 : constexpr FontStretch FontStretch::Expanded = FontStretch(125 << 1);
305 : constexpr FontStretch FontStretch::ExtraExpanded = FontStretch(150 << 1);
306 : constexpr FontStretch FontStretch::UltraExpanded = FontStretch(200 << 1);
307 :
308 : constexpr FontWeight FontWeight::Thin = FontWeight(100);
309 : constexpr FontWeight FontWeight::ExtraLight = FontWeight(200);
310 : constexpr FontWeight FontWeight::Light = FontWeight(300);
311 : constexpr FontWeight FontWeight::Normal = FontWeight(400);
312 : constexpr FontWeight FontWeight::Regular = FontWeight(400);
313 : constexpr FontWeight FontWeight::Medium = FontWeight(500);
314 : constexpr FontWeight FontWeight::SemiBold = FontWeight(600);
315 : constexpr FontWeight FontWeight::Bold = FontWeight(700);
316 : constexpr FontWeight FontWeight::ExtraBold = FontWeight(800);
317 : constexpr FontWeight FontWeight::Heavy = FontWeight(900);
318 : constexpr FontWeight FontWeight::Black = FontWeight(1000);
319 :
320 : constexpr FontSize FontSize::XXSmall = FontSize(uint16_t(8));
321 : constexpr FontSize FontSize::XSmall = FontSize(uint16_t(10));
322 : constexpr FontSize FontSize::Small = FontSize(uint16_t(12));
323 : constexpr FontSize FontSize::Medium = FontSize(uint16_t(14));
324 : constexpr FontSize FontSize::Large = FontSize(uint16_t(16));
325 : constexpr FontSize FontSize::XLarge = FontSize(uint16_t(20));
326 : constexpr FontSize FontSize::XXLarge = FontSize(uint16_t(24));
327 :
328 : constexpr FontStyle FontStyle::Normal = FontStyle(0);
329 : constexpr FontStyle FontStyle::Italic = FontStyle(minOf<int16_t>());
330 : constexpr FontStyle FontStyle::Oblique = FontStyle(-10 << 6);
331 :
332 : constexpr FontGrade FontGrade::Thin = FontGrade(-200);
333 : constexpr FontGrade FontGrade::Reduced = FontGrade(-50);
334 : constexpr FontGrade FontGrade::Normal = FontGrade(0);
335 : constexpr FontGrade FontGrade::Heavy = FontGrade(150);
336 :
337 : #endif
338 : }
339 :
340 : namespace STAPPLER_VERSIONIZED stappler {
341 :
342 160 : inline font::FontSize progress(font::FontSize source, font::FontSize target, float p) {
343 160 : return font::FontSize::progress(source, target, p);
344 : }
345 :
346 : }
347 :
348 : namespace std {
349 :
350 : template <>
351 : struct hash<STAPPLER_VERSIONIZED_NAMESPACE::font::FontSize> {
352 : hash() { }
353 :
354 : size_t operator() (const STAPPLER_VERSIONIZED_NAMESPACE::font::FontSize &value) const noexcept {
355 : return hash<uint16_t>{}(value.get());
356 : }
357 : };
358 :
359 : }
360 :
361 : #endif /* CORE_GEOM_SPFONTSTYLE_H_ */
|