HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
iso_15924_impl.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 "iso_15924_intf.hpp"
8#include "../utility/utility.hpp"
9#include "../algorithm/algorithm.hpp"
10#include "../macros.hpp"
11#include <array>
12#include <algorithm>
13#include <format>
14#include <compare>
15
16hi_export_module(hikogui.i18n.iso_15924 : impl);
17
18hi_export namespace hi { inline namespace v1 {
19namespace detail {
20
22 fixed_string<4> code4;
23 fixed_string<4> code4_open_type;
24 uint16_t number;
25
26 constexpr iso_15924_info(char const (&code4)[5], char const (&code4_open_type)[5], uint16_t number) noexcept :
27 code4{to_title(fixed_string(code4))}, code4_open_type{code4_open_type}, number(number)
28 {
29 }
30
31 constexpr iso_15924_info() noexcept : iso_15924_info("zzzz", 999) {}
32
33 constexpr iso_15924_info(char const (&code4)[5], uint16_t number) noexcept : iso_15924_info(code4, code4, number) {}
34};
35
36[[nodiscard]] consteval auto iso_15924_infos_init() noexcept
37{
38 // We are using a c-style array to std::array conversion because
39 // compilers, tools and analysers do not handle large std::array constructors.
40
41 // clang-format off
42 constexpr iso_15924_info data[] = {
43 {"adlm", 166},
44 {"afak", 439},
45 {"aghb", 239},
46 {"ahom", 338},
47 {"arab", 160},
48 {"aran", 161},
49 {"armi", 124},
50 {"armn", 230},
51 {"avst", 134},
52 {"bali", 360},
53 {"bamu", 435},
54 {"bass", 259},
55 {"batk", 365},
56 {"beng", "bng2", 325},
57 {"bhks", 334},
58 {"blis", 550},
59 {"bopo", 285},
60 {"brah", 300},
61 {"brai", 570},
62 {"bugi", 367},
63 {"buhd", 372},
64 {"cakm", 349},
65 {"cans", 440},
66 {"cari", 201},
67 {"cham", 358},
68 {"cher", 445},
69 {"chrs", 109},
70 {"cirt", 291},
71 {"copt", 204},
72 {"cpmn", 402},
73 {"cprt", 403},
74 {"cyrl", 220},
75 {"cyrs", 221},
76 {"deva", "dev2", 315},
77 {"diak", 342},
78 {"dogr", 328},
79 {"dsrt", 250},
80 {"dupl", 755},
81 {"egyd", 70},
82 {"egyh", 60},
83 {"egyp", 50},
84 {"elba", 226},
85 {"elym", 128},
86 {"ethi", 430},
87 {"geok", 241},
88 {"geor", 240},
89 {"glag", 225},
90 {"gong", 312},
91 {"gonm", 313},
92 {"goth", 206},
93 {"gran", 343},
94 {"grek", 200},
95 {"gujr", "gjr2", 320},
96 {"guru", "gur2", 310},
97 {"hanb", 503},
98 {"hang", 286},
99 {"hani", 500},
100 {"hano", 371},
101 {"hans", 501},
102 {"hant", 502},
103 {"hatr", 127},
104 {"hebr", 125},
105 {"hira", 410},
106 {"hluw", 80},
107 {"hmng", 450},
108 {"hmnp", 451},
109 {"hrkt", 412},
110 {"hung", 176},
111 {"inds", 610},
112 {"ital", 210},
113 {"jamo", 284},
114 {"java", 361},
115 {"jpan", 413},
116 {"jurc", 510},
117 {"kali", 357},
118 {"kana", 411},
119 {"khar", 305},
120 {"khmr", 355},
121 {"khoj", 322},
122 {"kitl", 505},
123 {"kits", 288},
124 {"knda", "knd2", 345},
125 {"kore", 287},
126 {"kpel", 436},
127 {"kthi", 317},
128 {"lana", 351},
129 {"laoo", "lao ", 356},
130 {"latf", 217},
131 {"latg", 216},
132 {"latn", 215},
133 {"leke", 364},
134 {"lepc", 335},
135 {"limb", 336},
136 {"lina", 400},
137 {"linb", 401},
138 {"lisu", 399},
139 {"loma", 437},
140 {"lyci", 202},
141 {"lydi", 116},
142 {"mahj", 314},
143 {"maka", 366},
144 {"mand", 140},
145 {"mani", 139},
146 {"marc", 332},
147 {"maya", 90},
148 {"medf", 265},
149 {"mend", 438},
150 {"merc", 101},
151 {"mero", 100},
152 {"mlym", "mlm2", 347},
153 {"modi", 324},
154 {"mong", 145},
155 {"moon", 218},
156 {"mroo", 264},
157 {"mtei", 337},
158 {"mult", 323},
159 {"mymr", "mym2", 350},
160 {"nand", 311},
161 {"narb", 106},
162 {"nbat", 159},
163 {"newa", 333},
164 {"nkdb", 85},
165 {"nkgb", 420},
166 {"nkoo", "nko ", 165},
167 {"nshu", 499},
168 {"ogam", 212},
169 {"olck", 261},
170 {"orkh", 175},
171 {"orya", "ory2", 327},
172 {"osge", 219},
173 {"osma", 260},
174 {"ougr", 143},
175 {"palm", 126},
176 {"pauc", 263},
177 {"pcun", 15},
178 {"pelm", 16},
179 {"perm", 227},
180 {"phag", 331},
181 {"phli", 131},
182 {"phlp", 132},
183 {"phlv", 133},
184 {"phnx", 115},
185 {"plrd", 282},
186 {"piqd", 293},
187 {"prti", 130},
188 {"psin", 103},
189 {"qaaa", 900},
190 {"qabv", "byzm", 947}, // Open-type
191 {"qabw", "musc", 948}, // Open-type
192 {"qabx", 949},
193 {"ranj", 303},
194 {"rjng", 363},
195 {"rohg", 167},
196 {"roro", 620},
197 {"runr", 211},
198 {"samr", 123},
199 {"sara", 292},
200 {"sarb", 105},
201 {"saur", 344},
202 {"sgnw", 95},
203 {"shaw", 281},
204 {"shrd", 319},
205 {"shui", 530},
206 {"sidd", 302},
207 {"sind", 318},
208 {"sinh", 348},
209 {"sogd", 141},
210 {"sogo", 142},
211 {"sora", 398},
212 {"soyo", 329},
213 {"sund", 362},
214 {"sylo", 316},
215 {"syrc", 135},
216 {"syre", 138},
217 {"syrj", 137},
218 {"syrn", 136},
219 {"tagb", 373},
220 {"takr", 321},
221 {"tale", 353},
222 {"talu", 354},
223 {"taml", "tml2", 346},
224 {"tang", 520},
225 {"tavt", 359},
226 {"telu", "tel2", 340},
227 {"teng", 290},
228 {"tfng", 120},
229 {"tglg", 370},
230 {"thaa", 170},
231 {"thai", 352},
232 {"tibt", 330},
233 {"tirh", 326},
234 {"tnsa", 275},
235 {"toto", 294},
236 {"ugar", 40},
237 {"vaii", "vai ", 470},
238 {"visp", 280},
239 {"vith", 228},
240 {"wara", 262},
241 {"wcho", 283},
242 {"wole", 480},
243 {"xpeo", 30},
244 {"xsux", 20},
245 {"yezi", 192},
246 {"yiii", "yi ", 460},
247 {"zanb", 339},
248 {"zinh", 994},
249 {"zmth", "math", 995},
250 {"zsye", 993},
251 {"zsym", 996},
252 {"zxxx", 997},
253 {"zyyy", "DFLT", 998},
254 {"zzzz", 999}};
255 // clang-format on
256
257 constexpr auto data_size = sizeof(data) / sizeof(data[0]);
258
260
261 for (auto i = 0_uz; i != data_size; ++i) {
262 r[i] = data[i];
263 }
264
265 return r;
266}
267
268constexpr auto iso_15924_infos = iso_15924_infos_init();
269
270[[nodiscard]] consteval auto iso_15924_code4_by_number_init() noexcept
271{
272 auto r = std::array<fixed_string<4>, 1000>{};
273
274 for (auto const& info : iso_15924_infos) {
275 r[info.number] = info.code4;
276 }
277
278 return r;
279}
280
281[[nodiscard]] consteval auto iso_15924_code4_open_type_by_number_init() noexcept
282{
283 auto r = std::array<fixed_string<4>, 1000>{};
284
285 for (auto const& info : iso_15924_infos) {
286 r[info.number] = info.code4_open_type;
287 }
288
289 return r;
290}
291
292[[nodiscard]] consteval auto iso_15924_number_by_code4_init() noexcept
293{
294 constexpr auto array_size = std::tuple_size_v<decltype(iso_15924_infos)>;
295 using record_type = std::pair<fixed_string<4>, uint16_t>;
296
298 for (auto i = 0_uz; i != iso_15924_infos.size(); ++i) {
299 r[i] = {iso_15924_infos[i].code4, iso_15924_infos[i].number};
300 }
301 std::sort(r.begin(), r.end(), [](auto const& a, auto const& b) {
302 return a.first < b.first;
303 });
304
305 return r;
306}
307
308constexpr auto iso_15924_code4_by_number = iso_15924_code4_by_number_init();
309constexpr auto iso_15924_code4_open_type_by_number = iso_15924_code4_open_type_by_number_init();
310constexpr auto iso_15924_number_by_code4 = iso_15924_number_by_code4_init();
311
312} // namespace detail
313
314constexpr iso_15924::iso_15924(std::string_view code4)
315{
316 if (code4.size() != 4) {
317 throw parse_error(std::format("Invalid script '{}'", code4));
318 }
319
320 auto const code4_ = to_title(code4);
321
322 auto const it = std::lower_bound(
323 detail::iso_15924_number_by_code4.begin(),
324 detail::iso_15924_number_by_code4.end(),
325 code4_,
326 [](auto const& item, auto const& value) {
327 return item.first < value;
328 });
329
330 if (it == detail::iso_15924_number_by_code4.end() or it->first != code4_) {
331 throw parse_error(std::format("Unknown script '{}'", code4));
332 }
333
334 _v = it->second;
335}
336
337[[nodiscard]] constexpr std::string iso_15924::code4() const noexcept
338{
339 hi_assert(_v < 1000);
340 return detail::iso_15924_code4_by_number[_v];
341}
342
343[[nodiscard]] constexpr std::string iso_15924::code4_open_type() const noexcept
344{
345 hi_assert(_v < 1000);
346 return detail::iso_15924_code4_open_type_by_number[_v];
347}
348
349[[nodiscard]] constexpr bool iso_15924::left_to_right() const noexcept
350{
351 switch (_v) {
352 case 50: // Hyro
353 case 105: // Sarb
354 case 106: // Narb
355 case 115: // Phnx
356 case 116: // Lydi
357 case 123: // Samr
358 case 124: // Armi
359 case 125: // Hebr
360 case 126: // Palm
361 case 127: // Hatr
362 case 130: // Prti
363 case 131: // Phli
364 case 132: // Phlp
365 case 133: // Phlv
366 case 134: // Evst
367 case 135: // Syrc
368 case 136: // Syrn
369 case 137: // Syrj
370 case 138: // Syre
371 case 140: // Mand
372 case 141: // Sogd
373 case 142: // Sogo
374 case 159: // Nbat
375 case 160: // Arab
376 case 161: // Aran
377 case 165: // Nkoo
378 case 166: // Adlm
379 case 167: // Rohg
380 case 170: // Thaa
381 case 175: // Orkh
382 case 176: // Hung
383 case 192: // Yezi
384 case 210: // Ital
385 case 305: // Khar
386 case 403: // Cprt
387 case 438: // Mend
388 case 495: // Ethi
389 case 610: // Inds
390 return false;
391 default:
392 return true;
393 }
394}
395}} // namespace hi::v1
@ end
Start from the end of the file.
@ begin
Start from the beginning of the file.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
constexpr std::string to_title(std::string_view rhs) noexcept
Convert the current string to using title case.
Definition strings.hpp:159
Definition iso_15924_impl.hpp:21
constexpr bool left_to_right() const noexcept
Is this script written left-to-right.
Definition iso_15924_impl.hpp:349
constexpr std::string code4_open_type() const noexcept
Get the 4-letter code used by open-type.
Definition iso_15924_impl.hpp:343
constexpr std::string code4() const noexcept
Get the iso-15924 4-letter code.
Definition iso_15924_impl.hpp:337
A string which may be used as a none-type template parameter.
Definition fixed_string.hpp:42
T lower_bound(T... args)
T size(T... args)
T sort(T... args)