2011-05-11 21:18:46 +00:00
|
|
|
#include <sysdefs.h>
|
|
|
|
#include <render.h>
|
|
|
|
#include <fonts.h>
|
|
|
|
|
|
|
|
/* Global Variables */
|
|
|
|
const struct FONT_DEF * font = NULL;
|
|
|
|
char font_direction = FONT_DIR_LTR;
|
|
|
|
|
|
|
|
/* Exported Functions */
|
2011-05-11 23:37:26 +00:00
|
|
|
|
2011-05-14 20:21:51 +00:00
|
|
|
uint8_t * pk_decode(const uint8_t * data,int*len);
|
2011-05-11 21:18:46 +00:00
|
|
|
int DoChar(int sx, int sy, char c){
|
2011-05-13 01:19:47 +00:00
|
|
|
int x=0;
|
2011-05-11 23:37:26 +00:00
|
|
|
int y;
|
|
|
|
|
2011-05-12 00:23:07 +00:00
|
|
|
/* how many bytes is it high? */
|
|
|
|
char height=(font->u8Height-1)/8+1;
|
|
|
|
|
2011-05-14 20:21:51 +00:00
|
|
|
const uint8_t * data;
|
|
|
|
|
2011-05-11 23:37:26 +00:00
|
|
|
/* "real" coordinates. Our physical display is upside down */
|
2011-05-11 21:18:46 +00:00
|
|
|
int rx=RESX-sx-1;
|
|
|
|
int ry=RESY-sy-font->u8Height;
|
2011-05-11 23:37:26 +00:00
|
|
|
|
|
|
|
/* Does this font provide this character? */
|
2011-05-11 21:18:46 +00:00
|
|
|
if(c<font->u8FirstChar || c>font->u8LastChar)
|
|
|
|
c=font->u8FirstChar+1; // error
|
|
|
|
|
2011-05-11 23:37:26 +00:00
|
|
|
/* starting offset into character source data */
|
2011-05-14 20:21:51 +00:00
|
|
|
int toff,width,preblank,blank;
|
2011-05-11 23:37:26 +00:00
|
|
|
if(font->u8Width==0){
|
2011-05-14 20:21:51 +00:00
|
|
|
toff=0;
|
2011-05-11 23:37:26 +00:00
|
|
|
width=font->charInfo[c-font->u8FirstChar].widthBits;
|
2011-05-14 20:21:51 +00:00
|
|
|
for(y=0;y<c-font->u8FirstChar;y++)
|
|
|
|
toff+=font->charInfo[y].widthBits;
|
|
|
|
toff*=height;
|
|
|
|
data=&font->au8FontTable[toff];
|
2011-05-13 01:19:47 +00:00
|
|
|
preblank=0;
|
2011-05-12 00:23:07 +00:00
|
|
|
blank=1;
|
2011-05-14 20:21:51 +00:00
|
|
|
/* }else if(font->u8Width==1){
|
2011-05-13 01:19:47 +00:00
|
|
|
FONT_CHAR_INFO_v2 * fci=(FONT_CHAR_INFO_v2*)font->charInfo;
|
|
|
|
off=0;
|
|
|
|
width=fci[c-font->u8FirstChar].widthBits;
|
|
|
|
for(y=0;y<c-font->u8FirstChar;y++)
|
|
|
|
off+=fci[y].widthBits;
|
|
|
|
off*=height;
|
|
|
|
preblank=fci[y].preblank;
|
2011-05-14 20:21:51 +00:00
|
|
|
blank=fci[y].blank; */
|
|
|
|
}else if(font->u8Width==1){ // NEW CODE
|
|
|
|
// Find offset and length for our character
|
|
|
|
toff=0;
|
|
|
|
for(int y=0;y<c-font->u8FirstChar;y++)
|
|
|
|
toff+=font->charInfo[y].widthBits;
|
|
|
|
width=font->charInfo[c-font->u8FirstChar].widthBits;
|
|
|
|
|
2011-05-14 20:44:18 +00:00
|
|
|
if(font->au8FontTable[toff]>>4 == 15){ // It's a raw character!
|
|
|
|
preblank = font->au8FontTable[toff+1];
|
|
|
|
blank= font->au8FontTable[toff+2];
|
|
|
|
data=&font->au8FontTable[toff+3];
|
|
|
|
width/=height;
|
|
|
|
width-=1;
|
|
|
|
}else{
|
|
|
|
data=pk_decode(&font->au8FontTable[toff],&width);
|
|
|
|
preblank=0;
|
|
|
|
blank=0;
|
|
|
|
}
|
2011-05-11 23:37:26 +00:00
|
|
|
}else{
|
2011-05-14 20:21:51 +00:00
|
|
|
toff=(c-font->u8FirstChar)*font->u8Width*height;
|
2011-05-11 23:37:26 +00:00
|
|
|
width=font->u8Width;
|
2011-05-14 20:21:51 +00:00
|
|
|
data=&font->au8FontTable[toff];
|
2011-05-13 01:19:47 +00:00
|
|
|
preblank=0;
|
2011-05-12 00:23:07 +00:00
|
|
|
blank=0;
|
2011-05-11 23:37:26 +00:00
|
|
|
};
|
|
|
|
|
2011-05-13 01:19:47 +00:00
|
|
|
// boundary sanity checks
|
|
|
|
if(sx<0 || sy<0 || sx >= RESX || (sy+font->u8Height) >= RESY)
|
|
|
|
return sx; // nothing printed.
|
|
|
|
|
2011-05-11 23:37:26 +00:00
|
|
|
/* raw character data */
|
2011-05-11 21:18:46 +00:00
|
|
|
int byte;
|
2011-05-11 23:37:26 +00:00
|
|
|
unsigned char mask;
|
|
|
|
|
|
|
|
/* print forward or backward? */
|
2011-05-11 21:18:46 +00:00
|
|
|
int dmul=0;
|
2011-05-13 01:19:47 +00:00
|
|
|
if(font_direction==FONT_DIR_RTL){
|
2011-05-11 21:18:46 +00:00
|
|
|
dmul=1;
|
2011-05-13 01:19:47 +00:00
|
|
|
if(sx-(width+preblank+blank)<=0) // sanity check for left side
|
|
|
|
return sx;
|
|
|
|
} else if (font_direction==FONT_DIR_LTR){
|
2011-05-11 21:18:46 +00:00
|
|
|
dmul=-1;
|
2011-05-13 01:19:47 +00:00
|
|
|
if(sx+(width+preblank+blank)>=RESX) // sanity check for right side
|
|
|
|
return sx;
|
|
|
|
};
|
2011-05-11 23:37:26 +00:00
|
|
|
|
|
|
|
/* break down the position on byte boundaries */
|
2011-05-11 21:18:46 +00:00
|
|
|
char yidx=ry/8;
|
2011-05-11 23:37:26 +00:00
|
|
|
char yoff=ry%8;
|
|
|
|
|
2011-05-13 01:19:47 +00:00
|
|
|
rx+=dmul*preblank;
|
|
|
|
|
2011-05-11 23:37:26 +00:00
|
|
|
/* multiple 8-bit-lines */
|
|
|
|
for(y=0;y<=height;y++){
|
2011-05-12 12:07:54 +00:00
|
|
|
int m=yoff+font->u8Height-8*y;
|
|
|
|
if(m>8)m=8;
|
|
|
|
if(m<0)m=0;
|
|
|
|
mask=255<<(8-m);
|
|
|
|
|
2011-05-11 23:37:26 +00:00
|
|
|
if(y==0){
|
2011-05-13 01:19:47 +00:00
|
|
|
mask=mask>>yoff;
|
2011-05-11 21:18:46 +00:00
|
|
|
};
|
|
|
|
|
2011-05-13 01:19:47 +00:00
|
|
|
if(mask==0) // Optimize :-)
|
2011-05-12 12:07:54 +00:00
|
|
|
break;
|
|
|
|
// buffer[(rx-dmul)+(yidx+y)*RESX]=5;
|
|
|
|
|
2011-05-11 21:18:46 +00:00
|
|
|
if(font_direction==FONT_DIR_LTR)
|
|
|
|
flip(mask);
|
|
|
|
|
2011-05-13 01:19:47 +00:00
|
|
|
for(m=1;m<=preblank;m++){
|
|
|
|
buffer[(rx-dmul*(m))+(yidx+y)*RESX]&=~mask;
|
|
|
|
};
|
2011-05-12 00:23:07 +00:00
|
|
|
for(x=0;x<width;x++){
|
2011-05-11 23:37:26 +00:00
|
|
|
unsigned char b1,b2;
|
|
|
|
if(y==0)
|
|
|
|
b1=0;
|
|
|
|
else
|
2011-05-14 20:21:51 +00:00
|
|
|
b1=data[x*height+y-1];
|
2011-05-11 23:37:26 +00:00
|
|
|
if(y==height)
|
|
|
|
b2=0;
|
|
|
|
else
|
2011-05-14 20:21:51 +00:00
|
|
|
b2=data[x*height+y];
|
2011-05-11 23:37:26 +00:00
|
|
|
|
|
|
|
byte= (b1<<(8-yoff)) | (b2>>yoff);
|
2011-05-11 21:18:46 +00:00
|
|
|
if(font_direction==FONT_DIR_LTR)
|
|
|
|
flip(byte);
|
2011-05-11 23:37:26 +00:00
|
|
|
|
|
|
|
buffer[(rx+dmul*x)+(yidx+y)*RESX]&=~mask;
|
|
|
|
buffer[(rx+dmul*x)+(yidx+y)*RESX]|=byte;
|
2011-05-11 21:18:46 +00:00
|
|
|
};
|
2011-05-13 01:19:47 +00:00
|
|
|
for(m=0;m<blank;m++){
|
|
|
|
buffer[(rx+dmul*(x+m))+(yidx+y)*RESX]&=~mask;
|
2011-05-12 00:23:07 +00:00
|
|
|
};
|
2011-05-11 21:18:46 +00:00
|
|
|
};
|
2011-05-13 01:19:47 +00:00
|
|
|
return sx-dmul*(x+preblank+blank);
|
2011-05-11 21:18:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int DoString(int sx, int sy, char *s){
|
|
|
|
char *c;
|
|
|
|
for(c=s;*c!=0;c++){
|
|
|
|
sx=DoChar(sx,sy,*c);
|
|
|
|
};
|
|
|
|
return sx;
|
|
|
|
};
|
|
|
|
|
|
|
|
int DoInt(int sx, int sy, int num){
|
|
|
|
#define mxlen 5
|
|
|
|
char s[(mxlen+1)];
|
|
|
|
char * o=s;
|
|
|
|
int len;
|
|
|
|
s[mxlen]=0;
|
|
|
|
char neg=0;
|
|
|
|
|
|
|
|
if(num<0){
|
|
|
|
num=-num;
|
|
|
|
neg=1;
|
|
|
|
};
|
|
|
|
|
|
|
|
for (len=(mxlen-1);len>=0;len--){
|
|
|
|
s[len]=(num%10)+'0';
|
|
|
|
if(num==0){
|
|
|
|
s[len]=' '; // configurable?
|
|
|
|
o=s+len;
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
num/=10;
|
|
|
|
};
|
|
|
|
if(neg)
|
|
|
|
*o='-';
|
|
|
|
return DoString(sx,sy,o);
|
|
|
|
#undef mxlen
|
|
|
|
};
|
|
|
|
|
|
|
|
int DoIntX(int sx, int sy, unsigned int num){
|
|
|
|
#define mxlen 8
|
|
|
|
char s[(mxlen+1)];
|
|
|
|
char * o=s;
|
|
|
|
int len;
|
|
|
|
s[mxlen]=0;
|
|
|
|
for (len=(mxlen-1);len>=0;len--){
|
|
|
|
s[len]=(num%16)+'0';
|
|
|
|
if(s[len]>'9')
|
|
|
|
s[len]+='A'-'9'-1;
|
|
|
|
if(num==0){
|
|
|
|
// s[len]=' '; // configurable?
|
|
|
|
// o=s+len; break;
|
|
|
|
};
|
|
|
|
num/=16;
|
|
|
|
};
|
|
|
|
return DoString(sx,sy,o);
|
|
|
|
#undef mxlen
|
|
|
|
};
|
|
|
|
|
|
|
|
|