HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
cp_1252.hpp
Go to the documentation of this file.
1// Copyright Take Vos 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
9#pragma once
10
11#include "char_converter.hpp"
12#include "../utility/utility.hpp"
13#include "../macros.hpp"
14#include <cstdint>
15#include <utility>
16#include <array>
17#include <bit>
18#include <compare>
19#if defined(HI_HAS_SSE2)
20#include <emmintrin.h>
21#endif
22
23hi_export_module(hikogui.char_maps.cp_1252);
24
25hi_export namespace hi { inline namespace v1 {
26
27namespace detail {
28
29constexpr auto cp_1252_make_table_0000_02DC() noexcept
30{
32 for (auto i = 0x0; i != 0x2dd; ++i) {
33 r[i] = 0x3f; // '?'
34 }
35 for (auto i = 0_uz; i != 0x80; ++i) {
36 r[i] = char_cast<uint8_t>(i);
37 }
38 r[0x81] = 0x81;
39 r[0x8d] = 0x8d;
40 r[0x8f] = 0x8f;
41 r[0x90] = 0x90;
42 r[0x9d] = 0x9d;
43 for (auto i = 0xa0; i != 0x100; ++i) {
44 r[i] = char_cast<uint8_t>(i);
45 }
46
47 r[0x192] = 0x83;
48 r[0x2c6] = 0x88;
49 r[0x160] = 0x8a;
50 r[0x152] = 0x8c;
51 r[0x17d] = 0x8e;
52
53 r[0x2dc] = 0x98;
54 r[0x161] = 0x9a;
55 r[0x153] = 0x9c;
56 r[0x17e] = 0x9e;
57 r[0x178] = 0x9f;
58
59 return r;
60}
61
62constexpr auto cp_1252_make_table_2000_2122() noexcept
63{
65 for (auto i = 0x0; i != 0x123; ++i) {
66 r[i] = 0x3f; // '?'
67 }
68
69 r[0xac] = 0x80;
70 r[0x1a] = 0x82;
71 r[0x1e] = 0x84;
72 r[0x26] = 0x85;
73 r[0x20] = 0x86;
74 r[0x21] = 0x87;
75 r[0x30] = 0x89;
76 r[0x39] = 0x8b;
77
78 r[0x18] = 0x91;
79 r[0x19] = 0x92;
80 r[0x1c] = 0x93;
81 r[0x1d] = 0x94;
82 r[0x22] = 0x95;
83 r[0x13] = 0x96;
84 r[0x14] = 0x97;
85 r[0x122] = 0x99;
86 r[0x3a] = 0x9b;
87
88 return r;
89}
90
91} // namespace detail
92
96template<>
97struct char_map<"cp-1252"> {
98 using char_type = char;
99
100 [[nodiscard]] constexpr std::endian guess_endian(void const *ptr, size_t size, std::endian endian) const noexcept
101 {
102 return std::endian::native;
103 }
104
105 template<typename It, typename EndIt>
106 [[nodiscard]] constexpr std::pair<char32_t, bool> read(It& it, EndIt last) const noexcept
107 {
108 // clang-format off
109 hi_axiom(it != last);
110 auto const c = char_cast<char8_t>(*it++);
111 switch (c) {
112 case 0x80: return {0x20ac, true};
113 case 0x81: return {0x81, true};
114 case 0x82: return {0x201a, true};
115 case 0x83: return {0x0192, true};
116 case 0x84: return {0x201e, true};
117 case 0x85: return {0x2026, true};
118 case 0x86: return {0x2020, true};
119 case 0x87: return {0x2021, true};
120 case 0x88: return {0x02c6, true};
121 case 0x89: return {0x2030, true};
122 case 0x8a: return {0x0160, true};
123 case 0x8b: return {0x2039, true};
124 case 0x8c: return {0x0152, true};
125 case 0x8d: return {0x8d, true};
126 case 0x8e: return {0x017d, true};
127 case 0x8f: return {0x8f, true};
128
129 case 0x90: return {0x90, true};
130 case 0x91: return {0x2018, true};
131 case 0x92: return {0x2019, true};
132 case 0x93: return {0x201c, true};
133 case 0x94: return {0x201d, true};
134 case 0x95: return {0x2022, true};
135 case 0x96: return {0x2013, true};
136 case 0x97: return {0x2014, true};
137 case 0x98: return {0x02dc, true};
138 case 0x99: return {0x2122, true};
139 case 0x9a: return {0x0161, true};
140 case 0x9b: return {0x203a, true};
141 case 0x9c: return {0x0153, true};
142 case 0x9d: return {0x9d, true};
143 case 0x9e: return {0x017e, true};
144 case 0x9f: return {0x0178, true};
145 default: return {c, true};
146 }
147 // clang-format on
148 }
149
150 constexpr static auto range_0000_02DC = detail::cp_1252_make_table_0000_02DC();
151 constexpr static auto range_2000_2122 = detail::cp_1252_make_table_2000_2122();
152
153 [[nodiscard]] constexpr std::pair<uint8_t, bool> size(char32_t code_point) const noexcept
154 {
155 hi_axiom(code_point < 0x11'0000);
156 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
157
158 if (code_point < 0x2dd) {
159 if (code_point == 0x3f) {
160 return {uint8_t{1}, true};
161 } else {
162 return {uint8_t{1}, range_0000_02DC[code_point] != 0x3f};
163 }
164 } else if (code_point < 0x2000) {
165 return {uint8_t{1}, false};
166
167 } else if (code_point < 0x2123) {
168 return {uint8_t{1}, range_2000_2122[wide_cast<size_t>(code_point) - 0x2000] != 0x3f};
169
170 } else {
171 return {uint8_t{1}, false};
172 }
173 }
174
175 template<typename It>
176 constexpr void write(char32_t code_point, It& dst) const noexcept
177 {
178 hi_axiom(code_point < 0x11'0000);
179 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
180
181 if (code_point < 0x2dd) {
182 *dst++ = char_cast<char_type>(range_0000_02DC[code_point]);
183
184 } else if (code_point < 0x2000) {
185 *dst++ = char_cast<char_type>(0x3f);
186
187 } else if (code_point < 0x2123) {
188 *dst++ = char_cast<char_type>(range_2000_2122[code_point - 0x2000]);
189
190 } else {
191 *dst++ = char_cast<char_type>(0x3f);
192 }
193 }
194
195#if defined(HI_HAS_SSE2)
196 template<typename It>
197 hi_force_inline __m128i read_ascii_chunk16(It it) const noexcept
198 {
199 return _mm_loadu_si128(reinterpret_cast<__m128i const *>(std::addressof(*it)));
200 }
201
202 template<typename It>
203 hi_force_inline void write_ascii_chunk16(__m128i chunk, It dst) const noexcept
204 {
205 _mm_storeu_si128(reinterpret_cast<__m128i *>(std::addressof(*dst)), chunk);
206 }
207#endif
208};
209
210}} // namespace hi::v1
Definition of the char_converter<From,To> functor.
@ read
Allow read access to a file.
@ write
Allow write access to a file.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Character encoder/decoder template.
Definition char_converter.hpp:89
T addressof(T... args)