HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
font_weight.hpp
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../utility/module.hpp"
8#include "../strings.hpp"
9#include <string>
10#include <unordered_map>
11#include <ostream>
12#include <array>
13
14namespace hi::inline v1 {
15
16enum class font_weight {
17 Thin,
19 Light,
20 Regular,
21 Medium,
22 SemiBold,
23 Bold,
24 ExtraBold,
25 Black,
27};
28
29inline hilet font_weight_from_string_table = std::unordered_map<std::string, font_weight>{
30 {"thin", font_weight::Thin},
31 {"hairline", font_weight::Thin},
32 {"ultra-light", font_weight::ExtraLight},
33 {"ultra light", font_weight::ExtraLight},
34 {"extra-light", font_weight::ExtraLight},
35 {"extra light", font_weight::ExtraLight},
36 {"light", font_weight::Light},
37 {"normal", font_weight::Regular},
38 {"regular", font_weight::Regular},
39 {"medium", font_weight::Medium},
40 {"semi-bold", font_weight::SemiBold},
41 {"semi bold", font_weight::SemiBold},
42 {"demi-bold", font_weight::SemiBold},
43 {"demi bold", font_weight::SemiBold},
44 {"bold", font_weight::Bold},
45 {"extra-bold", font_weight::ExtraBold},
46 {"extra bold", font_weight::ExtraBold},
47 {"ultra-bold", font_weight::ExtraBold},
48 {"ultra bold", font_weight::ExtraBold},
49 {"heavy", font_weight::Black},
50 {"black", font_weight::Black},
51 {"extra-black", font_weight::ExtraBlack},
52 {"ultra-black", font_weight::ExtraBlack},
53};
54
57[[nodiscard]] constexpr font_weight font_weight_from_int(numeric_integral auto rhs)
58{
59 if (rhs < 50 || rhs > 1000) {
60 throw parse_error(std::format("Unknown font-weight {}", rhs));
61 }
62 return static_cast<font_weight>(((rhs + 50) / 100) - 1);
63}
64
65[[nodiscard]] inline font_weight font_weight_from_string(std::string_view rhs)
66{
67 hilet i = font_weight_from_string_table.find(to_lower(rhs));
68 if (i == font_weight_from_string_table.end()) {
69 throw parse_error(std::format("Unknown font-weight {}", rhs));
70 }
71 return i->second;
72}
73
74[[nodiscard]] constexpr char const *to_const_string(font_weight const &x) noexcept
75{
76 switch (x) {
77 case font_weight::Thin: return "Thin";
78 case font_weight::ExtraLight: return "ExtraLight";
79 case font_weight::Light: return "Light";
80 case font_weight::Regular: return "Regular";
81 case font_weight::Medium: return "Medium";
82 case font_weight::SemiBold: return "SemiBold";
83 case font_weight::Bold: return "Bold";
84 case font_weight::ExtraBold: return "ExtraBold";
85 case font_weight::Black: return "Black";
86 case font_weight::ExtraBlack: return "ExtraBlack";
87 default: hi_no_default();
88 }
89}
90
91[[nodiscard]] inline std::string to_string(font_weight const &x) noexcept
92{
93 return to_const_string(x);
94}
95
96[[nodiscard]] inline char to_char(font_weight const &x) noexcept
97{
98 hilet x_ = static_cast<int>(x);
99 hi_axiom(x_ >= 0 && x_ <= 9);
100 return char_cast<char>('0' + x_);
101}
102
103[[nodiscard]] constexpr int to_int(font_weight const &x) noexcept
104{
105 hilet x_ = (static_cast<int>(x) + 1) * 100;
106 return (x_ == 1000) ? 950 : x_;
107}
108
109inline std::ostream &operator<<(std::ostream &lhs, font_weight const &rhs)
110{
111 return lhs << to_string(rhs);
112}
113
114inline bool almost_equal(font_weight const &lhs, font_weight const &rhs) noexcept
115{
116 // Check only if it is bold or not.
117 return (lhs > font_weight::Medium) == (rhs > font_weight::Medium);
118}
119
120[[nodiscard]] constexpr auto font_weight_alternative_table_generator() noexcept
121{
122 std::array<font_weight, 100> r = {font_weight::Regular};
123
124 for (auto w = 0_uz; w < 10_uz; ++w) {
125 auto min_w = w;
126 auto max_w = w;
127 auto new_w = w;
128 auto forward = false;
129
130 for (auto i = 0_uz; i < 10_uz; ++i) {
131 r[w * 10_uz + i] = static_cast<font_weight>(new_w);
132
133 // Change direction to not overflow.
134 if ((forward and max_w == 9_uz) or (not forward and min_w == 0_uz)) {
135 forward = not forward;
136 }
137
138 new_w = forward ? ++max_w : --min_w;
139
140 // Change direction to zig-zag.
141 forward = not forward;
142 }
143 }
144 return r;
145}
146
147constexpr auto font_weight_alternative_table = font_weight_alternative_table_generator();
148
149[[nodiscard]] constexpr font_weight font_weight_alterative(font_weight weight, int i) noexcept
150{
151 hi_axiom(i >= 0 && i < 10);
152 auto w = static_cast<int>(weight);
153 hi_axiom(w >= 0 && w < 10);
154 return font_weight_alternative_table[(w * 10) + i];
155}
156
157} // namespace hi::inline v1
158
159template<typename CharT>
160struct std::formatter<hi::font_weight, CharT> : std::formatter<char const *, CharT> {
161 auto format(hi::font_weight const &t, auto &fc)
162 {
163 return std::formatter<char const *, CharT>::format(hi::to_const_string(t), fc);
164 }
165};
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:264
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
constexpr std::string to_string(std::u32string_view rhs) noexcept
Conversion from UTF-32 to UTF-8.
Definition to_string.hpp:215
DOXYGEN BUG.
Definition algorithm.hpp:13
constexpr font_weight font_weight_from_int(numeric_integral auto rhs)
Convert a font weight value between 50 and 1000 to a font weight.
Definition font_weight.hpp:57
font_weight
Definition font_weight.hpp:16
@ SemiBold
600: Semi-bold / Demi-bold
@ Medium
500: Medium
@ Light
300: Light
@ ExtraBold
800: Extra-bold / Ultra-bold
@ Thin
100: Thin / Hairline
@ Regular
400: Normal / Regular
@ ExtraBlack
950: Extra-black / Ultra-black
@ Black
900: Heavy / Black
@ ExtraLight
200: Ultra-light / Extra-light
geometry/margins.hpp
Definition cache.hpp:11
Definition concepts.hpp:24
T forward(T... args)