Mirai's Miscellaneous Misadventures
M35 / core / text.c
1
2
3
4#include <mimimi/chapters.h>
5#include <mimimi/fonts.h>
6#include <mimimi/assets.h>
7
8static int mimimi_stamp_glyph(int stamp, struct mimimi_image *target, int x0, int y0, struct mimimi_font *font, unsigned char color, unsigned long int cp)
9{
10 if (cp == 0x20) return 4;
11
12 unsigned long int a = cp >> 8;
13 unsigned long int b = cp & 0xFF;
14
15 unsigned long int i = font->indices[a] * 0x100 + b;
16
17 int width = 0;
18 for (int x = 0 ; x < 8 ; x++)
19 for (int y = 0 ; y < 16 ; y++)
20 {
21 if ((font->glyphs[i][y] >> (8 - x) & 1) != 0)
22 width = x + 1;
23 }
24
25 if (stamp == 0) return width;
26
27 for (int x1 = 0 ; x1 < width ; x1++)
28 for (int y1 = 0 ; y1 < 16 ; y1++)
29 {
30 int x = x0 + x1 - 1;
31 int y = y0 + y1 - 10;
32
33 if (x < 0) continue;
34 if (y < 0) continue;
35
36 if (x >= target->width) break;
37 if (y >= target->height) return width;
38
39 if ((font->glyphs[i][y1] >> (8 - x1) & 1) == 0) continue;
40
41 target->colors[x + y * target->width] = color;
42 }
43
44 return width;
45}
46
47
48
49
50static unsigned long int mimimi_utf8(char **text)
51{
52 unsigned char ch = text[0][0];
53 if ((ch & 0x80) == 0x00)
54 {
55 text[0] += 1;
56 return ch;
57 }
58
59 unsigned char ch1 = text[0][1];
60 if ((ch & 0xE0) == 0xC0)
61 {
62 unsigned long int cp = ch;
63 cp &= ~0xC0;
64 cp <<= 6;
65 cp |= ch1 & ~0x80;
66 text[0] += 2;
67 return cp;
68 }
69
70 unsigned char ch2 = text[0][2];
71 if ((ch & 0xF0) == 0xE0)
72 {
73 unsigned long int cp = ch;
74 cp &= ~0xE0;
75 cp <<= 6;
76 cp |= ch1 & ~0x80;
77 cp <<= 6;
78 cp |= ch2 & ~0x80;
79 text[0] += 3;
80 return cp;
81 }
82
83 unsigned char ch3 = text[0][3];
84 if ((ch & 0xF8) == 0xF0)
85 {
86 unsigned long int cp = ch;
87 cp &= ~0xF0;
88 cp <<= 6;
89 cp |= ch1 & ~0x80;
90 cp <<= 6;
91 cp |= ch2 & ~0x80;
92 cp <<= 6;
93 cp |= ch3 & ~0x80;
94 text[0] += 4;
95 return cp;
96 }
97
98 return 0;
99}
100
101static int mimimi_measure_text_until(struct mimimi_font *font, char **text, unsigned long int last, unsigned long int last2)
102{
103 int x = 0;
104 for (;;)
105 {
106 if (**text == 0) break;
107 unsigned long int cp = mimimi_utf8(text);
108 if (cp == last) break;
109 if (cp == last2) break;
110 x += mimimi_stamp_glyph(0, 0, x, 0, font, 0, cp);
111 }
112 return x;
113}
114
115int mimimi_text_until(struct mimimi_image *image, struct mimimi_font *font, unsigned char color, int x, int y, char **text, unsigned long int last, unsigned long int last2)
116{
117 for (;;)
118 {
119 if (**text == 0) break;
120 unsigned long int cp = mimimi_utf8(text);
121 if (cp == last) break;
122 if (cp == last2) break;
123 x += mimimi_stamp_glyph(1, image, x, y, font, color, cp);
124 }
125 return x;
126}
127
128int mimimi_measure_text(struct mimimi_font *font, char *text)
129{
130 return mimimi_measure_text_until(font, &text, 0, 0);
131}
132
133int mimimi_text(struct mimimi_image *image, struct mimimi_font *font, unsigned char color, int x, int y, char *text)
134{
135 return mimimi_text_until(image, font, color, x, y, &text, 0, 0);
136}
137
138int mimimi_measure_word(struct mimimi_font *font, char **text)
139{
140 return mimimi_measure_text_until(font, text, 0x20, 0x0A);
141}
142
143int mimimi_word(struct mimimi_image *image, struct mimimi_font *font, unsigned char color, int x, int y, char **text)
144{
145 return mimimi_text_until(image, font, color, x, y, text, 0x20, 0x0A);
146}
147
148static int mimimi_stamp_line(int stamp, struct mimimi_image *image, struct mimimi_font *font, unsigned char color, int x, int y, int width, char **text)
149{
150 width += x;
151 int sp = mimimi_measure_text(font, " ");
152 for (;;)
153 {
154 char *text1 = *text;
155 int n = mimimi_measure_text_until(font, &text1, 0x20, 0x0A);
156
157 if (x + n > width) return x;
158
159 if (stamp == 0) *text = text1;
160 else mimimi_text_until(image, font, color, x, y, text, 0x20, 0x0A);
161
162 if (**text == 0) return x + n;
163 if ((*text)[-1] == 0x0A) return x + n;
164
165 while (**text == 0x20) mimimi_utf8(text);
166
167 x += n + sp;
168 }
169}
170
171int mimimi_measure_line(struct mimimi_font *font, int width, char **text)
172{
173 return mimimi_stamp_line(0, 0, font, 0, 0, 0, width, text);
174}
175
176int mimimi_line(struct mimimi_image *image, struct mimimi_font *font, unsigned char color, int x, int y, int width, char **text)
177{
178 return mimimi_stamp_line(1, image, font, color, x, y, width, text);
179}
180
181int mimimi_count_lines(struct mimimi_font *font, int width, char *text)
182{
183 int count = 0;
184 for (;;)
185 {
186 char *text1 = text;
187 mimimi_measure_line(font, width, &text);
188 if (text == text1) mimimi_measure_word(font, &text);
189 if (*text == 0) return count;
190 count++;
191 }
192}
193
194void mimimi_lines(struct mimimi_image *image, struct mimimi_font *font, unsigned char color, int x, int y, int width, int height, char *text)
195{
196 for (;;)
197 {
198 char *text1 = text;
199 mimimi_line(image, font, color, x, y, width, &text);
200 if (text == text1) mimimi_word(image, font, color, x, y, &text);
201 if (*text == 0) return;
202 y += height;
203 }
204}