-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathdraw_text_builtin.cpp
299 lines (282 loc) · 34.8 KB
/
draw_text_builtin.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
* (c)2021, Cris Luengo.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "diplib/generation.h"
#include <cmath>
#include "diplib.h"
#include "diplib/chain_code.h"
#include "diplib/geometry.h"
namespace dip {
namespace {
/*
* The following glyph bitmaps and metrics were obtained by rendering the Open Sans font,
* see examples/cpp/generate_embedded_font.cpp.
*
* Open Sans was designed by Steve Matteson, and released under the Apache 2.0 license.
* However, no copyright statement can be found in the font files or on the Google Fonts
* page where I downloaded them: https://fonts.google.com/specimen/Open+Sans#about
*/
constexpr dip::uint beginChar = 32;
constexpr dip::uint endChar = 127;
constexpr dip::uint nGlyphs = endChar - beginChar + 1;
constexpr dip::uint8 glyphImage[] = {
0, 211, 129, 0, 199, 118, 0, 187, 107, 0, 175, 95, 0, 163, 84, 0, 151, 72, 0, 138, 61, 0, 0, 0, 0, 153, 91, 0, 198, 119,
13, 255, 30, 137, 159, 0, 251, 13, 121, 143, 0, 233, 0, 105, 127, 0, 200, 0, 88, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 151, 88, 0, 143, 88, 0, 0, 0, 0, 197, 43, 0, 189, 43, 0, 0, 0, 1, 234, 4, 0, 227, 4, 0, 27, 220, 221, 251, 220, 220, 251, 220, 151, 0, 0, 87, 146, 0, 86, 150, 0, 0, 0, 0, 146, 88, 0, 143, 92, 0, 0, 143, 224, 251, 226, 224, 251, 226, 224, 42, 0, 1, 234, 2, 1, 231, 2, 0, 0, 0, 35, 201, 0, 37, 198, 0, 0, 0, 0, 78, 155, 0, 84, 151, 0, 0, 0,
0, 0, 0, 116, 96, 0, 0, 0, 0, 73, 198, 247, 250, 223, 121, 0, 10, 245, 85, 121, 98, 43, 55, 0, 16, 252, 44, 116, 96, 0, 0, 0, 0, 111, 237, 222, 148, 19, 0, 0, 0, 0, 15, 155, 207, 235, 126, 0, 0, 0, 0, 116, 96, 35, 253, 25, 17, 86, 31, 120, 113, 98, 238, 7, 18, 183, 231, 252, 238, 179, 50, 0, 0, 0, 0, 116, 96, 0, 0, 0,
0, 119, 213, 195, 27, 0, 0, 56, 198, 0, 0, 22, 220, 6, 106, 146, 0, 0, 196, 59, 0, 0, 64, 176, 0, 45, 194, 0, 84, 172, 0, 0, 0, 63, 176, 0, 46, 194, 5, 213, 36, 0, 0, 0, 20, 220, 7, 108, 146, 112, 144, 109, 213, 201, 35, 0, 113, 216, 198, 44, 220, 32, 226, 11, 90, 162, 0, 0, 0, 0, 140, 116, 48, 192, 0, 29, 210, 0, 0, 0, 32, 215, 7, 47, 192, 0, 30, 210, 0, 0, 0, 168, 88, 0, 11, 224, 11, 92, 162, 0, 0, 54, 200, 1, 0, 0, 101, 215, 203, 36,
0, 0, 108, 219, 234, 180, 22, 0, 0, 0, 0, 0, 46, 243, 35, 6, 180, 140, 0, 0, 0, 0, 0, 55, 232, 2, 0, 148, 146, 0, 0, 0, 0, 0, 2, 202, 136, 110, 224, 33, 0, 0, 0, 0, 0, 0, 94, 255, 225, 24, 0, 0, 0, 0, 0, 0, 112, 221, 82, 218, 142, 0, 0, 195, 95, 0, 25, 253, 45, 0, 24, 212, 154, 48, 241, 15, 0, 51, 253, 5, 0, 0, 20, 205, 244, 107, 0, 0, 10, 238, 144, 20, 16, 85, 225, 225, 167, 3, 0, 0, 55, 197, 247, 239, 190, 71, 16, 208, 161, 2,
13, 255, 30, 0, 251, 13, 0, 233, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 179, 97, 0, 88, 201, 0, 0, 200, 92, 0, 27, 252, 17, 0, 73, 217, 0, 0, 98, 194, 0, 0, 100, 195, 0, 0, 75, 222, 0, 0, 32, 251, 17, 0, 0, 204, 95, 0, 0, 94, 201, 1, 0, 0, 181, 99,
71, 208, 4, 0, 0, 173, 121, 0, 0, 66, 229, 1, 0, 3, 235, 58, 0, 0, 191, 104, 0, 0, 163, 129, 0, 0, 161, 132, 0, 0, 190, 106, 0, 3, 234, 63, 0, 64, 232, 2, 0, 171, 127, 0, 67, 210, 6, 0,
0, 0, 0, 196, 102, 0, 0, 0, 6, 2, 0, 170, 77, 0, 9, 0, 79, 236, 166, 196, 154, 190, 243, 3, 3, 26, 77, 235, 209, 43, 18, 0, 0, 4, 194, 102, 190, 114, 0, 0, 0, 47, 197, 6, 56, 189, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 104, 97, 0, 0, 0, 0, 0, 0, 124, 116, 0, 0, 0, 0, 0, 0, 124, 116, 0, 0, 0, 71, 240, 240, 247, 247, 240, 240, 67, 0, 0, 0, 124, 116, 0, 0, 0, 0, 0, 0, 124, 116, 0, 0, 0, 0, 0, 0, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 209, 115, 13, 248, 28, 76, 168, 0,
1, 4, 4, 3, 112, 255, 255, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 153, 90, 0, 198, 117,
0, 0, 0, 80, 203, 0, 0, 0, 176, 108, 0, 0, 20, 244, 19, 0, 0, 111, 174, 0, 0, 0, 207, 79, 0, 0, 45, 234, 5, 0, 0, 142, 144, 0, 0, 4, 232, 49, 0, 0, 77, 210, 0, 0, 0, 172, 115, 0, 0, 0,
0, 9, 157, 236, 236, 149, 5, 0, 0, 150, 183, 21, 22, 186, 139, 0, 6, 246, 38, 0, 0, 46, 242, 4, 48, 240, 0, 0, 0, 1, 245, 46, 69, 221, 0, 0, 0, 0, 226, 68, 69, 220, 0, 0, 0, 0, 226, 64, 47, 239, 0, 0, 0, 1, 244, 41, 5, 243, 36, 0, 0, 44, 246, 8, 0, 141, 177, 17, 18, 182, 151, 0, 0, 6, 151, 237, 241, 160, 11, 0,
0, 0, 6, 157, 236, 0, 21, 194, 175, 236, 0, 119, 112, 48, 236, 0, 0, 0, 48, 236, 0, 0, 0, 48, 236, 0, 0, 0, 48, 236, 0, 0, 0, 48, 236, 0, 0, 0, 48, 236, 0, 0, 0, 48, 236, 0, 0, 0, 48, 236,
0, 75, 192, 242, 237, 155, 11, 0, 7, 180, 79, 14, 31, 201, 144, 0, 0, 0, 0, 0, 0, 100, 203, 0, 0, 0, 0, 0, 0, 122, 176, 0, 0, 0, 0, 0, 22, 232, 67, 0, 0, 0, 0, 10, 195, 129, 0, 0, 0, 0, 9, 187, 147, 0, 0, 0, 0, 9, 186, 147, 0, 0, 0, 0, 9, 186, 153, 12, 12, 12, 12, 2, 79, 255, 255, 255, 255, 255, 255, 60,
3, 102, 209, 246, 234, 169, 24, 0, 20, 158, 52, 4, 19, 175, 173, 0, 0, 0, 0, 0, 0, 89, 212, 0, 0, 0, 0, 7, 52, 207, 97, 0, 0, 0, 209, 253, 249, 125, 3, 0, 0, 0, 0, 5, 45, 179, 176, 0, 0, 0, 0, 0, 0, 23, 255, 26, 0, 0, 0, 0, 0, 33, 255, 25, 53, 79, 19, 2, 34, 182, 186, 0, 49, 189, 237, 248, 227, 147, 16, 0,
0, 0, 0, 0, 71, 255, 60, 0, 0, 0, 0, 16, 212, 223, 60, 0, 0, 0, 0, 162, 111, 217, 60, 0, 0, 0, 79, 193, 2, 220, 60, 0, 0, 20, 221, 34, 0, 220, 60, 0, 0, 170, 105, 0, 0, 220, 60, 0, 88, 192, 9, 8, 8, 221, 66, 5, 179, 255, 255, 255, 255, 255, 255, 188, 0, 0, 0, 0, 0, 220, 60, 0, 0, 0, 0, 0, 0, 220, 60, 0,
0, 131, 255, 255, 255, 255, 128, 0, 0, 151, 124, 12, 12, 12, 6, 0, 0, 171, 97, 0, 0, 0, 0, 0, 0, 191, 77, 0, 0, 0, 0, 0, 0, 202, 234, 246, 240, 175, 33, 0, 0, 18, 16, 0, 27, 164, 215, 2, 0, 0, 0, 0, 0, 14, 254, 40, 0, 0, 0, 0, 0, 18, 255, 28, 14, 98, 23, 2, 36, 173, 183, 0, 11, 174, 234, 248, 228, 146, 14, 0,
0, 0, 29, 168, 236, 242, 136, 0, 0, 28, 236, 121, 14, 0, 7, 0, 0, 163, 146, 0, 0, 0, 0, 0, 2, 238, 46, 0, 0, 0, 0, 0, 30, 251, 79, 204, 232, 208, 65, 0, 45, 252, 148, 9, 0, 86, 242, 18, 25, 252, 4, 0, 0, 0, 218, 73, 0, 237, 35, 0, 0, 0, 230, 63, 0, 120, 192, 31, 8, 124, 226, 6, 0, 2, 124, 234, 245, 190, 43, 0,
92, 255, 255, 255, 255, 255, 255, 75, 4, 12, 12, 12, 12, 47, 242, 16, 0, 0, 0, 0, 0, 150, 146, 0, 0, 0, 0, 0, 20, 243, 35, 0, 0, 0, 0, 0, 128, 174, 0, 0, 0, 0, 0, 9, 235, 60, 0, 0, 0, 0, 0, 106, 202, 0, 0, 0, 0, 0, 2, 220, 88, 0, 0, 0, 0, 0, 84, 226, 4, 0, 0, 0, 0, 0, 201, 116, 0, 0, 0, 0,
0, 36, 182, 239, 240, 182, 35, 0, 0, 202, 141, 6, 7, 147, 198, 0, 0, 233, 54, 0, 0, 62, 234, 0, 0, 151, 175, 11, 11, 179, 131, 0, 0, 7, 159, 237, 233, 123, 0, 0, 0, 84, 217, 104, 137, 230, 79, 0, 29, 245, 36, 0, 0, 53, 243, 26, 68, 222, 0, 0, 0, 0, 225, 62, 19, 242, 90, 0, 1, 99, 236, 14, 0, 59, 195, 235, 236, 191, 50, 0,
0, 36, 184, 243, 234, 138, 4, 0, 3, 219, 134, 10, 29, 187, 142, 0, 55, 240, 2, 0, 0, 28, 245, 9, 65, 230, 0, 0, 0, 1, 243, 49, 14, 241, 95, 0, 14, 140, 250, 58, 0, 64, 209, 237, 215, 82, 246, 41, 0, 0, 0, 0, 0, 38, 245, 7, 0, 0, 0, 0, 0, 135, 173, 0, 0, 8, 0, 11, 111, 240, 34, 0, 0, 134, 241, 237, 175, 45, 0, 0,
0, 207, 126, 0, 147, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 90, 0, 198, 117,
0, 213, 120, 0, 151, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 238, 86, 41, 240, 10, 108, 139, 0,
0, 0, 0, 0, 0, 30, 154, 66, 0, 0, 0, 27, 150, 216, 102, 6, 0, 24, 145, 210, 96, 4, 0, 0, 55, 246, 125, 3, 0, 0, 0, 0, 6, 97, 209, 174, 61, 0, 0, 0, 0, 0, 0, 73, 189, 204, 91, 5, 0, 0, 0, 0, 0, 49, 166, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51, 236, 236, 236, 236, 236, 236, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 240, 240, 240, 240, 240, 240, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70, 152, 29, 0, 0, 0, 0, 0, 6, 104, 217, 147, 26, 0, 0, 0, 0, 0, 5, 99, 211, 143, 23, 0, 0, 0, 0, 0, 3, 126, 245, 52, 0, 0, 0, 61, 173, 206, 95, 5, 6, 93, 204, 188, 71, 0, 0, 0, 70, 164, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90, 203, 242, 235, 155, 7, 68, 60, 12, 30, 198, 119, 0, 0, 0, 0, 121, 153, 0, 0, 0, 15, 213, 80, 0, 0, 28, 211, 116, 0, 0, 0, 199, 97, 0, 0, 0, 3, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 177, 28, 0, 0, 0, 46, 231, 35, 0, 0,
0, 0, 0, 45, 159, 217, 219, 219, 183, 73, 0, 0, 0, 0, 101, 209, 77, 6, 0, 0, 49, 191, 127, 0, 0, 59, 207, 13, 0, 0, 0, 0, 0, 7, 205, 54, 0, 187, 63, 0, 70, 204, 212, 218, 128, 0, 93, 148, 11, 229, 0, 29, 233, 45, 0, 91, 157, 0, 53, 182, 39, 199, 0, 90, 176, 0, 0, 110, 142, 0, 71, 165, 33, 206, 0, 63, 205, 3, 4, 178, 153, 0, 160, 89, 6, 233, 10, 0, 146, 214, 197, 58, 172, 212, 148, 1, 0, 157, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 211, 131, 22, 0, 0, 11, 78, 3, 0, 0, 0, 0, 11, 126, 208, 220, 222, 216, 150, 3, 0, 0,
0, 0, 0, 75, 255, 38, 0, 0, 0, 0, 0, 0, 175, 210, 137, 0, 0, 0, 0, 0, 23, 246, 64, 232, 4, 0, 0, 0, 0, 119, 178, 0, 212, 80, 0, 0, 0, 0, 217, 85, 0, 120, 179, 0, 0, 0, 63, 241, 15, 8, 37, 251, 26, 0, 0, 163, 255, 255, 255, 255, 255, 123, 0, 15, 246, 50, 0, 0, 0, 100, 221, 1, 107, 201, 0, 0, 0, 0, 10, 239, 66, 206, 96, 0, 0, 0, 0, 0, 145, 166,
0, 160, 255, 255, 249, 228, 164, 29, 0, 0, 160, 136, 0, 5, 37, 178, 191, 0, 0, 160, 136, 0, 0, 0, 76, 228, 0, 0, 160, 136, 0, 0, 24, 173, 139, 0, 0, 160, 252, 248, 251, 255, 156, 9, 0, 0, 160, 136, 0, 2, 29, 157, 192, 4, 0, 160, 136, 0, 0, 0, 17, 254, 56, 0, 160, 136, 0, 0, 0, 15, 254, 57, 0, 160, 136, 0, 1, 27, 165, 224, 5, 0, 160, 254, 252, 252, 239, 175, 36, 0,
0, 0, 20, 144, 223, 249, 232, 182, 37, 0, 21, 222, 194, 55, 14, 36, 104, 9, 0, 155, 203, 2, 0, 0, 0, 0, 0, 3, 241, 83, 0, 0, 0, 0, 0, 0, 27, 255, 39, 0, 0, 0, 0, 0, 0, 25, 255, 30, 0, 0, 0, 0, 0, 0, 3, 245, 73, 0, 0, 0, 0, 0, 0, 0, 169, 182, 0, 0, 0, 0, 0, 0, 0, 34, 236, 166, 46, 10, 24, 73, 1, 0, 0, 34, 162, 229, 250, 237, 188, 2,
0, 160, 255, 255, 250, 226, 156, 35, 0, 0, 0, 160, 136, 0, 8, 44, 150, 242, 50, 0, 0, 160, 136, 0, 0, 0, 0, 142, 205, 0, 0, 160, 136, 0, 0, 0, 0, 31, 255, 33, 0, 160, 136, 0, 0, 0, 0, 0, 246, 64, 0, 160, 136, 0, 0, 0, 0, 0, 246, 60, 0, 160, 136, 0, 0, 0, 0, 35, 255, 26, 0, 160, 136, 0, 0, 0, 0, 153, 193, 0, 0, 160, 136, 0, 9, 51, 161, 236, 39, 0, 0, 160, 255, 255, 246, 218, 146, 25, 0, 0,
0, 160, 255, 255, 255, 255, 240, 0, 160, 139, 8, 8, 8, 7, 0, 160, 136, 0, 0, 0, 0, 0, 160, 137, 4, 4, 4, 2, 0, 160, 255, 255, 255, 255, 172, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 139, 8, 8, 8, 7, 0, 160, 255, 255, 255, 255, 240,
0, 160, 255, 255, 255, 255, 240, 0, 160, 139, 8, 8, 8, 7, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 139, 8, 8, 8, 5, 0, 160, 255, 255, 255, 255, 172, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0,
0, 0, 7, 118, 207, 242, 243, 214, 134, 0, 0, 10, 203, 197, 69, 16, 22, 66, 93, 0, 0, 141, 200, 5, 0, 0, 0, 0, 0, 0, 1, 237, 77, 0, 0, 0, 0, 0, 0, 0, 22, 255, 28, 0, 0, 0, 0, 0, 0, 0, 24, 255, 27, 0, 0, 92, 255, 255, 255, 36, 2, 243, 71, 0, 0, 2, 8, 15, 255, 36, 0, 162, 185, 1, 0, 0, 0, 8, 255, 36, 0, 25, 228, 176, 56, 14, 11, 46, 255, 36, 0, 0, 23, 148, 223, 249, 243, 223, 170, 19,
0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 139, 8, 8, 8, 8, 62, 240, 0, 160, 255, 255, 255, 255, 255, 255, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240, 0, 160, 136, 0, 0, 0, 0, 56, 240,
0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136, 0, 160, 136,
0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 176, 120, 0, 0, 0, 182, 111, 4, 12, 55, 242, 58, 27, 245, 236, 124, 0,
0, 160, 136, 0, 0, 0, 101, 221, 24, 0, 160, 136, 0, 0, 81, 229, 35, 0, 0, 160, 136, 0, 63, 232, 48, 0, 0, 0, 160, 136, 46, 232, 62, 0, 0, 0, 0, 160, 168, 230, 165, 0, 0, 0, 0, 0, 160, 240, 105, 245, 73, 0, 0, 0, 0, 160, 137, 0, 102, 234, 25, 0, 0, 0, 160, 136, 0, 0, 167, 188, 2, 0, 0, 160, 136, 0, 0, 13, 219, 122, 0, 0, 160, 136, 0, 0, 0, 50, 244, 58,
0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 160, 141, 12, 12, 12, 11, 0, 160, 255, 255, 255, 255, 248,
0, 160, 255, 72, 0, 0, 0, 0, 0, 174, 255, 56, 0, 160, 215, 169, 0, 0, 0, 0, 22, 235, 228, 56, 0, 160, 133, 244, 17, 0, 0, 0, 116, 152, 230, 56, 0, 160, 114, 180, 107, 0, 0, 0, 214, 53, 235, 56, 0, 160, 116, 83, 205, 0, 0, 58, 211, 0, 236, 56, 0, 160, 116, 6, 235, 46, 0, 157, 113, 0, 236, 56, 0, 160, 116, 0, 144, 143, 12, 237, 21, 0, 236, 56, 0, 160, 116, 0, 47, 234, 105, 173, 0, 0, 236, 56, 0, 160, 116, 0, 0, 206, 242, 75, 0, 0, 236, 56, 0, 160, 116, 0, 0, 109, 229, 3, 0, 0, 236, 56,
0, 160, 238, 23, 0, 0, 0, 0, 232, 48, 0, 160, 238, 172, 0, 0, 0, 0, 232, 48, 0, 160, 121, 238, 82, 0, 0, 0, 232, 48, 0, 160, 109, 96, 230, 16, 0, 0, 232, 48, 0, 160, 115, 0, 185, 157, 0, 0, 232, 48, 0, 160, 116, 0, 31, 243, 67, 0, 232, 48, 0, 160, 116, 0, 0, 110, 222, 10, 229, 48, 0, 160, 116, 0, 0, 2, 197, 142, 221, 48, 0, 160, 116, 0, 0, 0, 41, 245, 243, 48, 0, 160, 116, 0, 0, 0, 0, 123, 255, 48,
0, 0, 32, 158, 228, 248, 224, 145, 18, 0, 0, 0, 33, 235, 157, 43, 14, 43, 164, 218, 14, 0, 0, 168, 172, 0, 0, 0, 0, 0, 203, 134, 0, 3, 244, 68, 0, 0, 0, 0, 0, 100, 218, 0, 25, 255, 30, 0, 0, 0, 0, 0, 64, 250, 1, 27, 255, 29, 0, 0, 0, 0, 0, 59, 253, 1, 4, 245, 68, 0, 0, 0, 0, 0, 97, 219, 0, 0, 170, 168, 0, 0, 0, 0, 1, 195, 138, 0, 0, 36, 237, 150, 38, 11, 43, 168, 221, 17, 0, 0, 0, 35, 163, 232, 250, 227, 149, 21, 0, 0,
0, 160, 255, 255, 248, 211, 106, 0, 0, 160, 136, 0, 17, 85, 244, 83, 0, 160, 136, 0, 0, 0, 150, 160, 0, 160, 136, 0, 0, 0, 151, 150, 0, 160, 136, 0, 13, 87, 241, 64, 0, 160, 254, 252, 243, 193, 73, 0, 0, 160, 136, 0, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0, 0, 160, 136, 0, 0, 0, 0, 0,
0, 0, 32, 158, 228, 248, 224, 145, 18, 0, 0, 0, 33, 235, 157, 43, 14, 43, 164, 218, 14, 0, 0, 168, 172, 0, 0, 0, 0, 0, 203, 134, 0, 3, 244, 68, 0, 0, 0, 0, 0, 100, 218, 0, 25, 255, 30, 0, 0, 0, 0, 0, 64, 250, 1, 27, 255, 29, 0, 0, 0, 0, 0, 59, 252, 1, 4, 245, 68, 0, 0, 0, 0, 0, 97, 217, 0, 0, 170, 168, 0, 0, 0, 0, 1, 195, 134, 0, 0, 36, 237, 150, 38, 11, 43, 168, 219, 16, 0, 0, 0, 35, 163, 232, 253, 255, 157, 19, 0, 0, 0, 0, 0, 0, 0, 4, 173, 197, 15, 0, 0, 0, 0, 0, 0, 0, 0, 6, 181, 205, 20, 0,
0, 160, 255, 255, 247, 214, 114, 0, 0, 0, 160, 137, 4, 17, 79, 242, 96, 0, 0, 160, 136, 0, 0, 0, 149, 168, 0, 0, 160, 136, 0, 0, 0, 152, 160, 0, 0, 160, 136, 0, 8, 74, 236, 56, 0, 0, 160, 254, 252, 255, 230, 58, 0, 0, 0, 160, 136, 0, 32, 242, 52, 0, 0, 0, 160, 136, 0, 0, 121, 207, 4, 0, 0, 160, 136, 0, 0, 5, 214, 117, 0, 0, 160, 136, 0, 0, 0, 63, 244, 33,
0, 42, 183, 243, 243, 209, 100, 5, 226, 145, 31, 23, 69, 64, 30, 255, 24, 0, 0, 0, 0, 3, 233, 118, 0, 0, 0, 0, 0, 60, 228, 208, 106, 12, 0, 0, 0, 6, 91, 197, 234, 63, 0, 0, 0, 0, 0, 131, 219, 0, 0, 0, 0, 0, 53, 245, 38, 85, 32, 11, 43, 179, 170, 41, 200, 243, 252, 228, 147, 13,
224, 255, 255, 255, 255, 255, 255, 144, 7, 8, 8, 190, 116, 8, 8, 4, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0, 0, 0, 0, 188, 112, 0, 0, 0,
0, 188, 112, 0, 0, 0, 0, 60, 236, 0, 188, 112, 0, 0, 0, 0, 60, 236, 0, 188, 112, 0, 0, 0, 0, 60, 236, 0, 188, 112, 0, 0, 0, 0, 60, 236, 0, 188, 112, 0, 0, 0, 0, 60, 236, 0, 188, 112, 0, 0, 0, 0, 60, 236, 0, 179, 119, 0, 0, 0, 0, 65, 230, 0, 139, 171, 0, 0, 0, 0, 114, 192, 0, 32, 244, 117, 26, 14, 84, 239, 78, 0, 0, 49, 185, 235, 244, 199, 78, 0,
210, 101, 0, 0, 0, 0, 21, 251, 41, 119, 192, 0, 0, 0, 0, 108, 206, 0, 28, 252, 29, 0, 0, 0, 198, 114, 0, 0, 191, 118, 0, 0, 32, 252, 26, 0, 0, 99, 210, 0, 0, 122, 187, 0, 0, 0, 15, 247, 45, 0, 212, 95, 0, 0, 0, 0, 171, 136, 46, 246, 13, 0, 0, 0, 0, 79, 218, 131, 168, 0, 0, 0, 0, 0, 5, 236, 226, 77, 0, 0, 0, 0, 0, 0, 150, 236, 5, 0, 0, 0,
171, 140, 0, 0, 0, 86, 255, 41, 0, 0, 0, 161, 149, 103, 205, 0, 0, 0, 160, 235, 118, 0, 0, 0, 225, 81, 34, 253, 17, 0, 1, 232, 124, 195, 0, 0, 35, 252, 16, 0, 222, 79, 0, 52, 227, 16, 248, 19, 0, 100, 200, 0, 0, 155, 144, 0, 126, 154, 0, 192, 93, 0, 165, 131, 0, 0, 87, 209, 0, 200, 81, 0, 117, 169, 0, 229, 63, 0, 0, 20, 252, 37, 247, 13, 0, 41, 240, 42, 244, 6, 0, 0, 0, 207, 154, 190, 0, 0, 0, 221, 149, 182, 0, 0, 0, 0, 139, 242, 117, 0, 0, 0, 146, 241, 114, 0, 0, 0, 0, 70, 255, 44, 0, 0, 0, 70, 255, 46, 0, 0,
102, 216, 7, 0, 0, 0, 191, 120, 0, 1, 190, 128, 0, 0, 97, 206, 4, 0, 0, 35, 239, 39, 20, 232, 48, 0, 0, 0, 0, 117, 192, 163, 134, 0, 0, 0, 0, 0, 3, 211, 225, 7, 0, 0, 0, 0, 0, 32, 233, 237, 48, 0, 0, 0, 0, 0, 184, 115, 110, 203, 3, 0, 0, 0, 92, 208, 4, 3, 205, 114, 0, 0, 19, 233, 56, 0, 0, 54, 242, 33, 0, 162, 151, 0, 0, 0, 0, 151, 185, 0,
187, 135, 0, 0, 0, 0, 176, 141, 50, 244, 25, 0, 0, 56, 239, 18, 0, 165, 150, 0, 0, 191, 119, 0, 0, 33, 244, 35, 71, 227, 9, 0, 0, 0, 144, 166, 205, 97, 0, 0, 0, 0, 20, 241, 211, 2, 0, 0, 0, 0, 0, 170, 129, 0, 0, 0, 0, 0, 0, 168, 128, 0, 0, 0, 0, 0, 0, 168, 128, 0, 0, 0, 0, 0, 0, 168, 128, 0, 0, 0,
72, 255, 255, 255, 255, 255, 255, 82, 3, 12, 12, 12, 12, 112, 221, 11, 0, 0, 0, 0, 29, 240, 63, 0, 0, 0, 0, 0, 185, 147, 0, 0, 0, 0, 0, 101, 221, 11, 0, 0, 0, 0, 29, 239, 63, 0, 0, 0, 0, 0, 184, 146, 0, 0, 0, 0, 0, 100, 220, 11, 0, 0, 0, 0, 28, 240, 75, 12, 12, 12, 12, 5, 118, 255, 255, 255, 255, 255, 255, 120,
0, 220, 244, 240, 56, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 64, 0, 0, 0, 220, 247, 244, 57,
173, 115, 0, 0, 0, 77, 210, 0, 0, 0, 4, 233, 50, 0, 0, 0, 142, 146, 0, 0, 0, 46, 236, 5, 0, 0, 0, 207, 81, 0, 0, 0, 111, 177, 0, 0, 0, 20, 245, 21, 0, 0, 0, 176, 112, 0, 0, 0, 80, 208,
157, 240, 250, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 0, 0, 168, 116, 160, 244, 251, 116,
0, 0, 0, 181, 121, 0, 0, 0, 0, 0, 52, 190, 213, 19, 0, 0, 0, 0, 181, 62, 102, 143, 0, 0, 0, 52, 195, 0, 4, 211, 33, 0, 0, 181, 72, 0, 0, 87, 166, 0, 52, 204, 0, 0, 0, 1, 204, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 6, 212, 212, 212, 212, 212, 212, 33,
42, 237, 63, 0, 0, 48, 199, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 59, 191, 229, 231, 163, 8, 0, 34, 53, 2, 11, 196, 110, 0, 0, 0, 0, 0, 125, 156, 0, 44, 163, 203, 203, 228, 164, 23, 237, 99, 2, 0, 127, 164, 80, 224, 0, 0, 0, 165, 164, 55, 247, 39, 1, 80, 238, 164, 0, 121, 228, 231, 162, 81, 164,
0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 83, 0, 0, 0, 0, 0, 0, 204, 110, 190, 243, 224, 94, 0, 0, 204, 223, 46, 1, 67, 242, 48, 0, 204, 127, 0, 0, 0, 154, 150, 0, 204, 90, 0, 0, 0, 112, 184, 0, 204, 94, 0, 0, 0, 114, 188, 0, 204, 134, 0, 0, 0, 160, 150, 0, 204, 228, 55, 3, 72, 245, 53, 0, 204, 70, 197, 245, 221, 90, 0,
0, 6, 133, 228, 247, 214, 24, 0, 148, 198, 35, 6, 52, 0, 11, 247, 48, 0, 0, 0, 0, 44, 252, 1, 0, 0, 0, 0, 45, 251, 1, 0, 0, 0, 0, 13, 250, 47, 0, 0, 0, 0, 0, 160, 193, 29, 6, 50, 12, 0, 10, 148, 234, 248, 209, 20,
0, 0, 0, 0, 0, 0, 196, 92, 0, 0, 0, 0, 0, 0, 196, 92, 0, 0, 0, 0, 0, 0, 196, 92, 0, 15, 167, 242, 228, 127, 192, 92, 0, 158, 189, 19, 9, 134, 249, 92, 9, 251, 49, 0, 0, 6, 241, 92, 40, 253, 4, 0, 0, 0, 208, 92, 41, 252, 2, 0, 0, 0, 204, 92, 11, 253, 43, 0, 0, 4, 237, 92, 0, 164, 183, 19, 9, 130, 248, 92, 0, 15, 162, 236, 229, 124, 158, 92,
0, 5, 141, 232, 235, 167, 18, 0, 0, 144, 172, 12, 6, 166, 174, 0, 8, 245, 29, 0, 0, 44, 252, 10, 44, 255, 232, 232, 232, 233, 255, 30, 45, 253, 6, 0, 0, 0, 0, 0, 11, 247, 61, 0, 0, 0, 0, 0, 0, 147, 210, 45, 2, 23, 70, 0, 0, 5, 132, 227, 248, 228, 132, 0,
0, 2, 155, 240, 237, 45, 0, 80, 225, 17, 9, 2, 0, 117, 175, 0, 0, 0, 133, 233, 246, 228, 121, 0, 0, 120, 172, 0, 0, 0, 0, 120, 172, 0, 0, 0, 0, 120, 172, 0, 0, 0, 0, 120, 172, 0, 0, 0, 0, 120, 172, 0, 0, 0, 0, 120, 172, 0, 0, 0, 0, 120, 172, 0, 0, 0,
0, 66, 207, 220, 227, 220, 209, 62, 10, 241, 82, 0, 32, 242, 44, 0, 44, 255, 5, 0, 0, 201, 96, 0, 13, 245, 73, 0, 26, 238, 48, 0, 0, 82, 248, 214, 210, 96, 0, 0, 0, 168, 113, 0, 0, 0, 0, 0, 0, 133, 255, 255, 254, 226, 102, 0, 97, 204, 45, 16, 22, 86, 253, 23, 188, 103, 0, 0, 0, 2, 247, 45, 148, 173, 10, 0, 11, 136, 217, 3, 14, 158, 226, 225, 218, 151, 27, 0,
0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 111, 184, 237, 230, 119, 0, 0, 204, 224, 49, 0, 52, 247, 54, 0, 204, 128, 0, 0, 0, 185, 103, 0, 204, 89, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112,
0, 78, 27, 0, 192, 83, 0, 0, 0, 0, 204, 84, 0, 204, 84, 0, 204, 84, 0, 204, 84, 0, 204, 84, 0, 204, 84, 0, 204, 84, 0, 204, 84,
0, 0, 78, 27, 0, 0, 192, 83, 0, 0, 0, 0, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 84, 0, 0, 204, 82, 4, 17, 236, 50, 178, 244, 152, 1,
0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 84, 0, 0, 0, 0, 0, 0, 204, 84, 0, 5, 187, 151, 0, 0, 204, 84, 0, 160, 178, 3, 0, 0, 204, 83, 129, 201, 10, 0, 0, 0, 204, 153, 255, 54, 0, 0, 0, 0, 204, 216, 161, 195, 3, 0, 0, 0, 204, 85, 9, 214, 123, 0, 0, 0, 204, 84, 0, 50, 245, 53, 0, 0, 204, 84, 0, 0, 121, 218, 11,
0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88, 0, 204, 88,
0, 204, 81, 192, 243, 217, 68, 91, 220, 242, 185, 24, 0, 204, 220, 40, 6, 133, 240, 184, 21, 10, 181, 151, 0, 204, 124, 0, 0, 29, 255, 57, 0, 0, 87, 199, 0, 204, 88, 0, 0, 12, 255, 24, 0, 0, 76, 212, 0, 204, 84, 0, 0, 12, 255, 20, 0, 0, 76, 212, 0, 204, 84, 0, 0, 12, 255, 20, 0, 0, 76, 212, 0, 204, 84, 0, 0, 12, 255, 20, 0, 0, 76, 212, 0, 204, 84, 0, 0, 12, 255, 20, 0, 0, 76, 212,
0, 204, 73, 181, 240, 226, 111, 0, 0, 204, 225, 59, 2, 56, 246, 47, 0, 204, 133, 0, 0, 0, 186, 98, 0, 204, 93, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112, 0, 204, 84, 0, 0, 0, 172, 112,
0, 6, 139, 231, 242, 191, 46, 0, 0, 151, 195, 28, 3, 101, 235, 20, 11, 248, 50, 0, 0, 0, 192, 111, 45, 253, 4, 0, 0, 0, 141, 156, 37, 254, 8, 0, 0, 0, 153, 148, 4, 245, 50, 0, 0, 0, 198, 105, 0, 131, 191, 24, 3, 101, 232, 12, 0, 3, 127, 233, 244, 191, 38, 0,
0, 204, 80, 184, 239, 215, 89, 0, 0, 204, 222, 48, 2, 72, 245, 64, 0, 204, 131, 0, 0, 0, 156, 157, 0, 204, 93, 0, 0, 0, 108, 192, 0, 204, 95, 0, 0, 0, 117, 188, 0, 204, 135, 0, 0, 0, 161, 150, 0, 204, 228, 50, 0, 69, 246, 54, 0, 204, 115, 190, 241, 222, 92, 0, 0, 204, 87, 0, 0, 0, 0, 0, 0, 204, 88, 0, 0, 0, 0, 0, 0, 204, 88, 0, 0, 0, 0, 0,
0, 14, 164, 240, 231, 115, 159, 92, 0, 169, 186, 17, 9, 139, 247, 92, 15, 252, 47, 0, 0, 8, 242, 92, 50, 253, 3, 0, 0, 0, 208, 92, 45, 252, 2, 0, 0, 0, 202, 92, 14, 253, 42, 0, 0, 2, 236, 92, 0, 168, 180, 18, 6, 130, 247, 92, 0, 16, 165, 237, 230, 124, 196, 92, 0, 0, 0, 0, 0, 0, 200, 92, 0, 0, 0, 0, 0, 0, 200, 92, 0, 0, 0, 0, 0, 0, 200, 92,
0, 204, 61, 171, 245, 108, 0, 204, 217, 102, 18, 10, 0, 204, 157, 0, 0, 0, 0, 204, 98, 0, 0, 0, 0, 204, 88, 0, 0, 0, 0, 204, 88, 0, 0, 0, 0, 204, 88, 0, 0, 0, 0, 204, 88, 0, 0, 0,
0, 102, 218, 236, 225, 131, 0, 40, 237, 30, 0, 22, 47, 0, 51, 243, 37, 0, 0, 0, 0, 0, 125, 242, 163, 48, 0, 0, 0, 0, 24, 129, 240, 124, 0, 0, 0, 0, 0, 55, 252, 4, 34, 57, 5, 0, 96, 228, 0, 44, 203, 239, 238, 198, 56, 0,
0, 95, 108, 0, 0, 0, 159, 108, 0, 0, 144, 248, 239, 228, 142, 0, 184, 108, 0, 0, 0, 184, 108, 0, 0, 0, 184, 108, 0, 0, 0, 184, 108, 0, 0, 0, 182, 110, 0, 0, 0, 152, 174, 2, 5, 0, 35, 201, 240, 148,
0, 228, 68, 0, 0, 0, 196, 100, 0, 228, 68, 0, 0, 0, 196, 100, 0, 228, 68, 0, 0, 0, 196, 100, 0, 228, 68, 0, 0, 0, 196, 100, 0, 228, 68, 0, 0, 0, 201, 100, 0, 220, 81, 0, 0, 3, 236, 100, 0, 170, 181, 12, 8, 133, 248, 100, 0, 30, 190, 246, 228, 125, 157, 100,
211, 98, 0, 0, 0, 100, 209, 120, 185, 0, 0, 0, 188, 118, 30, 250, 20, 0, 23, 250, 28, 0, 194, 103, 0, 108, 191, 0, 0, 103, 190, 0, 195, 99, 0, 0, 18, 246, 43, 246, 16, 0, 0, 0, 177, 188, 172, 0, 0, 0, 0, 86, 255, 81, 0, 0,
180, 118, 0, 0, 79, 255, 52, 0, 0, 152, 142, 114, 181, 0, 0, 155, 223, 126, 0, 0, 216, 75, 48, 240, 2, 1, 230, 104, 199, 0, 23, 251, 13, 1, 235, 50, 53, 221, 7, 242, 19, 87, 198, 0, 0, 172, 112, 128, 144, 0, 180, 90, 150, 132, 0, 0, 106, 171, 195, 66, 0, 107, 160, 211, 65, 0, 0, 40, 228, 232, 4, 0, 34, 225, 244, 8, 0, 0, 0, 228, 166, 0, 0, 0, 217, 189, 0, 0,
72, 235, 21, 0, 0, 174, 150, 0, 0, 158, 167, 0, 81, 224, 12, 0, 0, 15, 228, 92, 228, 67, 0, 0, 0, 0, 74, 255, 154, 0, 0, 0, 0, 0, 105, 244, 184, 0, 0, 0, 0, 31, 238, 53, 209, 100, 0, 0, 0, 188, 133, 0, 53, 238, 29, 0, 103, 215, 7, 0, 0, 142, 185, 0,
202, 107, 0, 0, 0, 99, 211, 0, 100, 204, 0, 0, 0, 191, 115, 0, 12, 242, 44, 0, 28, 249, 23, 0, 0, 154, 140, 0, 119, 179, 0, 0, 0, 53, 232, 3, 208, 83, 0, 0, 0, 0, 208, 104, 236, 6, 0, 0, 0, 0, 107, 236, 147, 0, 0, 0, 0, 0, 22, 255, 51, 0, 0, 0, 0, 0, 86, 209, 0, 0, 0, 0, 0, 28, 218, 89, 0, 0, 0, 0, 207, 242, 129, 0, 0, 0, 0, 0,
42, 228, 228, 228, 238, 233, 0, 0, 0, 0, 0, 188, 127, 0, 0, 0, 0, 98, 211, 5, 0, 0, 0, 24, 236, 54, 0, 0, 0, 0, 173, 142, 0, 0, 0, 0, 82, 222, 10, 0, 0, 0, 16, 230, 68, 0, 0, 0, 0, 110, 252, 224, 224, 224, 224, 3,
0, 0, 60, 198, 188, 0, 0, 213, 129, 3, 0, 0, 236, 52, 0, 0, 0, 236, 51, 0, 1, 62, 247, 22, 0, 153, 242, 80, 0, 0, 8, 90, 238, 13, 0, 0, 0, 241, 49, 0, 0, 0, 236, 52, 0, 0, 0, 234, 55, 0, 0, 0, 195, 138, 5, 0, 0, 42, 195, 195,
0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80, 0, 0, 0, 164, 80,
133, 224, 103, 0, 0, 0, 63, 253, 23, 0, 0, 0, 244, 44, 0, 0, 0, 243, 44, 0, 0, 0, 210, 123, 4, 0, 0, 40, 220, 221, 0, 0, 185, 146, 16, 0, 0, 241, 49, 0, 0, 0, 244, 44, 0, 0, 1, 247, 42, 0, 1, 85, 246, 13, 0, 131, 208, 79, 0, 0,
12, 174, 234, 189, 76, 2, 74, 62, 65, 71, 1, 74, 191, 238, 173, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
constexpr dip::uint glyphOrigin[ nGlyphs ] = { 0, 0, 30, 80, 170, 250, 360, 470, 500, 548, 596, 684, 748, 757, 777, 783, 833, 913, 963, 1043, 1123, 1203, 1283, 1363, 1443, 1523, 1603, 1627, 1654, 1726, 1782, 1854, 1914, 2046, 2136, 2226, 2316, 2416, 2486, 2556, 2656, 2746, 2776, 2841, 2931, 3001, 3121, 3221, 3331, 3411, 3543, 3633, 3703, 3783, 3873, 3963, 4093, 4183, 4263, 4343, 4403, 4453, 4501, 4581, 4597, 4637, 4693, 4781, 4837, 4925, 4989, 5055, 5143, 5231, 5264, 5320, 5408, 5441, 5537, 5601, 5665, 5753, 5841, 5889, 5945, 5995, 6059, 6115, 6203, 6267, 6355, 6411, 6471, 6541, 6601, 0, };
constexpr dip::uint glyphWidth[ nGlyphs ] = { 0, 3, 5, 9, 8, 11, 11, 3, 4, 4, 8, 8, 3, 4, 3, 5, 8, 5, 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 8, 8, 8, 6, 12, 9, 9, 9, 10, 7, 7, 10, 9, 3, 5, 9, 7, 12, 10, 11, 8, 11, 9, 7, 8, 9, 9, 13, 9, 8, 8, 5, 5, 4, 8, 8, 4, 7, 8, 7, 8, 8, 6, 8, 8, 3, 4, 8, 3, 12, 8, 8, 8, 8, 6, 7, 5, 8, 7, 11, 8, 8, 7, 5, 5, 5, 8, 0, };
constexpr dip::uint glyphHeight[ nGlyphs ] = { 0, 10, 10, 10, 10, 10, 10, 10, 12, 12, 11, 8, 3, 5, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 9, 9, 7, 9, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 10, 10, 10, 10, 10, 10, 12, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 10, 12, 10, 2, 10, 8, 11, 8, 11, 8, 11, 11, 11, 11, 14, 11, 11, 8, 8, 8, 11, 11, 8, 8, 10, 8, 8, 8, 8, 11, 8, 12, 14, 12, 6, 0, };
constexpr dip::sint glyphShift[ nGlyphs ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
constexpr dip::sint glyphBaseline[ nGlyphs ] = { 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 7, 1, 4, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 8, 6, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -1, 9, 7, 10, 7, 10, 7, 10, 7, 10, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 9, 7, 7, 7, 7, 7, 7, 9, 10, 9, 5, 0, };
constexpr dip::sint glyphAdvance[ nGlyphs ] = { 4, 4, 6, 9, 8, 12, 10, 3, 4, 4, 8, 8, 4, 5, 4, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, 8, 6, 13, 9, 9, 9, 10, 8, 7, 10, 10, 4, 4, 9, 7, 13, 11, 11, 8, 11, 9, 8, 8, 10, 8, 13, 8, 8, 8, 5, 5, 5, 8, 6, 4, 8, 9, 7, 9, 8, 5, 8, 9, 4, 4, 7, 4, 13, 9, 8, 9, 9, 6, 7, 5, 9, 7, 11, 7, 7, 7, 5, 8, 5, 8, 0, };
struct GlyphData {
Image image;
dip::sint shift;
dip::sint baseline;
dip::sint advance;
};
dip::uint GetGlyphIndex( char ch ) {
dip::uint index = static_cast< dip::uint >( ch ) - beginChar;
if( index >= nGlyphs ) {
index = nGlyphs - 1; // Any character we don't have a glyph for, we represent as a zero-width character
}
return index;
}
GlyphData GetGlyphData( char ch ) {
dip::uint index = GetGlyphIndex( ch );
GlyphData glyphData {
Image{},
glyphShift[ index ],
glyphBaseline[ index ],
glyphAdvance[ index ],
};
if( index > 0 ) { // If index == 0, it's a space, for which we don't have pixel data; the image will be raw.
glyphData.image = Image( glyphImage + glyphOrigin[ index ], { glyphWidth[ index ], glyphHeight[ index ] } );
}
return glyphData;
}
dip::sint GetTextLength( String const& text ) {
dip::sint len = 0;
for( auto ch : text ) {
dip::uint index = GetGlyphIndex( ch );
len += glyphAdvance[ index ];
}
return len;
}
VertexFloat Rotate( VertexFloat pt, VertexFloat unit ) {
return { unit.x * pt.x - unit.y * pt.y,
unit.x * pt.y + unit.y * pt.x };
}
BoundingBoxFloat GetTextBoundingBox( String const& text, dfloat orientation ) {
VertexFloat advanceScale{ std::cos( orientation ), std::sin( orientation ) };
BoundingBoxFloat boundingBox;
VertexFloat pen{ 0, 0 };
for( auto ch : text ) {
auto glyphData = GetGlyphData( ch );
if( glyphData.image.IsForged() ) {
// Origin of the glyph
VertexFloat origin{static_cast< dfloat >( glyphData.shift ), static_cast< dfloat >( glyphData.baseline ) };
// Image box
VertexFloat topLeft{ -origin.x, -origin.y };
VertexFloat bottomRight{
static_cast< dfloat >( glyphData.image.Size( 0 )) - origin.x - 1,
static_cast< dfloat >( glyphData.image.Size( 1 )) - origin.y - 1
};
VertexFloat topRight{ bottomRight.x, topLeft.y };
VertexFloat bottomLeft{ topLeft.x, bottomRight.y };
// Rotate box
if( orientation != 0 ) {
topLeft = Rotate( topLeft, advanceScale );
bottomRight = Rotate( bottomRight, advanceScale );
topRight = Rotate( topRight, advanceScale );
bottomLeft = Rotate( bottomLeft, advanceScale );
}
// Add pen position
topLeft += pen;
bottomRight += pen;
topRight += pen;
bottomLeft += pen;
boundingBox.Expand( topLeft );
boundingBox.Expand( bottomRight );
boundingBox.Expand( topRight );
boundingBox.Expand( bottomLeft );
} else {
boundingBox.Expand( pen );
}
pen += advanceScale * static_cast< dfloat >( glyphData.advance );
}
return boundingBox;
}
} // namespace
void DrawText(
Image& out,
String const& text,
FloatArray origin,
Image::Pixel const& value,
dfloat orientation,
String const& align
) {
DIP_THROW_IF( !out.IsForged(), E::IMAGE_NOT_FORGED );
DIP_THROW_IF( out.Dimensionality() != 2, E::DIMENSIONALITY_NOT_SUPPORTED );
DIP_THROW_IF( origin.size() != 2, E::ARRAY_PARAMETER_WRONG_LENGTH );
DIP_THROW_IF( !value.IsScalar() && ( value.TensorElements() != out.TensorElements() ), E::NTENSORELEM_DONT_MATCH );
dfloat advanceScaleX = std::cos( orientation );
dfloat advanceScaleY = std::sin( orientation );
if( align != S::LEFT ) {
dfloat length = static_cast< dfloat >( GetTextLength( text ));
if( align == S::CENTER ) {
origin[ 0 ] -= advanceScaleX * length / 2.0;
origin[ 1 ] -= advanceScaleY * length / 2.0;
} else if( align == S::RIGHT ) {
origin[ 0 ] -= advanceScaleX * length;
origin[ 1 ] -= advanceScaleY * length;
} else {
DIP_THROW_INVALID_FLAG( align );
}
}
for( auto ch : text ) {
auto glyphData = GetGlyphData( ch );
if( glyphData.image.IsForged() ) {
dfloat xpos = static_cast< dfloat >( glyphData.shift );
dfloat ypos = static_cast< dfloat >( glyphData.baseline );
if( orientation != 0 ) {
auto c0 = glyphData.image.GetCenter();
xpos -= c0[ 0 ];
ypos -= c0[ 1 ];
dfloat tmp = advanceScaleX * xpos - advanceScaleY * ypos;
ypos = advanceScaleX * ypos + advanceScaleY * xpos;
xpos = tmp;
glyphData.image = Rotation2D( glyphData.image, orientation );
auto c1 = glyphData.image.GetCenter();
xpos += c1[ 0 ];
ypos += c1[ 1 ];
}
IntegerArray pos{ round_cast( origin[ 0 ] - xpos ), round_cast( origin[ 1 ] - ypos ) };
BlendBandlimitedMask( out, glyphData.image, dip::Image( value ), pos );
}
origin[ 0 ] += advanceScaleX * static_cast< dfloat >( glyphData.advance );
origin[ 1 ] += advanceScaleY * static_cast< dfloat >( glyphData.advance );
}
}
Image DrawText(
String const& text,
dfloat orientation
) {
// Figure out what size image we need for this text
BoundingBoxFloat boundingBox = GetTextBoundingBox( text, orientation );
// Create output image
auto sz = boundingBox.bottomRight - boundingBox.topLeft + 1;
Image out( { static_cast< dip::uint >( std::round( sz.x )),
static_cast< dip::uint >( std::round( sz.y )) }, 1, DT_UINT8 );
out.Fill( 0 );
// Figure out the origin
FloatArray origin{ -boundingBox.topLeft.x, -boundingBox.topLeft.y };
// Draw the text
DrawText( out, text, origin, { 255 }, orientation );
return out; // TODO: Do we want to return a dip::FreeTypeTool::TextInfo object? (of course we'd move the class out of FreeTypeTool)
}
} // namespace dip