source: mainline/uspace/lib/gfxfont/test/font.c@ ea459d4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ea459d4 was 313ac8e, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Make negative quadrants actually work

  • Property mode set to 100644
File size: 11.0 KB
Line 
1/*
2 * Copyright (c) 2020 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/context.h>
30#include <gfx/font.h>
31#include <gfx/glyph.h>
32#include <gfx/typeface.h>
33#include <pcut/pcut.h>
34#include "../private/font.h"
35#include "../private/typeface.h"
36
37PCUT_INIT;
38
39PCUT_TEST_SUITE(font);
40
41static errno_t testgc_set_color(void *, gfx_color_t *);
42static errno_t testgc_fill_rect(void *, gfx_rect_t *);
43static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
44 gfx_bitmap_alloc_t *, void **);
45static errno_t testgc_bitmap_destroy(void *);
46static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
47static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
48
49static gfx_context_ops_t test_ops = {
50 .set_color = testgc_set_color,
51 .fill_rect = testgc_fill_rect,
52 .bitmap_create = testgc_bitmap_create,
53 .bitmap_destroy = testgc_bitmap_destroy,
54 .bitmap_render = testgc_bitmap_render,
55 .bitmap_get_alloc = testgc_bitmap_get_alloc
56};
57
58typedef struct {
59 gfx_bitmap_params_t bm_params;
60 void *bm_pixels;
61 gfx_rect_t bm_srect;
62 gfx_coord2_t bm_offs;
63} test_gc_t;
64
65typedef struct {
66 test_gc_t *tgc;
67 gfx_bitmap_alloc_t alloc;
68 bool myalloc;
69} testgc_bitmap_t;
70
71/** Test creating and destroying font */
72PCUT_TEST(create_destroy)
73{
74 gfx_font_props_t props;
75 gfx_font_metrics_t metrics;
76 gfx_typeface_t *tface;
77 gfx_font_t *font;
78 gfx_context_t *gc;
79 test_gc_t tgc;
80 errno_t rc;
81
82 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
83 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
84
85 rc = gfx_typeface_create(gc, &tface);
86 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
87
88 gfx_font_props_init(&props);
89 gfx_font_metrics_init(&metrics);
90 rc = gfx_font_create(tface, &props, &metrics, &font);
91 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
92
93 gfx_font_close(font);
94 gfx_typeface_destroy(tface);
95
96 rc = gfx_context_delete(gc);
97 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
98}
99
100/** Test gfx_font_get_metrics() */
101PCUT_TEST(get_metrics)
102{
103 gfx_font_props_t props;
104 gfx_font_metrics_t metrics;
105 gfx_font_metrics_t gmetrics;
106 gfx_typeface_t *tface;
107 gfx_font_t *font;
108 gfx_context_t *gc;
109 test_gc_t tgc;
110 errno_t rc;
111
112 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
113 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
114
115 gfx_font_metrics_init(&metrics);
116 metrics.ascent = 1;
117 metrics.descent = 2;
118 metrics.leading = 3;
119
120 rc = gfx_typeface_create(gc, &tface);
121 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
122
123 gfx_font_props_init(&props);
124 gfx_font_metrics_init(&metrics);
125 rc = gfx_font_create(tface, &props, &metrics, &font);
126 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
127
128 gfx_font_get_metrics(font, &gmetrics);
129 PCUT_ASSERT_INT_EQUALS(metrics.ascent, gmetrics.ascent);
130 PCUT_ASSERT_INT_EQUALS(metrics.descent, gmetrics.descent);
131 PCUT_ASSERT_INT_EQUALS(metrics.leading, gmetrics.leading);
132
133 gfx_font_close(font);
134 gfx_typeface_destroy(tface);
135 rc = gfx_context_delete(gc);
136 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
137}
138
139/** Test gfx_font_set_metrics() */
140PCUT_TEST(set_metrics)
141{
142 gfx_font_props_t props;
143 gfx_font_metrics_t metrics1;
144 gfx_font_metrics_t metrics2;
145 gfx_font_metrics_t gmetrics;
146 gfx_typeface_t *tface;
147 gfx_font_t *font;
148 gfx_context_t *gc;
149 test_gc_t tgc;
150 errno_t rc;
151
152 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
153 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
154
155 rc = gfx_typeface_create(gc, &tface);
156 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
157
158 gfx_font_props_init(&props);
159
160 gfx_font_metrics_init(&metrics1);
161 metrics1.ascent = 1;
162 metrics1.descent = 2;
163 metrics1.leading = 3;
164
165 rc = gfx_font_create(tface, &props, &metrics1, &font);
166 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
167
168 gfx_font_metrics_init(&metrics2);
169 metrics1.ascent = 4;
170 metrics1.descent = 5;
171 metrics1.leading = 6;
172
173 rc = gfx_font_set_metrics(font, &metrics2);
174 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
175
176 gfx_font_get_metrics(font, &gmetrics);
177 PCUT_ASSERT_INT_EQUALS(metrics2.ascent, gmetrics.ascent);
178 PCUT_ASSERT_INT_EQUALS(metrics2.descent, gmetrics.descent);
179 PCUT_ASSERT_INT_EQUALS(metrics2.leading, gmetrics.leading);
180
181 gfx_font_close(font);
182 gfx_typeface_destroy(tface);
183 rc = gfx_context_delete(gc);
184 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
185}
186
187/** Test gfx_font_first_glyph() */
188PCUT_TEST(first_glyph)
189{
190 gfx_font_props_t props;
191 gfx_font_metrics_t metrics;
192 gfx_glyph_metrics_t gmetrics;
193 gfx_typeface_t *tface;
194 gfx_font_t *font;
195 gfx_context_t *gc;
196 gfx_glyph_t *glyph;
197 gfx_glyph_t *gfirst;
198 test_gc_t tgc;
199 errno_t rc;
200
201 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
202 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
203
204 gfx_font_metrics_init(&metrics);
205
206 rc = gfx_typeface_create(gc, &tface);
207 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
208
209 gfx_font_props_init(&props);
210 gfx_font_metrics_init(&metrics);
211 rc = gfx_font_create(tface, &props, &metrics, &font);
212 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
213
214 /* Should get NULL since there is no glyph in the font */
215 glyph = gfx_font_first_glyph(font);
216 PCUT_ASSERT_NULL(glyph);
217
218 /* Now add one */
219 gfx_glyph_metrics_init(&gmetrics);
220 rc = gfx_glyph_create(font, &gmetrics, &glyph);
221 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
222
223 /* gfx_font_first_glyph() should return the same */
224 gfirst = gfx_font_first_glyph(font);
225 PCUT_ASSERT_EQUALS(glyph, gfirst);
226
227 gfx_glyph_destroy(glyph);
228 gfx_font_close(font);
229 gfx_typeface_destroy(tface);
230 rc = gfx_context_delete(gc);
231 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
232}
233
234/** Test gfx_font_next_glyph() */
235PCUT_TEST(next_glyph)
236{
237 gfx_font_props_t props;
238 gfx_font_metrics_t metrics;
239 gfx_glyph_metrics_t gmetrics;
240 gfx_typeface_t *tface;
241 gfx_font_t *font;
242 gfx_context_t *gc;
243 gfx_glyph_t *glyph1;
244 gfx_glyph_t *glyph2;
245 gfx_glyph_t *gfirst;
246 gfx_glyph_t *gsecond;
247 test_gc_t tgc;
248 errno_t rc;
249
250 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
251 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
252
253 gfx_font_metrics_init(&metrics);
254
255 rc = gfx_typeface_create(gc, &tface);
256 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
257
258 gfx_font_props_init(&props);
259 gfx_font_metrics_init(&metrics);
260 rc = gfx_font_create(tface, &props, &metrics, &font);
261 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
262
263 /* Add first glyph */
264 gfx_glyph_metrics_init(&gmetrics);
265 rc = gfx_glyph_create(font, &gmetrics, &glyph1);
266 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
267
268 /* Add second glyph */
269 gfx_glyph_metrics_init(&gmetrics);
270 rc = gfx_glyph_create(font, &gmetrics, &glyph2);
271 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
272
273 /* gfx_font_first_glyph() should return glyph1 */
274 gfirst = gfx_font_first_glyph(font);
275 PCUT_ASSERT_EQUALS(glyph1, gfirst);
276
277 /* gfx_font_next_glyph() should return glyph2 */
278 gsecond = gfx_font_next_glyph(gfirst);
279 PCUT_ASSERT_EQUALS(glyph2, gsecond);
280
281 gfx_glyph_destroy(glyph1);
282 gfx_glyph_destroy(glyph2);
283 gfx_font_close(font);
284 gfx_typeface_destroy(tface);
285 rc = gfx_context_delete(gc);
286 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
287}
288
289/** Test gfx_font_search_glyph() */
290PCUT_TEST(search_glyph)
291{
292 gfx_font_props_t props;
293 gfx_font_metrics_t metrics;
294 gfx_typeface_t *tface;
295 gfx_font_t *font;
296 gfx_context_t *gc;
297 gfx_glyph_t *glyph;
298 size_t bytes;
299 test_gc_t tgc;
300 errno_t rc;
301
302 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
303 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
304
305 gfx_font_metrics_init(&metrics);
306
307 rc = gfx_typeface_create(gc, &tface);
308 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
309
310 gfx_font_props_init(&props);
311 gfx_font_metrics_init(&metrics);
312 rc = gfx_font_create(tface, &props, &metrics, &font);
313 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
314
315 rc = gfx_font_search_glyph(font, "Hello", &glyph, &bytes);
316 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
317
318 gfx_font_close(font);
319 gfx_typeface_destroy(tface);
320 rc = gfx_context_delete(gc);
321 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
322}
323
324/** Test gfx_font_splice_at_glyph() */
325PCUT_TEST(splice_at_glyph)
326{
327 gfx_font_props_t props;
328 gfx_font_metrics_t fmetrics;
329 gfx_typeface_t *tface;
330 gfx_font_t *font;
331 gfx_glyph_metrics_t gmetrics;
332 gfx_glyph_t *glyph;
333 gfx_context_t *gc;
334 gfx_rect_t nrect;
335 test_gc_t tgc;
336 errno_t rc;
337
338 rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
339 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
340
341 rc = gfx_typeface_create(gc, &tface);
342 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
343
344 gfx_font_props_init(&props);
345 gfx_font_metrics_init(&fmetrics);
346 rc = gfx_font_create(tface, &props, &fmetrics, &font);
347 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
348
349 gfx_glyph_metrics_init(&gmetrics);
350 rc = gfx_glyph_create(font, &gmetrics, &glyph);
351 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
352
353 nrect.p0.x = -5;
354 nrect.p0.y = -5;
355 nrect.p1.x = 5;
356 nrect.p1.y = 5;
357 rc = gfx_font_splice_at_glyph(font, glyph, &nrect);
358 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
359
360 gfx_glyph_destroy(glyph);
361
362 gfx_font_close(font);
363 gfx_typeface_destroy(tface);
364 rc = gfx_context_delete(gc);
365 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
366}
367
368static errno_t testgc_set_color(void *arg, gfx_color_t *color)
369{
370 return EOK;
371}
372
373static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
374{
375 return EOK;
376}
377
378static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
379 gfx_bitmap_alloc_t *alloc, void **rbm)
380{
381 test_gc_t *tgc = (test_gc_t *) arg;
382 testgc_bitmap_t *tbm;
383
384 tbm = calloc(1, sizeof(testgc_bitmap_t));
385 if (tbm == NULL)
386 return ENOMEM;
387
388 if (alloc == NULL) {
389 tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
390 sizeof(uint32_t);
391 tbm->alloc.off0 = 0;
392 tbm->alloc.pixels = calloc(sizeof(uint32_t),
393 tbm->alloc.pitch * (params->rect.p1.y - params->rect.p0.y));
394 tbm->myalloc = true;
395 if (tbm->alloc.pixels == NULL) {
396 free(tbm);
397 return ENOMEM;
398 }
399 } else {
400 tbm->alloc = *alloc;
401 }
402
403 tbm->tgc = tgc;
404 tgc->bm_params = *params;
405 tgc->bm_pixels = tbm->alloc.pixels;
406 *rbm = (void *)tbm;
407 return EOK;
408}
409
410static errno_t testgc_bitmap_destroy(void *bm)
411{
412 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
413 if (tbm->myalloc)
414 free(tbm->alloc.pixels);
415 free(tbm);
416 return EOK;
417}
418
419static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
420 gfx_coord2_t *offs)
421{
422 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
423 tbm->tgc->bm_srect = *srect;
424 tbm->tgc->bm_offs = *offs;
425 return EOK;
426}
427
428static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
429{
430 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
431 *alloc = tbm->alloc;
432 return EOK;
433}
434
435PCUT_EXPORT(font);
Note: See TracBrowser for help on using the repository browser.