3 * Text rendering rutines.
5 * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos
6 * <jiri.bluebear.dluhos@gmail.com>
7 * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
10 #include "core/GP_GetPutPixel.h"
11 #include "core/GP_MixPixels.gen.h"
12 #include "gfx/GP_HLine.h"
13 #include "GP_TextStyle.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)
35 for (p = str; *p != '\0'; p++) {
36 const GP_GlyphBitmap *glyph = GP_GetGlyphBitmap(style->font, *p);
39 glyph = GP_GetGlyphBitmap(style->font, ' ');
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);
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;
57 x_start -= glyph->bearing_x * x_mul;
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);
67 y += style->pixel_ymul + style->pixel_yspace;
70 x += get_width(style, glyph->advance_x) + style->char_xspace;
73 x -= get_width(style, glyph->bearing_x);
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);
90 GP_ABORT("Invalid pixmap->pixel_type");
94 @ def text_8BPP(pt, use_bg):
99 for (p = str; *p != '\0'; p++) {
100 const GP_GlyphBitmap *glyph = GP_GetGlyphBitmap(style->font, *p);
103 glyph = GP_GetGlyphBitmap(style->font, ' ');
107 unsigned int x_mul = style->pixel_xmul + style->pixel_xspace;
108 unsigned int y_mul = style->pixel_ymul + style->pixel_yspace;
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;
119 x_start -= glyph->bearing_x * x_mul;
124 int cur_y = y - (glyph->bearing_y - style->font->ascend) * y_mul;
126 for (k = 0; k < style->pixel_ymul; k++) {
128 GP_HLine(pixmap, x_start, x_start + style->pixel_xmul - 1, cur_y + k,
129 GP_MIX_PIXELS_{{ pt.name }}(fg, bg, gray));
133 for (l = x_start; l < x_start + style->pixel_xmul; 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);
144 y += style->pixel_ymul + style->pixel_yspace;
147 x += get_width(style, glyph->advance_x) + style->char_xspace;
150 x -= get_width(style, glyph->bearing_x);
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)
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);
185 GP_ABORT("Invalid pixmap->pixel_type");
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);
201 GP_ABORT("Invalid pixmap->pixel_type");
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);
213 case GP_FONT_BITMAP_8BPP:
215 text_8BPP(pixmap, style, x, y, fg, str);
217 text_8BPP_bg(pixmap, style, x, y, fg, bg, str);
220 GP_ABORT("Invalid font glyph bitmap format");