blob: e9c70cd64e8a179f18b002c61befdbd26e7f5c22 [file] [log] [blame]
Daniel Stenberg93b231c2002-09-12 13:33:59 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19/*
20 * Rockbox startup font initialization
21 * This file specifies which fonts get compiled-in and
22 * loaded at startup, as well as their mapping into
23 * the FONT_SYSFIXED, FONT_UI and FONT_MP3 ids.
24 */
25#include "config.h"
26
27#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
28
29#include <stdio.h>
30#include <string.h>
31#include "lcd.h"
32#include "font.h"
33#include "debug.h"
34#include "panic.h"
35
36/* available compiled-in fonts*/
37extern MWCFONT font_X5x8;
38/*extern MWCFONT font_X6x9; */
39/*extern MWCFONT font_courB08; */
40/*extern MWCFONT font_timR08; */
41
42/* structure filled in by rbf_load_font*/
43static MWCFONT font_UI;
44
45/* system font table, in order of FONT_xxx definition*/
46struct corefont sysfonts[MAXFONTS] = {
47 { &font_X5x8, NULL }, /* compiled-in FONT_SYSFIXED*/
48 { &font_UI, "/system.fnt" }, /* loaded FONT_UI*/
49 { NULL, NULL }, /* no FONT_MP3*/
50};
51
Daniel Stenberg0a1c2212002-09-13 06:37:49 +000052static void rotate_font_bits(PMWCFONT pf);
53static void rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width,
54 unsigned int height);
55
Daniel Stenberg93b231c2002-09-12 13:33:59 +000056void
57font_init(void)
58{
59 struct corefont *cfp;
60
61 for (cfp=sysfonts; cfp < &sysfonts[MAXFONTS]; ++cfp) {
62 if (cfp->pf && cfp->diskname) {
63 cfp->pf = rbf_load_font(cfp->diskname, cfp->pf);
64#if defined(DEBUG) || defined(SIMULATOR)
65 if (!cfp->pf)
66 DEBUGF("Font load failed: %s\n", cfp->diskname);
67#endif
68 }
Daniel Stenberg0a1c2212002-09-13 06:37:49 +000069
70 /* one-time rotate font bits to rockbox format*/
71 if (cfp->pf && cfp->pf->height)
72 rotate_font_bits(cfp->pf);
Daniel Stenberg93b231c2002-09-12 13:33:59 +000073 }
74}
75
76/*
77 * Return a pointer to an incore font structure.
78 * If the requested font isn't loaded/compiled-in,
79 * decrement the font number and try again.
80 */
81PMWCFONT
82getfont(int font)
83{
84 PMWCFONT pf;
85
Eric Linenberg038df5c2002-09-16 03:18:49 +000086 if (font >= MAXFONTS)
87 font = 0;
Daniel Stenberg93b231c2002-09-12 13:33:59 +000088 while (1) {
89 pf = sysfonts[font].pf;
90 if (pf && pf->height)
91 return pf;
92 if (--font < 0)
93 panicf("No font!");
94 }
95}
96
97/*
98 * Return width and height of a given font.
99 */
100void lcd_getfontsize(int font, int *width, int *height)
101{
102 PMWCFONT pf = getfont(font);
103
104 *width = pf->maxwidth;
105 *height = pf->height;
106}
107
108/*
109 * Return width and height of a given font.
110 */
111//FIXME rename to font_gettextsize, add baseline
112int
113lcd_getstringsize(unsigned char *str, int font, int *w, int *h)
114{
115 PMWCFONT pf = getfont(font);
116 int ch;
117 int width = 0;
118
119 while((ch = *str++)) {
Eric Linenberg038df5c2002-09-16 03:18:49 +0000120 /* check input range*/
121 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
122 ch = pf->defaultchar;
123 ch -= pf->firstchar;
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000124
Eric Linenberg038df5c2002-09-16 03:18:49 +0000125 /* get proportional width and glyph bits*/
126 width += pf->width? pf->width[ch]: pf->maxwidth;
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000127 }
128 *w = width;
129 *h = pf->height;
130
131 return width;
132}
133
134/*
Daniel Stenberg0a1c2212002-09-13 06:37:49 +0000135 * Put a string at specified bit position
136 */
137//FIXME rename font_putsxy?
138void
139lcd_putsxy(int x, int y, unsigned char *str, int font)
140{
141 int ch;
142 PMWCFONT pf = getfont(font);
143
144 while (((ch = *str++) != '\0')) {
145 MWIMAGEBITS *bits;
146 int width;
147
148 /* check input range*/
149 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
150 ch = pf->defaultchar;
151 ch -= pf->firstchar;
152
153 /* get proportional width and glyph bits*/
154 width = pf->width? pf->width[ch]: pf->maxwidth;
Eric Linenberg038df5c2002-09-16 03:18:49 +0000155 if (x + width > LCD_WIDTH)
156 break;
157
158 /* no partial-height drawing for now...*/
159 if (y + pf->height > LCD_HEIGHT)
Daniel Stenberg0a1c2212002-09-13 06:37:49 +0000160 break;
161 bits = pf->bits + (pf->offset? pf->offset[ch]: (pf->height * ch));
162
163 lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true);
164 x += width;
165 }
166}
167
168/* convert font bitmap data inplace to rockbox format*/
169static void
170rotate_font_bits(PMWCFONT pf)
171{
172 int i;
173 int defaultchar = pf->defaultchar - pf->firstchar;
174 int did_defaultchar = 0;
175 unsigned char buf[256];
176
177 for (i=0; i<pf->size; ++i) {
178 MWIMAGEBITS *bits = pf->bits +
179 (pf->offset? pf->offset[i]: (pf->height * i));
180 int width = pf->width? pf->width[i]: pf->maxwidth;
181 int src_bytes = MWIMAGE_BYTES(width) * pf->height;
182
183 /*
184 * Due to the way the offset map works,
185 * non-mapped characters are mapped to the default
186 * character, and shouldn't be rotated twice.
187 */
188 if (i == defaultchar) {
189 if (did_defaultchar)
190 continue;
191 did_defaultchar = 1;
192 }
193
194 /* rotate left for lcd_bitmap function input*/
195 rotleft(buf, bits, width, pf->height);
196
197 /* copy back into original location*/
198 memcpy(bits, buf, src_bytes);
199 }
200}
201
202/*
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000203 * Take an MWIMAGEBITS bitmap and convert to Rockbox format.
204 * Used for converting font glyphs for the time being.
205 * Can use for standard X11 and Win32 images as well.
206 *
207 * Doing it this way keeps fonts in standard formats,
208 * as well as keeping Rockbox hw bitmap format.
209 */
210static void
211rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width,
212 unsigned int height)
213{
214 unsigned int i,j;
215 unsigned int dst_col = 0; /* destination column*/
216 unsigned int dst_shift = 0; /* destination shift amount*/
217 unsigned int dst_linelen; /* # bytes per output row*/
218 unsigned int src_words; /* # words of input image*/
219
220 /* calc bytes per output row*/
221 dst_linelen = (height-1)/8+1;
222
223 /* calc words of input image*/
224 src_words = MWIMAGE_WORDS(width) * height;
225
226 /* clear background*/
Daniel Stenberg0a1c2212002-09-13 06:37:49 +0000227 memset(dst, 0, dst_linelen*width);
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000228
229 for (i=0; i < src_words; i++) {
230 MWIMAGEBITS srcmap; /* current src input bit*/
231 MWIMAGEBITS dstmap; /* current dst output bit*/
232
Eric Linenberg038df5c2002-09-16 03:18:49 +0000233 /* calc src input bit*/
234 srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1);
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000235
Eric Linenberg038df5c2002-09-16 03:18:49 +0000236 /* calc dst output bit*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000237 if (i>0 && (i%8==0)) {
238 ++dst_col;
239 dst_shift = 0;
240 }
241 dstmap = 1 << dst_shift++;
242
Eric Linenberg038df5c2002-09-16 03:18:49 +0000243 /* for each input column...*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000244 for(j=0; j < width; j++) {
245
Eric Linenberg038df5c2002-09-16 03:18:49 +0000246 /* calc input bitmask*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000247 MWIMAGEBITS bit = srcmap >> j;
248 if (bit==0) {
249 srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1);
250 bit = srcmap >> (j % 16);
251 }
252
Eric Linenberg038df5c2002-09-16 03:18:49 +0000253 /* if set in input, set in rotated output*/
254 if (bit & src[i]) {
255 /* input column j becomes output row*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000256 dst[j*dst_linelen + dst_col] |= dstmap;
257 }
Daniel Stenberg0a1c2212002-09-13 06:37:49 +0000258 /*debugf((bit & src[i])? "*": ".");*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000259 }
Daniel Stenberg0a1c2212002-09-13 06:37:49 +0000260 /*debugf("\n");*/
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000261 }
262}
263#endif /* HAVE_LCD_BITMAP */
264
265/* -----------------------------------------------------------------
266 * local variables:
267 * eval: (load-file "rockbox-mode.el")
Eric Linenberg038df5c2002-09-16 03:18:49 +0000268 * vim: et sw=4 ts=8 sts=4 tw=78
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000269 * end:
270 */