]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libgfxbitmap/lib/src/font.c
091d2091973cc02ba628da736383965db93c51ae
[l4.git] / l4 / pkg / libgfxbitmap / lib / src / font.c
1 /**
2  * \file
3  * \brief     Font functions
4  *
5  * \author    Christian Helmuth <ch12@os.inf.tu-dresden.de>
6  *            Frank Mehnert <fm3@os.inf.tu-dresden.de>
7  *            Adam Lackorzynski <adam@os.inf.tu-dresden.de> */
8
9 /*
10  * (c) 2001-2009 Author(s)
11  *     economic rights: Technische Universität Dresden (Germany)
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU Lesser General Public License 2.1.
14  * Please see the COPYING-LGPL-2.1 file for details.
15  */
16
17 #include <l4/libgfxbitmap/font.h>
18 #include <l4/libgfxbitmap/bitmap.h>
19 #include <l4/sys/l4int.h>
20 #include <string.h>
21 #include <stdio.h>
22
23 extern const char _binary_vgafont_psf_start[];
24 extern const char _binary_lat0_12_psf_start[];
25 extern const char _binary_lat0_14_psf_start[];
26 extern const char _binary_lat0_16_psf_start[];
27
28 static struct {
29   const char *fontdata;
30   const char *name;
31 } font_list[] = {
32   { _binary_lat0_14_psf_start, "lat0-14" }, // first one is the default one
33   { _binary_lat0_12_psf_start, "lat0-12" },
34   { _binary_lat0_16_psf_start, "lat0-16" },
35   { _binary_vgafont_psf_start, "vgafont" },
36 };
37
38 enum {
39   FONT_XRES = 8,
40 };
41
42 struct psf_header
43 {
44   unsigned char magic[2];
45   unsigned char mode;
46   unsigned char height;
47 } __attribute__((packed));
48
49 struct psf_font
50 {
51   struct psf_header header;
52   char data[];
53 };
54
55 static struct psf_font *std_font;
56
57
58 static int check_magic(struct psf_font *f)
59 { return f->header.magic[0] == 0x36 && f->header.magic[1] == 0x4; }
60
61 static inline struct psf_font *font_cast(gfxbitmap_font_t font)
62 {
63   struct psf_font *f = (struct psf_font *)font;
64   if (!f || !check_magic(f))
65     return std_font;
66   return f;
67 }
68
69 static unsigned char font_yres(struct psf_font *f)
70 { return f->header.height; }
71
72 unsigned
73 gfxbitmap_font_width(gfxbitmap_font_t font)
74 {
75   (void)font;
76   return FONT_XRES;
77 }
78
79 unsigned
80 gfxbitmap_font_height(gfxbitmap_font_t font)
81 {
82   struct psf_font *f = font_cast(font);
83   return f ? f->header.height : 0;
84 }
85
86 static inline
87 void *
88 get_font_char(struct psf_font *f, unsigned c)
89 {
90   return &f->data[(FONT_XRES / 8) * font_yres(f) * c];
91 }
92
93 void *
94 gfxbitmap_font_data(gfxbitmap_font_t font, unsigned c)
95 {
96   struct psf_font *f = font_cast(font);
97   if (!f)
98     return NULL;
99
100   return get_font_char(f, c);
101 }
102
103 void
104 gfxbitmap_font_text(void *fb, l4re_video_view_info_t *vi,
105                     gfxbitmap_font_t font, const char *text, unsigned len,
106                     unsigned x, unsigned y,
107                     gfxbitmap_color_pix_t fg, gfxbitmap_color_pix_t bg)
108 {
109   unsigned i, j;
110   struct gfxbitmap_offset offset = {0,0,0};
111   struct psf_font *f = font_cast(font);
112
113   if (!f)
114     return;
115
116   if (len == GFXBITMAP_USE_STRLEN)
117     len = strlen(text);
118
119   for (i = 0; i < len; i++, text++)
120     {
121       /* optimization: collect spaces */
122       for (j = 0; (i < len) && (*text == ' '); i++, j++, text++)
123         ;
124
125       if (j > 0)
126         {
127           gfxbitmap_fill(fb, vi, x, y, j * FONT_XRES, font_yres(f), bg);
128           x += j * FONT_XRES;
129           i--;
130           text--;
131           continue;
132         }
133
134       gfxbitmap_bmap(fb, vi, x, y, FONT_XRES, font_yres(f),
135                      get_font_char(f, *(unsigned char *)text), fg, bg,
136                      &offset, pSLIM_BMAP_START_MSB);
137       x += FONT_XRES;
138     }
139 }
140
141
142 void
143 gfxbitmap_font_text_scale(void *fb, l4re_video_view_info_t *vi,
144                           gfxbitmap_font_t font, const char *text, unsigned len,
145                           unsigned x, unsigned y,
146                           gfxbitmap_color_pix_t fg, gfxbitmap_color_pix_t bg,
147                           int scale_x, int scale_y)
148 {
149   int pix_x, pix_y;
150   unsigned rect_x = x;
151   unsigned rect_y = y;
152   unsigned rect_w = gfxbitmap_font_width(font) * scale_x;
153   unsigned i;
154   struct psf_font *f = font_cast(font);
155
156   if (!f)
157     return;
158
159   pix_x = scale_x;
160   if (scale_x >= 5)
161     pix_x = scale_x * 14/15;
162   pix_y = scale_y;
163   if (scale_y >= 5)
164     pix_y = scale_y * 14/15;
165
166   if (len == GFXBITMAP_USE_STRLEN)
167     len = strlen(text);
168
169   for (i=0; i < len; i++, text++)
170     {
171       unsigned lrect_x = rect_x;
172       unsigned lrect_y = rect_y;
173       unsigned lrect_w = pix_x;
174       unsigned lrect_h = pix_y;
175       const char *bmap = get_font_char(f, *text);
176       int j;
177
178       for (j=0; j<font_yres(f); j++)
179         {
180           unsigned char mask = 0x80;
181           int k;
182
183           for (k=0; k<FONT_XRES; k++)
184             {
185               unsigned color = (*bmap & mask) ? fg : bg;
186               gfxbitmap_fill(fb, vi, lrect_x, lrect_y, lrect_w, lrect_h, color);
187               lrect_x += scale_x;
188               bmap += (mask &  1);
189               mask  = (mask >> 1) | (mask << 7);
190             }
191           lrect_x -= rect_w;
192           lrect_y += scale_y;
193         }
194       rect_x += rect_w;
195     }
196 }
197
198
199 gfxbitmap_font_t
200 gfxbitmap_font_get(const char *name)
201 {
202   unsigned i = 0;
203   for (; i < sizeof(font_list) / sizeof(font_list[0]); ++i)
204     if (!strcmp(font_list[i].name, name))
205       return (gfxbitmap_font_t)font_list[i].fontdata;
206   return NULL;
207 }
208
209 /** Init lib */
210 int
211 gfxbitmap_font_init(void)
212 {
213   unsigned chars;
214
215   struct psf_font *f;
216   f = font_cast((gfxbitmap_font_t)font_list[0].fontdata);
217
218   /* check magic number of .psf */
219   if (!check_magic(f))
220     return 1; // psf magic number failed
221
222   std_font = f;
223
224   /* check file mode */
225   switch (f->header.mode)
226     {
227     case 0:
228     case 2:
229       chars = 256;
230       break;
231     case 1:
232     case 3:
233       chars = 512;
234       break;
235     default:
236       return 2; // "bad psf font file magic %02x!", f->header.mode
237     }
238
239   if (0)
240     printf("Font: Character size is %dx%d, font has %d characters\n",
241            FONT_XRES, font_yres(f), chars);
242
243   return 0;
244 }
245