]> git.defcon.no Git - avrfbosd/blobdiff - draw.c
Added support for drawing characters and strings, updated font with "limited ascii...
[avrfbosd] / draw.c
diff --git a/draw.c b/draw.c
index f2355c388d80051735269a6ebee02055c63879e4..2fd89b412406574e36fe12e5301453338b3816e1 100644 (file)
--- a/draw.c
+++ b/draw.c
@@ -1,39 +1,40 @@
 #include "draw.h"
 #include <stdlib.h>
+#include "font.h"
 
 extern uint8_t* screen_buffer;
 extern uint8_t hres_bytes;
 
 void sp(uint8_t x, uint8_t y, uint8_t color)
 {
-        if (color==0)      screen_buffer[(x/8) + (y*hres_bytes)] &= ~0x80 >> (x&7);
-        else if (color==1) screen_buffer[(x/8) + (y*hres_bytes)] |=  0x80 >> (x&7);
-        else               screen_buffer[(x/8) + (y*hres_bytes)] ^=  0x80 >> (x&7);
+       if (color==0)      screen_buffer[(x/8) + (y*hres_bytes)] &= ~0x80 >> (x&7);
+       else if (color==1) screen_buffer[(x/8) + (y*hres_bytes)] |=  0x80 >> (x&7);
+       else               screen_buffer[(x/8) + (y*hres_bytes)] ^=  0x80 >> (x&7);
 }
 
 void set_pixel(uint8_t x, uint8_t y, uint8_t color)
 {
-        if (x >= hres_bytes*8 || y >= VRES)
-                return;
-        sp(x,y,color);
+       if (x >= hres_bytes*8 || y >= VRES)
+               return;
+       sp(x,y,color);
 }
 
 void fill(uint8_t color)
 {
-        switch(color) {
-                case c_BLACK:
-                        for (int i = 0; i < (hres_bytes*VRES); i++)
-                                screen_buffer[i] = 0;
-                        break;
-                case c_WHITE:
-                        for (int i = 0; i < (hres_bytes*VRES); i++)
-                                screen_buffer[i] = 0xFF;
-                        break;
-                case c_INVERT:
-                        for (int i = 0; i < (hres_bytes*VRES); i++)
-                                screen_buffer[i] = ~screen_buffer[i];
-                        break;
-        }
+       switch(color) {
+               case c_BLACK:
+                       for (int i = 0; i < (hres_bytes*VRES); i++)
+                               screen_buffer[i] = 0;
+                       break;
+               case c_WHITE:
+                       for (int i = 0; i < (hres_bytes*VRES); i++)
+                               screen_buffer[i] = 0xFF;
+                       break;
+               case c_INVERT:
+                       for (int i = 0; i < (hres_bytes*VRES); i++)
+                               screen_buffer[i] = ~screen_buffer[i];
+                       break;
+       }
 }
 
 
@@ -63,8 +64,8 @@ Bresenham's line algorithm, optimized and simplified.
 void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t c)
 {
 
-        if (x0 > hres_bytes*8 || y0 > VRES || x1 > hres_bytes*8 || y1 > VRES)
-                return;
+       if (x0 > hres_bytes*8 || y0 > VRES) // || x1 > hres_bytes*8 || y1 > VRES)
+               return;
 
        int dx, dy, sx, sy, err, p;
 
@@ -77,7 +78,9 @@ void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t c)
        while (1)
        {
                sp(x0, y0, c);
-               if ( ( x0 == x1 ) && ( y0 == y1 ) ) return;
+               if ( ( x0 == x1 ) && ( y0 == y1 ) ) return;
+               if ( x0 > hres_bytes*8  || y0 > VRES ) return;
+               
                p = 2 * err;
                if ( p > -dy )
                {
@@ -118,30 +121,30 @@ void _draw_rect(uint8_t x0, uint8_t y0, uint8_t w, uint8_t h, int8_t c, int8_t f
 
 void _draw_circle(uint8_t x0, uint8_t y0, uint8_t radius, int8_t c, int8_t fc) {
 
-        int f = 1 - radius;
-        int ddF_x = 1;
-        int     ddF_y = -2 * radius;
-        int x = 0;
-        int y = radius;
-        uint8_t pyy = y,pyx = x;
-        
-        //there is a fill color
-        if (fc != -1)
-                draw_row(y0,x0-radius,x0+radius,fc);
-
-        sp(x0, y0 + radius,c);
-        sp(x0, y0 - radius,c);
-        sp(x0 + radius, y0,c);
-        sp(x0 - radius, y0,c);
-        
-        while(x < y) {
-                if(f >= 0) {
-                        y--;
-                        ddF_y += 2;
-                        f += ddF_y;
-                }
-                x++;
-                ddF_x += 2;
+       int f = 1 - radius;
+       int ddF_x = 1;
+       int     ddF_y = -2 * radius;
+       int x = 0;
+       int y = radius;
+       uint8_t pyy = y,pyx = x;
+
+       //there is a fill color
+       if (fc != -1)
+               draw_row(y0,x0-radius,x0+radius,fc);
+
+       sp(x0, y0 + radius,c);
+       sp(x0, y0 - radius,c);
+       sp(x0 + radius, y0,c);
+       sp(x0 - radius, y0,c);
+
+       while(x < y) {
+               if(f >= 0) {
+                       y--;
+                       ddF_y += 2;
+                       f += ddF_y;
+               }
+               x++;
+               ddF_x += 2;
                f += ddF_x;
                //there is a fill color
                if (fc > -1) {
@@ -163,10 +166,10 @@ void _draw_circle(uint8_t x0, uint8_t y0, uint8_t radius, int8_t c, int8_t fc) {
                sp(x0 + x, y0 - y,c);
                sp(x0 - x, y0 - y,c);
                sp(x0 + y, y0 + x,c);
-                sp(x0 - y, y0 + x,c);
-                sp(x0 + y, y0 - x,c);
-                sp(x0 - y, y0 - x,c);
-        }
+               sp(x0 - y, y0 + x,c);
+               sp(x0 + y, y0 - x,c);
+               sp(x0 - y, y0 - x,c);
+       }
 }
 
 void draw_rect(uint8_t x0, uint8_t y0, uint8_t w, uint8_t h, uint8_t c)
@@ -189,4 +192,53 @@ void fill_circle(uint8_t x0, uint8_t y0, uint8_t radius, char c)
        _draw_circle(x0, y0, radius, c, c);
 }
 
+void draw_8bpp_bitmap( uint8_t pos_x, uint8_t pos_y, uint8_t width, uint8_t height, const uint8_t* image )
+{
+       for ( int v = 0; v < height; v++ )
+       {
+               for ( int h = 0; h < width; h++ )
+               {
+                       uint8_t t = image[v*width+h];
+                       set_pixel( pos_x + h, pos_y + v, t);
+               }
+       }
+}
+
+void pgm_draw_8bpp_bitmap( uint8_t pos_x, uint8_t pos_y, uint8_t width, uint8_t height, const uint8_t* image )
+{
+       for ( int v = 0; v < height; v++ )
+       {
+               for ( int h = 0; h < width; h++ )
+               {
+                       uint8_t t = pgm_read_byte(&(image[v*width+h]));
+                       set_pixel( pos_x + h, pos_y + v, t);
+               }
+       }
+}
+
+void draw_char ( uint8_t pos_x, uint8_t pos_y, uint8_t ch)
+{
+       for ( int h = 0; h < font_height; h++ )
+       {
+               uint8_t fl = pgm_read_byte(&( font[ch-32][h]));
+               fl = fl<<(8-font_width);
+               
+               for ( int p = 0; p < font_width; p++ )
+               {
+                       uint8_t ft = fl<<p;
+                       ft = ft & 0x80;
+                       ft = ft>>7;
+                       set_pixel( pos_x+p, pos_y+h, ft);
+               }
+       }
+       
+}
+
+void draw_string ( uint8_t pos_x, uint8_t pos_y, const char *text)
+{
+       for (int i = 0; text[i] != 0; i++)
+       {
+               draw_char( pos_x+(font_width*i)+1, pos_y, text[i]);
+       }
+}