#include "oswald.h" #include "oswald_strings.h" #include "oswald_fonts.h" #include "oswald_hal.h" #include "oswald_graphics.h" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "fonts/font5x8scaledx4x5.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "fonts/font5x8scaledx2x2.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "fonts/font5x8scaledx2x3.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "fonts/fontbigdigits.xbm" #define LCD_WIDTH 96 #define LCD_HEIGHT 96 typedef struct { unsigned int x1,y1,x2,y2; unsigned int x,y; unsigned int w; } gc_t; gc_t gc={0,0,LCD_WIDTH-1,LCD_HEIGHT-1}; void oswald_set_draw_window(const unsigned int x1,const unsigned int y1,const unsigned int x2,const unsigned int y2) { gc.x1=x1,gc.x2=x2,gc.y1=y1,gc.y2=y2; gc.x=gc.y=0; gc.w=gc.x2-gc.x1+1; } void oswald_draw_point(const uint8_t color) { hal_lcd_set_pixel(gc.x1+gc.x,gc.y1+gc.y,color); gc.x++; gc.y+=(gc.x/gc.w); gc.x%=gc.w; } void oswald_draw_point_transparent(const uint8_t color, const uint8_t transparent) { if(color!=transparent) hal_lcd_set_pixel(gc.x1+gc.x,gc.y1+gc.y,color); gc.x++; gc.y+=(gc.x/gc.w); gc.x%=gc.w; } #if 0 void oswald_draw_pixel(const unsigned int xstart, const unsigned int ystart, uint8_t color) { hal_lcd_set_pixel(xstart, ystart, TRUE); } #endif void oswald_draw_bitmap_opts(const unsigned int xstart, const unsigned int ystart, const unsigned int xoff, const unsigned int yoff, const unsigned int width, const unsigned int height, const boolean fg, const unsigned int bmp_width, const unsigned int bmp_height, const void *bmp) { unsigned int x, y; uint8_t *cb; if (bmp == NULL) return; cb = (uint8_t *)bmp; // we only draw set pixel, unset pixel remain as they are for (y=yoff; y<bmp_height && y<height; y++) { for (x=xoff; x<bmp_width && x<width; x++) { cb = (uint8_t *)(bmp + (y * ((bmp_width / 8) + ((bmp_width % 8) ? 1 : 0))) + (x / 8)); if (*cb & (1 << (x % 8))) { hal_lcd_set_pixel((xstart + x) - xoff, (ystart + y) - yoff, fg); } } } } void oswald_draw_bitmap_opts_1x2fg(const unsigned int xstart, const unsigned int ystart, const unsigned int xoff, const unsigned int yoff, const unsigned int width, const unsigned int height, const boolean fg, const unsigned int bmp_width, const unsigned int bmp_height, const void *bmp) { unsigned int x, y, iy; uint8_t *cb; if (bmp == NULL) return; cb = (uint8_t *)bmp; for (y=yoff,iy=0; y<bmp_height && y<height; y++, iy++) { for (x=xoff; x<bmp_width && x<width; x++) { cb = (uint8_t *)(bmp + (y * ((bmp_width / 8) + ((bmp_width % 8) ? 1 : 0))) + (x / 8)); if (*cb & (1 << (x % 8))) { hal_lcd_set_pixel((xstart + x) - xoff, (ystart + y) - yoff + iy , fg); hal_lcd_set_pixel((xstart + x) - xoff, (ystart + y) - yoff + iy + 1, fg); } } } } void oswald_draw_rect(const unsigned int x1, const unsigned int y1, const unsigned int x2, const unsigned int y2, const uint8_t color) { unsigned int x, y; for(y=y1;y<=y2;++y) { for(x=x1;x<=x2;++x) hal_lcd_set_pixel(x,y,color); } } void oswald_draw_grid(const unsigned int x1, const unsigned int y1, const unsigned int x2, const unsigned int y2, const unsigned int ix, const unsigned int iy) { unsigned int x, y; for(y=y1+iy;y<y2;y+=iy) { oswald_set_draw_window(x1,y,x2,y); for(x=x1;x<=x2;++x) oswald_draw_point(x&1); } for(x=x1+ix;x<x2;x+=ix) { oswald_set_draw_window(x,y1,x,y2); for(y=y1;y<=y2;++y) oswald_draw_point(y&1); } oswald_draw_rect(x1+1,y1,x2-1,y1,1); oswald_draw_rect(x1+1,y2,x2-1,y2,1); oswald_draw_rect(x1,y1+1,x1,y2-1,1); oswald_draw_rect(x2,y1+1,x2,y2-1,1); hal_lcd_set_pixel(x1+1,y1+1,1); hal_lcd_set_pixel(x1+1,y2-1,1); hal_lcd_set_pixel(x2-1,y1+1,1); hal_lcd_set_pixel(x2-1,y2-1,1); } static const uint8_t * oswald_getchar_font58(const uint8_t character, int *width) { const uint8_t *ptr; if(character<32 || character>255) { *width=0; return(NULL); } ptr=(font5x8+((character-32)<<2)); /* simple way to calc. the width */ *width=(((ptr[0]&0x02)||(ptr[1]&0x10)||(ptr[2]&0x84)||(ptr[3]&0x21))?5: ((ptr[0]&0x04)||(ptr[1]&0x21)||(ptr[2]&0x08)||(ptr[3]&0x42))?4: ((ptr[0]&0x08)||(ptr[1]&0x42)||(ptr[2]&0x10)||(ptr[3]&0x84))?3: ((ptr[0]&0x10)||(ptr[1]&0x84)||(ptr[2]&0x21)||(ptr[3]&0x08))?2: ((ptr[0]&0x3f)||(ptr[1]&0xff)||(ptr[2]&0xff)||(ptr[3]&0xff))?2:1); return(ptr); } void oswald_draw_font58(const unsigned int x1, unsigned int y1, const uint8_t character, int *width, const uint8_t fg, const uint8_t bg) { int bit; int k; uint8_t car; const uint8_t *ptr; if((ptr=oswald_getchar_font58(character,width))==NULL) return; if(ptr[0]&0x80) { oswald_draw_rect(x1,y1,x1+*width,y1+1,bg); if(ptr[0]&0x40) oswald_draw_rect(x1+*width-1,y1,x1+*width-1,y1,fg); y1+=2; } else oswald_draw_rect(x1,y1,x1+*width-1,y1+7,bg); oswald_set_draw_window(x1,y1,x1+4,y1+5); for(k=0;k<=3;++k) { for(bit=((k==0)?0x20:0x80),car=ptr[k];bit>0;bit>>=1) oswald_draw_point_transparent((car&bit)?fg:bg,bg); } return; } void oswald_writestr_font58(const unsigned int x1, unsigned int y1, const char *str, int *width, const uint8_t fg, const uint8_t bg) { int x,w; for(x=x1;*str!='\0';x+=w+1,str++) oswald_draw_font58(x, y1,*str,&w,fg,bg); *width=x-x1; } int oswald_getwidth_font58(char *str) { int total; int width; for(total=0;*str!='\0';str++) { if(oswald_getchar_font58(*str,&width)!=NULL) total+=width; total++; } return(total); } void oswald_draw_font58_scaled(const unsigned int x1, unsigned int y1, const uint8_t character, int *width, const uint8_t fg, const uint8_t bg,const unsigned int scalex,const unsigned int scaley) { int x,y,ix,iy; int k,n,b,c; const uint8_t *ptr; *width=0; if(character<32 || character>255) return; /* special cases */ if(character>='0' && character<='9') { if(scalex==4 && scaley==10) { *width=16; oswald_draw_bitmap_opts_1x2fg(x1,y1,(character-'0')*4*4,0,(character-'0')*4*4+16,font5x8scaledx4x5_height,fg,font5x8scaledx4x5_width,font5x8scaledx4x5_height,font5x8scaledx4x5_bits); return; } else if(scalex==4 && scaley==5) { *width=16; oswald_draw_bitmap_opts(x1,y1,(character-'0')*4*4,0,(character-'0')*4*4+16,font5x8scaledx4x5_height,fg,font5x8scaledx4x5_width,font5x8scaledx4x5_height,font5x8scaledx4x5_bits); return; } else if(scalex==2 && scaley==2) { *width=8; oswald_draw_bitmap_opts(x1,y1,(character-'0')*2*4,0,(character-'0')*2*4+8,font5x8scaledx2x2_height,fg,font5x8scaledx2x2_width,font5x8scaledx2x2_height,font5x8scaledx2x2_bits); return; } else if(scalex==2 && scaley==3) { *width=8; oswald_draw_bitmap_opts(x1,y1,(character-'0')*2*4,0,(character-'0')*2*4+8,font5x8scaledx2x3_height,fg,font5x8scaledx2x3_width,font5x8scaledx2x3_height,font5x8scaledx2x3_bits); return; } } /* default case */ if((ptr=oswald_getchar_font58(character,width))==NULL) return; if(ptr[0]&0x80) { if(ptr[0]&0x40) oswald_draw_rect(x1+(*width-1)*scalex,y1,x1+(*width-1+1)*scalex-1,y1+scaley-1,fg); y1+=2*scaley; } oswald_set_draw_window(x1,y1,x1+(4+1)*scalex-1,y1+(5+1)*scaley-1); for(y=0;y<6;y++) { for(iy=0;iy<scaley;iy++) { for(x=0;x<5;x++) { n=2+x+y*5; k=n>>3; b=n&0x7; c=(ptr[k]&(0x80>>b))?fg:bg; for(ix=0;ix<scalex;ix++) oswald_draw_point_transparent(c,bg); } } } *width*=scalex; return; } void oswald_writestr_font58_scaled(const unsigned int x1, unsigned int y1, const char *str, int *width, const uint8_t fg, const uint8_t bg,const unsigned int scalex,const unsigned int scaley) { int x,w; for(x=x1;*str!='\0';x+=w+1,str++) oswald_draw_font58_scaled(x, y1,*str,&w,fg,bg,scalex,scaley); *width=x-x1; } int oswald_getwidth_font58_scaled(char *str, int scalex, int scaley) { int total; int width; for(total=0;*str!='\0';str++) { if(oswald_getchar_font58(*str,&width)!=NULL) total+=width*scalex; total++; } return(total); } void oswald_draw_microdigit(const unsigned int x1, unsigned int y1, const uint8_t character, int *width, const uint8_t fg, const uint8_t bg) { static unsigned char micronumbers[10] = { 0xff, 0x55, 0xdb, 0xd7, /* 0-3 */ 0xbd, 0xe6, 0xef, 0xda, /* 4-7 */ 0xcf, 0xf7 /* 8-9 */ }; unsigned char bit,car; car=((character>='0' && character<='9')?micronumbers[character-'0']:0x00); oswald_set_draw_window(x1,y1,x1+1,y1+3); for(bit=0x80;bit>0;bit>>=1) oswald_draw_point_transparent((car&bit)?fg:bg,bg); *width=3; return; } void oswald_draw_tinydigit(const unsigned int x1, unsigned int y1, const uint8_t character, int *width, const uint8_t fg, const uint8_t bg) { static unsigned short tinynumbers[10] = { 0x2b6a,0x2c97,0x62a7,0x728e, 0x5bc9,0x798e,0x29aa,0x7252, 0x2aaa,0x2aca }; unsigned short bit,car; car=((character>='0' && character<='9')?tinynumbers[character-'0']:0x00); oswald_set_draw_window(x1,y1,x1+2,y1+4); for(bit=0x4000;bit>0;bit>>=1) oswald_draw_point_transparent((car&bit)?fg:bg,bg); *width=4; return; } void oswald_draw_bigdigit(const unsigned int x1, unsigned int y1, const uint8_t character, int *width, const uint8_t fg, const uint8_t bg) { *width=14; if(character>='0' && character<='9') oswald_draw_bitmap_opts(x1,y1,(character-'0')*14,0,(character-'0')*14+14,fontbigdigits_height,fg,fontbigdigits_width,fontbigdigits_height,fontbigdigits_bits); return; } void oswald_draw_line(const uint8_t xstart, const uint8_t ystart, const uint8_t xend, const uint8_t yend, const uint8_t fg) { int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; dx = xend - xstart; dy = yend - ystart; incx = (dx >= 0) ? 1 : -1; incy = (dy >= 0) ? 1 : -1; if (dx<0) dx = -dx; if (dy<0) dy = -dy; if (dx>dy) { pdx = incx; pdy = 0; ddx=incx; ddy=incy; es =dy; el =dx; } else { pdx=0; pdy=incy; ddx=incx; ddy=incy; es =dx; el =dy; } x = xstart; y = ystart; err = el/2; hal_lcd_set_pixel(x, y, fg); for (t = 0; t < el; ++t) { err -= es; if (err < 0) { err += el; x += ddx; y += ddy; } else { x += pdx; y += pdy; } hal_lcd_set_pixel(x, y, fg); } } void oswald_draw_line_ww(const uint8_t xstart, const uint8_t ystart, const uint8_t xend, const uint8_t yend, const uint8_t fg, const uint8_t thickness) { int16_t i, x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; dx = xend - xstart; dy = yend - ystart; incx = (dx >= 0) ? 1 : -1; incy = (dy >= 0) ? 1 : -1; if (dx<0) dx = -dx; if (dy<0) dy = -dy; if (dx>dy) { pdx = incx; pdy = 0; ddx = incx; ddy = incy; es = dy; el = dx; } else { pdx = 0; pdy = incy; ddx = incx; ddy = incy; es = dx; el = dy; } x = xstart; y = ystart; err = el/2; hal_lcd_set_pixel(x, y, TRUE); for (i=1; i<thickness; i++) { hal_lcd_set_pixel(x-i, y, fg); hal_lcd_set_pixel(x+i, y, fg); hal_lcd_set_pixel(x, y-i, fg); hal_lcd_set_pixel(x, y+i, fg); } for (t = 0; t < el; ++t) { err -= es; if (err < 0) { err += el; x += ddx; y += ddy; } else { x += pdx; y += pdy; } hal_lcd_set_pixel(x, y, fg); for (i=1; i<thickness; i++) { hal_lcd_set_pixel(x-i, y, fg); hal_lcd_set_pixel(x+i, y, fg); hal_lcd_set_pixel(x, y-i, fg); hal_lcd_set_pixel(x, y+i, fg); } } } uint8_t oswald_write_character(const uint8_t x, const uint8_t y, const oswald_font_face face, const boolean invert, const uint8_t Character) { int width; oswald_draw_font58(x,y,Character,&width,!invert,invert); return width+1; } void oswald_write_string(const uint8_t x, const uint8_t y, const oswald_font_face face, const boolean invert, char *str) { uint8_t lx, i, strl; strl = oswald_strlen(str); if (strl == 0) return; lx = x; for (i=0; i<strl; i++) { lx += oswald_write_character(lx, y, face, invert, str[i]); } } uint8_t oswald_write_string_length(const uint8_t x, const uint8_t y, const uint8_t len, const oswald_font_face face, const boolean invert, char *str) { uint8_t lx, i, strl; strl = oswald_strlen(str); if (strl == 0) return(0); lx = x; for (i=0; i<strl; i++) { lx += oswald_write_character(lx, y, face, invert, str[i]); if (lx > len) break; } return (i+1); } void oswald_write_number(const uint8_t x, const uint8_t y, const oswald_font_face face, const boolean invert, const int16_t number) { uint8_t lx, i, strl; char str[8]; itoa(number, str, 10); strl = oswald_strlen(str); if (strl == 0) return; lx = x; for (i=0; i<strl; i++) { lx += oswald_write_character(lx, y, face, invert, str[i]); } }