cb1bc5abce72380b61af9026d7c15f6940370749
[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 void
22 ao_text(const struct ao_bitmap  *dst,
23         const struct ao_font    *font,
24         int16_t                 x,
25         int16_t                 y,
26         char                    *string,
27         uint32_t                fill,
28         uint8_t                 rop)
29 {
30         int16_t         glyph_stride = ao_stride(font->max_width);
31         uint32_t        src[glyph_stride * font->max_height];
32         char            c;
33         int             h;
34         int16_t         x_off = 0, y_off = 0, advance = 0;
35         int16_t         byte_width = 0;
36
37         struct ao_bitmap        src_bitmap = {
38                 .base = src,
39         };
40
41         rop = (rop & 3) | 0x4;
42
43         if ((fill&1) == 0)
44                 rop ^= 3;
45
46         if (!font->metrics) {
47                 src_bitmap.width = font->max_width;
48                 src_bitmap.height = font->max_height;
49                 src_bitmap.stride = glyph_stride;
50                 x_off = 0;
51                 y_off = font->ascent;
52                 advance = font->max_width;
53                 byte_width = ao_stride_bytes(font->max_width);
54         }
55         while ((c = *string++)) {
56                 const uint8_t   *bytes = &font->bytes[font->pos[(uint8_t) c]];
57
58                 if (font->metrics) {
59                         const struct ao_glyph_metrics *m = &font->metrics[(uint8_t) c];
60                         src_bitmap.width = m->width;
61                         src_bitmap.height = m->height;
62                         src_bitmap.stride = ao_stride(m->width);
63                         x_off = m->x_off;
64                         y_off = m->y_off;
65                         advance = m->advance;
66                         byte_width = ao_stride_bytes(m->width);
67                 }
68
69                 for (h = 0; h < src_bitmap.height; h++)
70                         memcpy(&src[h * src_bitmap.stride], &bytes[h * byte_width], (size_t) byte_width);
71
72                 ao_copy(dst,
73                         x + x_off, y - y_off, src_bitmap.width, src_bitmap.height,
74                         &src_bitmap,
75                         0, 0, rop);
76                 x += advance;
77         }
78 }