0a1c22128f
Rotates the font bitmaps only once at font_init() time, with some source cleanup to rockbox standards. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2284 a1c6a512-1295-4272-9138-f99709370657
264 lines
7.1 KiB
C
264 lines
7.1 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
|
|
*
|
|
* 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 <stdio.h>
|
|
#include <string.h>
|
|
#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;
|
|
|
|
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;
|
|
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; i<pf->size; ++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=4 sts=4 tw=78
|
|
* end:
|
|
*/
|