c20f2399d97849d7d3f4dcbf8005fe39bd2d8481
[fw/altos] / src / draw / ao_text.c
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #include <ao_draw.h>
16 #include <ao_draw_int.h>
17 #include "ao_font.h"
18 #include <string.h>
19 #include <stdio.h>
20
21 extern uint32_t ao_glyph_temp[];
22
23 static struct ao_bitmap src_bitmap = {
24         .base = ao_glyph_temp,
25 };
26
27 void
28 ao_text(struct ao_bitmap        *dst,
29         const struct ao_font    *font,
30         int16_t                 x,
31         int16_t                 y,
32         char                    *string,
33         uint32_t                fill,
34         uint8_t                 rop)
35 {
36         int16_t         glyph_stride = ao_stride(font->max_width);
37         char            c;
38         int             h;
39         int16_t         x_off = 0, y_off = 0, advance = 0;
40         int16_t         byte_width = 0;
41
42         rop = (rop & 3) | 0x4;
43
44         if ((fill&1) == 0)
45                 rop ^= 3;
46
47         if (!font->metrics) {
48                 src_bitmap.width = font->max_width;
49                 src_bitmap.height = font->max_height;
50                 src_bitmap.stride = glyph_stride;
51                 x_off = 0;
52                 y_off = font->ascent;
53                 advance = font->max_width;
54                 byte_width = ao_stride_bytes(font->max_width);
55         }
56         while ((c = *string++)) {
57                 const uint8_t   *bytes = &font->bytes[font->pos[(uint8_t) c]];
58
59                 if (font->metrics) {
60                         const struct ao_glyph_metrics *m = &font->metrics[(uint8_t) c];
61                         src_bitmap.width = m->width;
62                         src_bitmap.height = m->height;
63                         src_bitmap.stride = ao_stride(m->width);
64                         x_off = m->x_off;
65                         y_off = m->y_off;
66                         advance = m->advance;
67                         byte_width = ao_stride_bytes(m->width);
68                 }
69
70                 for (h = 0; h < src_bitmap.height; h++)
71                         memcpy(&ao_glyph_temp[h * src_bitmap.stride], &bytes[h * byte_width], (size_t) byte_width);
72
73                 ao_copy(dst,
74                         x + x_off, y - y_off, src_bitmap.width, src_bitmap.height,
75                         &src_bitmap,
76                         0, 0, rop);
77                 x += advance;
78         }
79 }