source: mainline/uspace/lib/gfxfont/test/text.c

Last change on this file was 1fa6292, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 5 months ago

Remove a ton of duplicated code in libui/libgfxfont tests

  • Property mode set to 100644
File size: 10.1 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <gfx/color.h>
30#include <gfx/context.h>
31#include <gfx/font.h>
32#include <gfx/glyph.h>
33#include <gfx/text.h>
34#include <gfx/typeface.h>
35#include <pcut/pcut.h>
36#include "../private/font.h"
37#include "../private/typeface.h"
38#include "../private/testgc.h"
39
40PCUT_INIT;
41
42PCUT_TEST_SUITE(text);
43
44/** Test text width computation with a dummy font */
45PCUT_TEST(dummy_text_width)
46{
47 gfx_font_props_t props;
48 gfx_font_metrics_t metrics;
49 gfx_typeface_t *tface;
50 gfx_font_t *font;
51 gfx_context_t *gc;
52 gfx_coord_t width;
53 test_gc_t tgc;
54 errno_t rc;
55
56 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
57 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
58
59 rc = gfx_typeface_create(gc, &tface);
60 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
61
62 gfx_font_props_init(&props);
63 gfx_font_metrics_init(&metrics);
64 rc = gfx_font_create(tface, &props, &metrics, &font);
65 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
66
67 width = gfx_text_width(font, "Hello world!");
68 PCUT_ASSERT_INT_EQUALS(0, width);
69
70 gfx_font_close(font);
71 gfx_typeface_destroy(tface);
72
73 rc = gfx_context_delete(gc);
74 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
75}
76
77/** Test text rendering with a dummy font */
78PCUT_TEST(dummy_puttext)
79{
80 gfx_font_props_t props;
81 gfx_font_metrics_t metrics;
82 gfx_typeface_t *tface;
83 gfx_font_t *font;
84 gfx_context_t *gc;
85 gfx_color_t *color;
86 gfx_text_fmt_t fmt;
87 gfx_coord2_t pos;
88 test_gc_t tgc;
89 errno_t rc;
90
91 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
92 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
93
94 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
95 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
96
97 rc = gfx_typeface_create(gc, &tface);
98 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
99
100 gfx_font_props_init(&props);
101 gfx_font_metrics_init(&metrics);
102 rc = gfx_font_create(tface, &props, &metrics, &font);
103 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
104
105 gfx_text_fmt_init(&fmt);
106 fmt.font = font;
107 fmt.color = color;
108 pos.x = 0;
109 pos.y = 0;
110
111 rc = gfx_puttext(&pos, &fmt, "Hello world!");
112 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
113
114 gfx_font_close(font);
115 gfx_typeface_destroy(tface);
116 gfx_color_delete(color);
117
118 rc = gfx_context_delete(gc);
119 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
120}
121
122/** gfx_text_start_pos() correctly computes text start position */
123PCUT_TEST(text_start_pos)
124{
125 gfx_font_props_t props;
126 gfx_font_metrics_t metrics;
127 gfx_typeface_t *tface;
128 gfx_font_t *font;
129 gfx_context_t *gc;
130 gfx_color_t *color;
131 gfx_text_fmt_t fmt;
132 gfx_coord2_t pos;
133 test_gc_t tgc;
134 errno_t rc;
135
136 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
137 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
138
139 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
140 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
141
142 rc = gfx_typeface_create(gc, &tface);
143 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
144
145 gfx_font_props_init(&props);
146 gfx_font_metrics_init(&metrics);
147 metrics.ascent = 10; // XXX
148 metrics.descent = 10; // XXX
149 rc = gfx_font_create(tface, &props, &metrics, &font);
150 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
151
152 gfx_text_fmt_init(&fmt);
153 fmt.font = font;
154 fmt.color = color;
155 pos.x = 0;
156 pos.y = 0;
157
158 rc = gfx_puttext(&pos, &fmt, "Hello world!");
159 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
160
161 gfx_font_close(font);
162 gfx_typeface_destroy(tface);
163 gfx_color_delete(color);
164
165 rc = gfx_context_delete(gc);
166 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
167}
168
169/** gfx_text_find_pos() finds position in text */
170PCUT_TEST(text_find_pos)
171{
172 gfx_font_props_t props;
173 gfx_font_metrics_t metrics;
174 gfx_typeface_t *tface;
175 gfx_font_t *font;
176 gfx_glyph_metrics_t gmetrics;
177 gfx_glyph_t *glyph1;
178 gfx_glyph_t *glyph2;
179 gfx_context_t *gc;
180 gfx_text_fmt_t fmt;
181 gfx_coord2_t anchor;
182 gfx_coord2_t fpos;
183 size_t off;
184 test_gc_t tgc;
185 errno_t rc;
186
187 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
188 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
189
190 rc = gfx_typeface_create(gc, &tface);
191 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
192
193 gfx_font_props_init(&props);
194 gfx_font_metrics_init(&metrics);
195 rc = gfx_font_create(tface, &props, &metrics, &font);
196 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
197
198 /* Need to create some glyphs with metrics */
199 gfx_glyph_metrics_init(&gmetrics);
200 gmetrics.advance = 10;
201
202 rc = gfx_glyph_create(font, &gmetrics, &glyph1);
203 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
204
205 rc = gfx_glyph_set_pattern(glyph1, "A");
206 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
207
208 gfx_glyph_metrics_init(&gmetrics);
209 gmetrics.advance = 1;
210
211 rc = gfx_glyph_create(font, &gmetrics, &glyph2);
212 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
213
214 rc = gfx_glyph_set_pattern(glyph2, "i");
215 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
216
217 gfx_text_fmt_init(&fmt);
218 fmt.font = font;
219 anchor.x = 10;
220 anchor.y = 0;
221
222 fpos.x = 9;
223 fpos.y = 0;
224 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
225 PCUT_ASSERT_INT_EQUALS(0, off);
226
227 fpos.x = 10;
228 fpos.y = 0;
229 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
230 PCUT_ASSERT_INT_EQUALS(0, off);
231
232 fpos.x = 11;
233 fpos.y = 0;
234 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
235 PCUT_ASSERT_INT_EQUALS(0, off);
236
237 fpos.x = 19;
238 fpos.y = 0;
239 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
240 PCUT_ASSERT_INT_EQUALS(1, off);
241
242 fpos.x = 20;
243 fpos.y = 0;
244 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
245 PCUT_ASSERT_INT_EQUALS(2, off);
246
247 fpos.x = 21;
248 fpos.y = 0;
249 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
250 PCUT_ASSERT_INT_EQUALS(3, off);
251
252 fpos.x = 22;
253 fpos.y = 0;
254 off = gfx_text_find_pos(&anchor, &fmt, "Aii", &fpos);
255 PCUT_ASSERT_INT_EQUALS(3, off);
256
257 gfx_glyph_destroy(glyph1);
258 gfx_glyph_destroy(glyph2);
259
260 gfx_font_close(font);
261 gfx_typeface_destroy(tface);
262
263 rc = gfx_context_delete(gc);
264 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
265}
266
267/** gfx_text_find_pos() finds position in text in text mode */
268PCUT_TEST(text_find_pos_text)
269{
270 gfx_typeface_t *tface;
271 gfx_font_t *font;
272 gfx_context_t *gc;
273 test_gc_t tgc;
274 size_t off;
275 gfx_text_fmt_t fmt;
276 gfx_coord2_t anchor;
277 gfx_coord2_t fpos;
278 errno_t rc;
279
280 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
281 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
282
283 rc = gfx_typeface_create(gc, &tface);
284 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
285
286 rc = gfx_font_create_textmode(tface, &font);
287 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
288
289 anchor.x = 10;
290 anchor.y = 0;
291 gfx_text_fmt_init(&fmt);
292 fmt.font = font;
293
294 fpos.x = 9;
295 fpos.y = 0;
296 off = gfx_text_find_pos(&anchor, &fmt, "Abc", &fpos);
297 PCUT_ASSERT_INT_EQUALS(0, off);
298
299 fpos.x = 10;
300 fpos.y = 0;
301 off = gfx_text_find_pos(&anchor, &fmt, "Abc", &fpos);
302 PCUT_ASSERT_INT_EQUALS(0, off);
303
304 fpos.x = 11;
305 fpos.y = 0;
306 off = gfx_text_find_pos(&anchor, &fmt, "Abc", &fpos);
307 PCUT_ASSERT_INT_EQUALS(1, off);
308
309 fpos.x = 12;
310 fpos.y = 0;
311 off = gfx_text_find_pos(&anchor, &fmt, "Abc", &fpos);
312 PCUT_ASSERT_INT_EQUALS(2, off);
313
314 fpos.x = 13;
315 fpos.y = 0;
316 off = gfx_text_find_pos(&anchor, &fmt, "Abc", &fpos);
317 PCUT_ASSERT_INT_EQUALS(3, off);
318
319 fpos.x = 14;
320 fpos.y = 0;
321 off = gfx_text_find_pos(&anchor, &fmt, "Abc", &fpos);
322 PCUT_ASSERT_INT_EQUALS(3, off);
323
324 gfx_font_close(font);
325 gfx_typeface_destroy(tface);
326
327 rc = gfx_context_delete(gc);
328 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
329}
330
331/** gfx_text_cont() produces correct continuation parameters */
332PCUT_TEST(text_cont)
333{
334 gfx_typeface_t *tface;
335 gfx_font_t *font;
336 gfx_context_t *gc;
337 gfx_color_t *color;
338 test_gc_t tgc;
339 gfx_text_fmt_t fmt;
340 gfx_coord2_t anchor;
341 gfx_coord2_t cpos;
342 gfx_text_fmt_t cfmt;
343 errno_t rc;
344
345 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
346 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
347
348 rc = gfx_typeface_create(gc, &tface);
349 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
350
351 rc = gfx_font_create_textmode(tface, &font);
352 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
353
354 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
355 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
356
357 anchor.x = 10;
358 anchor.y = 20;
359 gfx_text_fmt_init(&fmt);
360 fmt.font = font;
361 fmt.color = color;
362
363 gfx_text_cont(&anchor, &fmt, "Abc", &cpos, &cfmt);
364
365 PCUT_ASSERT_INT_EQUALS(13, cpos.x);
366 PCUT_ASSERT_INT_EQUALS(20, cpos.y);
367 PCUT_ASSERT_EQUALS(fmt.color, cfmt.color);
368 PCUT_ASSERT_EQUALS(gfx_halign_left, cfmt.halign);
369 PCUT_ASSERT_EQUALS(gfx_valign_baseline, cfmt.valign);
370
371 gfx_font_close(font);
372 gfx_typeface_destroy(tface);
373 gfx_color_delete(color);
374
375 rc = gfx_context_delete(gc);
376 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
377}
378
379/** gfx_text_rect() computes bounding rectangle */
380PCUT_TEST(text_rect)
381{
382 gfx_typeface_t *tface;
383 gfx_font_t *font;
384 gfx_context_t *gc;
385 gfx_color_t *color;
386 test_gc_t tgc;
387 gfx_text_fmt_t fmt;
388 gfx_coord2_t anchor;
389 gfx_rect_t rect;
390 errno_t rc;
391
392 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
393 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
394
395 rc = gfx_typeface_create(gc, &tface);
396 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
397
398 rc = gfx_font_create_textmode(tface, &font);
399 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
400
401 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
402 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
403
404 anchor.x = 10;
405 anchor.y = 20;
406 gfx_text_fmt_init(&fmt);
407 fmt.font = font;
408 fmt.color = color;
409
410 gfx_text_rect(&anchor, &fmt, "Abc", &rect);
411
412 PCUT_ASSERT_INT_EQUALS(10, rect.p0.x);
413 PCUT_ASSERT_INT_EQUALS(20, rect.p0.y);
414 PCUT_ASSERT_INT_EQUALS(13, rect.p1.x);
415 PCUT_ASSERT_INT_EQUALS(21, rect.p1.y);
416
417 gfx_font_close(font);
418 gfx_typeface_destroy(tface);
419 gfx_color_delete(color);
420
421 rc = gfx_context_delete(gc);
422 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
423}
424
425PCUT_EXPORT(text);
Note: See TracBrowser for help on using the repository browser.