Rename GP_Context -> GP_Pixmap
[gfxprim.git] / libs / text / GP_Text.gen.c.t
blob209d00defd0721f6bc49f24a8a5caf9db8b48da4
1 @ include source.t
2 /*
3  * Text rendering rutines.
4  *
5  * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos
6  *                         <jiri.bluebear.dluhos@gmail.com>
7  * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
8  */
10 #include "core/GP_GetPutPixel.h"
11 #include "core/GP_MixPixels.gen.h"
12 #include "gfx/GP_HLine.h"
13 #include "GP_TextStyle.h"
14 #include "GP_Text.h"
15 #include "GP_Font.h"
17 #define WIDTH_TO_1BPP_BPP(width) ((width)/8 + ((width)%8 != 0))
19 static int get_width(const GP_TextStyle *style, int width)
21         return width * style->pixel_xmul + (width - 1) * style->pixel_xspace;
24 @ for pt in pixeltypes:
25 @     if not pt.is_unknown():
27 static void text_draw_1BPP_{{ pt.name }}(GP_Pixmap *pixmap, const GP_TextStyle *style,
28                                          GP_Coord x, GP_Coord y,
29                                          GP_Pixel fg, const char *str)
31         const char *p;
33         GP_Coord y0 = y;
35         for (p = str; *p != '\0'; p++) {
36                 const GP_GlyphBitmap *glyph = GP_GetGlyphBitmap(style->font, *p);
38                 if (glyph == NULL)
39                         glyph = GP_GetGlyphBitmap(style->font, ' ');
41                 int i, j, k;
43                 unsigned int x_mul = style->pixel_xmul + style->pixel_xspace;
44                 unsigned int y_mul = style->pixel_ymul + style->pixel_yspace;
46                 unsigned int bpp = WIDTH_TO_1BPP_BPP(glyph->width);
48                 y = y0;
50                 for (j = 0; j < glyph->height; j++) {
51                         for (i = 0; i < glyph->width; i++) {
52                                 uint8_t bit = (glyph->bitmap[i/8 + j * bpp]) & (0x80>>(i%8));
54                                 unsigned int x_start = x + (i + glyph->bearing_x) * x_mul;
56                                 if (p == str)
57                                         x_start -= glyph->bearing_x * x_mul;
59                                 if (!bit)
60                                         continue;
62                                 for (k = 0; k < style->pixel_ymul; k++)
63                                         GP_HLine(pixmap, x_start, x_start + style->pixel_xmul - 1,
64                                                  y - (glyph->bearing_y - style->font->ascend) * y_mul + k, fg);
65                         }
67                         y += style->pixel_ymul + style->pixel_yspace;
68                 }
70                 x += get_width(style, glyph->advance_x) + style->char_xspace;
72                 if (p == str)
73                         x -= get_width(style, glyph->bearing_x);
74         }
77 @ end
79 static void text_draw_1BPP(GP_Pixmap *pixmap, const GP_TextStyle *style, int x, int y,
80                            GP_Pixel fg, const char *str)
82         switch (pixmap->pixel_type) {
83 @ for pt in pixeltypes:
84 @     if not pt.is_unknown():
85         case GP_PIXEL_{{ pt.name }}:
86                 text_draw_1BPP_{{ pt.name }}(pixmap, style, x, y, fg, str);
87         break;
88 @ end
89         default:
90                 GP_ABORT("Invalid pixmap->pixel_type");
91         }
94 @ def text_8BPP(pt, use_bg):
95         const char *p;
97         GP_Coord y0 = y;
99         for (p = str; *p != '\0'; p++) {
100                 const GP_GlyphBitmap *glyph = GP_GetGlyphBitmap(style->font, *p);
102                 if (glyph == NULL)
103                         glyph = GP_GetGlyphBitmap(style->font, ' ');
105                 int i, j, k;
107                 unsigned int x_mul = style->pixel_xmul + style->pixel_xspace;
108                 unsigned int y_mul = style->pixel_ymul + style->pixel_yspace;
110                 y = y0;
112                 for (j = 0; j < glyph->height; j++) {
113                         for (i = 0; i < glyph->width; i++) {
114                                 uint8_t gray = glyph->bitmap[i + j * glyph->width];
116                                 unsigned int x_start = x + (i + glyph->bearing_x) * x_mul;
118                                 if (p == str)
119                                         x_start -= glyph->bearing_x * x_mul;
121                                 if (!gray)
122                                         continue;
124                                 int cur_y = y - (glyph->bearing_y - style->font->ascend) * y_mul;
126                                 for (k = 0; k < style->pixel_ymul; k++) {
127 @     if use_bg:
128                                         GP_HLine(pixmap, x_start, x_start + style->pixel_xmul - 1, cur_y + k,
129                                         GP_MIX_PIXELS_{{ pt.name }}(fg, bg, gray));
130 @     else:
131                                         unsigned int l;
133                                         for (l = x_start; l < x_start + style->pixel_xmul; l++) {
134                                                 unsigned int px = l;
135                                                 unsigned int py = cur_y + k;
136                                                 //TODO: optimize this
137                                                 GP_TRANSFORM_POINT(pixmap, px, py);
138                                                 GP_MixPixel_Raw_Clipped_{{ pt.name }}(pixmap, px, py, fg, gray);
139                                         }
140 @     end
141                                 }
142                         }
144                         y += style->pixel_ymul + style->pixel_yspace;
145                 }
147                 x += get_width(style, glyph->advance_x) + style->char_xspace;
149                 if (p == str)
150                         x -= get_width(style, glyph->bearing_x);
151         }
152 @ end
154 @ for pt in pixeltypes:
155 @     if not pt.is_unknown():
157 static void text_8BPP_bg_{{ pt.name }}(GP_Pixmap *pixmap, const GP_TextStyle *style,
158                                        GP_Coord x, GP_Coord y,
159                                        GP_Pixel fg, GP_Pixel bg, const char *str)
161 @         text_8BPP(pt, True)
164 static void text_8BPP_{{ pt.name }}(GP_Pixmap *pixmap, const GP_TextStyle *style,
165                                     GP_Coord x, GP_Coord y,
166                                     GP_Pixel fg, const char *str)
168 @         text_8BPP(pt, False)
171 @ end
173 static void text_8BPP_bg(GP_Pixmap *pixmap, const GP_TextStyle *style,
174                          GP_Coord x, GP_Coord y,
175                          GP_Pixel fg, GP_Pixel bg, const char *str)
177         switch (pixmap->pixel_type) {
178 @ for pt in pixeltypes:
179 @     if not pt.is_unknown():
180         case GP_PIXEL_{{ pt.name }}:
181                 text_8BPP_bg_{{ pt.name }}(pixmap, style, x, y, fg, bg, str);
182         break;
183 @ end
184         default:
185                 GP_ABORT("Invalid pixmap->pixel_type");
186         }
189 static void text_8BPP(GP_Pixmap *pixmap, const GP_TextStyle *style,
190                       GP_Coord x, GP_Coord y,
191                       GP_Pixel fg, const char *str)
193         switch (pixmap->pixel_type) {
194 @ for pt in pixeltypes:
195 @     if not pt.is_unknown():
196         case GP_PIXEL_{{ pt.name }}:
197                 text_8BPP_{{ pt.name }}(pixmap, style, x, y, fg, str);
198         break;
199 @ end
200         default:
201                 GP_ABORT("Invalid pixmap->pixel_type");
202         }
205 void GP_Text_Raw(GP_Pixmap *pixmap, const GP_TextStyle *style,
206                  GP_Coord x, GP_Coord y, uint8_t flags,
207                  GP_Pixel fg, GP_Pixel bg, const char *str)
209         switch (style->font->glyph_bitmap_format) {
210         case GP_FONT_BITMAP_1BPP:
211                 text_draw_1BPP(pixmap, style, x, y, fg, str);
212         break;
213         case GP_FONT_BITMAP_8BPP:
214                 if (flags)
215                         text_8BPP(pixmap, style, x, y, fg, str);
216                 else
217                         text_8BPP_bg(pixmap, style, x, y, fg, bg, str);
218         break;
219         default:
220                 GP_ABORT("Invalid font glyph bitmap format");
221         }