/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (c) 2002 by Greg Haerr * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ /* * Rockbox startup font initialization * This file specifies which fonts get compiled-in and * loaded at startup, as well as their mapping into * the FONT_SYSFIXED, FONT_UI and FONT_MP3 ids. */ #include "config.h" #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) #include #include #include "lcd.h" #include "font.h" #include "debug.h" #include "panic.h" /* available compiled-in fonts*/ extern MWCFONT font_X5x8; /*extern MWCFONT font_X6x9; */ /*extern MWCFONT font_courB08; */ /*extern MWCFONT font_timR08; */ /* structure filled in by rbf_load_font*/ static MWCFONT font_UI; /* system font table, in order of FONT_xxx definition*/ struct corefont sysfonts[MAXFONTS] = { { &font_X5x8, NULL }, /* compiled-in FONT_SYSFIXED*/ { &font_UI, "/system.fnt" }, /* loaded FONT_UI*/ { NULL, NULL }, /* no FONT_MP3*/ }; static void rotate_font_bits(PMWCFONT pf); static void rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width, unsigned int height); void font_init(void) { struct corefont *cfp; for (cfp=sysfonts; cfp < &sysfonts[MAXFONTS]; ++cfp) { if (cfp->pf && cfp->diskname) { cfp->pf = rbf_load_font(cfp->diskname, cfp->pf); #if defined(DEBUG) || defined(SIMULATOR) if (!cfp->pf) DEBUGF("Font load failed: %s\n", cfp->diskname); #endif } /* one-time rotate font bits to rockbox format*/ if (cfp->pf && cfp->pf->height) rotate_font_bits(cfp->pf); } } /* * Return a pointer to an incore font structure. * If the requested font isn't loaded/compiled-in, * decrement the font number and try again. */ PMWCFONT getfont(int font) { PMWCFONT pf; if (font >= MAXFONTS) font = 0; while (1) { pf = sysfonts[font].pf; if (pf && pf->height) return pf; if (--font < 0) panicf("No font!"); } } /* * Return width and height of a given font. */ void lcd_getfontsize(int font, int *width, int *height) { PMWCFONT pf = getfont(font); *width = pf->maxwidth; *height = pf->height; } /* * Return width and height of a given font. */ //FIXME rename to font_gettextsize, add baseline int lcd_getstringsize(unsigned char *str, int font, int *w, int *h) { PMWCFONT pf = getfont(font); int ch; int width = 0; while((ch = *str++)) { /* check input range*/ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) ch = pf->defaultchar; ch -= pf->firstchar; /* get proportional width and glyph bits*/ width += pf->width? pf->width[ch]: pf->maxwidth; } *w = width; *h = pf->height; return width; } /* * Put a string at specified bit position */ //FIXME rename font_putsxy? void lcd_putsxy(int x, int y, unsigned char *str, int font) { int ch; PMWCFONT pf = getfont(font); while (((ch = *str++) != '\0')) { MWIMAGEBITS *bits; int width; /* check input range*/ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) ch = pf->defaultchar; ch -= pf->firstchar; /* get proportional width and glyph bits*/ width = pf->width? pf->width[ch]: pf->maxwidth; if (x + width > LCD_WIDTH) break; /* no partial-height drawing for now...*/ if (y + pf->height > LCD_HEIGHT) break; bits = pf->bits + (pf->offset? pf->offset[ch]: (pf->height * ch)); lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true); x += width; } } /* convert font bitmap data inplace to rockbox format*/ static void rotate_font_bits(PMWCFONT pf) { int i; int defaultchar = pf->defaultchar - pf->firstchar; int did_defaultchar = 0; unsigned char buf[256]; for (i=0; isize; ++i) { MWIMAGEBITS *bits = pf->bits + (pf->offset? pf->offset[i]: (pf->height * i)); int width = pf->width? pf->width[i]: pf->maxwidth; int src_bytes = MWIMAGE_BYTES(width) * pf->height; /* * Due to the way the offset map works, * non-mapped characters are mapped to the default * character, and shouldn't be rotated twice. */ if (i == defaultchar) { if (did_defaultchar) continue; did_defaultchar = 1; } /* rotate left for lcd_bitmap function input*/ rotleft(buf, bits, width, pf->height); /* copy back into original location*/ memcpy(bits, buf, src_bytes); } } /* * Take an MWIMAGEBITS bitmap and convert to Rockbox format. * Used for converting font glyphs for the time being. * Can use for standard X11 and Win32 images as well. * * Doing it this way keeps fonts in standard formats, * as well as keeping Rockbox hw bitmap format. */ static void rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width, unsigned int height) { unsigned int i,j; unsigned int dst_col = 0; /* destination column*/ unsigned int dst_shift = 0; /* destination shift amount*/ unsigned int dst_linelen; /* # bytes per output row*/ unsigned int src_words; /* # words of input image*/ /* calc bytes per output row*/ dst_linelen = (height-1)/8+1; /* calc words of input image*/ src_words = MWIMAGE_WORDS(width) * height; /* clear background*/ memset(dst, 0, dst_linelen*width); for (i=0; i < src_words; i++) { MWIMAGEBITS srcmap; /* current src input bit*/ MWIMAGEBITS dstmap; /* current dst output bit*/ /* calc src input bit*/ srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1); /* calc dst output bit*/ if (i>0 && (i%8==0)) { ++dst_col; dst_shift = 0; } dstmap = 1 << dst_shift++; /* for each input column...*/ for(j=0; j < width; j++) { /* calc input bitmask*/ MWIMAGEBITS bit = srcmap >> j; if (bit==0) { srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1); bit = srcmap >> (j % 16); } /* if set in input, set in rotated output*/ if (bit & src[i]) { /* input column j becomes output row*/ dst[j*dst_linelen + dst_col] |= dstmap; } /*debugf((bit & src[i])? "*": ".");*/ } /*debugf("\n");*/ } } #endif /* HAVE_LCD_BITMAP */ /* ----------------------------------------------------------------- * local variables: * eval: (load-file "rockbox-mode.el") * vim: et sw=4 ts=8 sts=4 tw=78 * end: */