Library files for using Seeed Studio TFT Touch Shield for Arduino (ST7781R controller) together with ELMICRO TestBed for mbed. Featuring a short example program of how to calibrate the touch screen. Some basic drawing functions are also included (circle, rectangle, lines, text).

Dependencies:   mbed

2d_draw.c

Committer:
elmicro
Date:
2012-06-28
Revision:
0:db0d63650413

File content as of revision 0:db0d63650413:

#include "2d_draw.h"
#include "TFT.h"
#include "touch.h"

//unsigned char DispDir;

/* ===================================================================
    routine:    DrawCircle
    purpose:    Guess what?!
    parameters: <posX, posY>    Middlepoint of circle (pixel-aligned)
                <radius>        radius of circle (in pixels)
                <color>                         
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void DrawCircle(unsigned int posX, unsigned int posY, unsigned int radius, unsigned int color)
{
    int x = -radius, y = 0, err = 2 - 2 * radius, e2; 
    do {
        SetPixel(posX - x, posY + y, color); 
        SetPixel(posX + x, posY + y, color); 
        SetPixel(posX + x, posY - y, color); 
        SetPixel(posX - x, posY - y, color); 
        e2 = err;
        if (e2 <= y) { 
            err += ++y*2+1;
            if (-x == y && e2 <= x) e2 = 0; 
        }
        if (e2 > x) err += ++x*2+1; 
    } while (x <= 0);    
}

/* ===================================================================
    routine:    DrawHorizontalLine    
    parameters: <posX, posY>    starting point (pixel-aligned)
                <length>        length of line (in pixels)
                <color>                         
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void DrawHorizontalLine(unsigned int posX, unsigned int posY,unsigned int length,unsigned int color)
{
    SetXY(posX, posY);
    SetOrientation(0);
    if(length + posX > TFTData.XRes)
    {
        length = TFTData.XRes - posX;
    }
    for(unsigned int i=0; i<length; i++)
    {
        SendData(color);
    }
}


/* ===================================================================
    routine:    DrawVerticalLine    
    parameters: <posX, posY>    starting point (pixel-aligned)
                <length>        length of line (in pixels)
                <color>                         
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void DrawVerticalLine(unsigned int posX, unsigned int posY,unsigned int length,unsigned int color)
{
    SetXY(posX,posY);
    SetOrientation(1);
    if(length + posY > TFTData.YRes)
    {
        length = TFTData.YRes - posY;
    }

    for(unsigned int i=0; i<length; i++)
    {
        SendData(color);
    }
}


 /* ===================================================================
    routine:    DrawLine
    purpose:    Connects two points by a line with width of 1 pixel
    parameters: <xstart, xend>  starting point (pixel-aligned)
                <xstart, xend>  ending point (pixel-aligned)
                <iColor>                         
    date:       2012-06-27
    note:       Based on the Bresenham-Algorithm for rasterizing
                vector elements
    author:     (C)2006 Stefan Kleinwort (mikrocontroller.net)
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
 
void DrawLine(int xstart, int ystart, int xend ,int yend, int iColor)
{
    int x, y, t, dist, xerr, yerr, dx, dy, incx, incy;

    /* calculate distances of both directions */
     dx = xend - xstart;
     dy = yend - ystart;

    /* calculate polarity */
    if(dx<0)
    {
      incx = -1;
      dx = -dx;
    }
    else
      incx = dx ? 1 : 0;

    if(dy < 0)
    {
      incy = -1;
      dy = -dy;
    }
    else
      incy = dy ? 1 : 0;

    /* determine larger distance */
    dist = (dx > dy) ? dx : dy;

    /* loop init */
    x = xstart;
    y = ystart;
    xerr = yerr = (dist) >> 1; //dx;

    /* Calculate pixel */
    for(t = 0; t < dist; ++t)
    {
       SetPixel(x,y,iColor);
       xerr += dx;
       yerr += dy;
       if(xerr >= dist)
       {
          xerr -= dist;
          x += incx;
       }

       if(yerr >= dist)
       {
         yerr -= dist;
         y += incy;
       }
     }    
     SetPixel(x, y, iColor);
} 


/* ===================================================================
    routine:    DrawRectangle  
    purpose:    Draws outlined rectangle with width of 1 pixel
    parameters: <posX, posY>    starting point (pixel-aligned)
                <length>        length of rectangle (in pixels)
                <height>        height of rectangle (in pixels)
                <color>                         
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void DrawRectangle(unsigned int posX, unsigned int posY, unsigned int length, unsigned int height, unsigned int color)
{
    DrawHorizontalLine(posX,           posY,        length, color);
    DrawHorizontalLine(posX,           posY+height, length, color);
    DrawVerticalLine  (posX,           posY,        height,  color);
    DrawVerticalLine  (posX + length,  posY,        height,  color);
}


/* ===================================================================
    routine:    FillRectangle  
    purpose:    Draws solid rectangle
    parameters: <posX, posY>    starting point (pixel-aligned)
                <length>        length of rectangle (in pixels)
                <height>        height of rectangle (in pixels)
                <color>                         
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void FillRectangle(unsigned int posX, unsigned int posY, unsigned int length, unsigned int width, unsigned int color)
{
    for(unsigned int i=0; i<width; i++)
    {
        switch(DispDir)
        {                
            case DOWN2UP:
              DrawHorizontalLine(posX, posY-i, length, color);
              break;
            case RIGHT2LEFT:
              DrawHorizontalLine(posX, posY-i, length, color);
              break;
            case UP2DOWN:
              DrawHorizontalLine(posX, posY+i, length, color);
              break;
            case LEFT2RIGHT:
            default:
              DrawHorizontalLine(posX, posY+i, length, color);
        }                
    }
}

/* ===================================================================
    routine:    DrawAscii  
    purpose:    Displays single character
    parameters: <ascii>         character to display
                <posX, posY>    pixel-aligned starting point
                <size>          scaling factor of character
                                (size=1 means no scaling, 2 doubles the size)
                <fgcolor>                         
    note:       Needs a rastered font definition table with 8 
                bytes per character (const unsigned char simpleFont[][8])
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void DrawAscii(unsigned char ascii,unsigned int posX, unsigned int posY,unsigned int size, unsigned int fgcolor)
{
    SetXY(posX, posY);
    
    if( (ascii < 0x20) || (ascii > 0x7e) )      //check for valid ASCII char
    {
        ascii = '?';                            //char not supported
    }
    for(unsigned char i=0; i<8; i++)
    {
        unsigned char temp = simpleFont[ascii - 0x20][i];
        for(unsigned char f=0; f<8; f++)
        {
            if( (temp>>f) & 0x01 )
            {
                switch(DispDir)
                {                
                case DOWN2UP:
                    FillRectangle(posX+f*size, posY-i*size, size, size, fgcolor);
                    break;
                case RIGHT2LEFT:
                     FillRectangle(posX-i*size, posY-f*size, size, size, fgcolor);
                     break;
                case UP2DOWN:
                     FillRectangle(posX-f*size, posY+i*size, size, size, fgcolor);
                     break;
                case LEFT2RIGHT:
                default:
                       FillRectangle(posX+i*size, posY+f*size, size, size, fgcolor);
                }
            }    
        }
    }
}

/* ===================================================================
    routine:    DrawString
    purpose:    Displays string of characters
    parameters: <*string>       pointer to null-terminated (!) character
                                array
                <posX, posY>    pixel-aligned starting point
                <size>          scaling factor of characters (see DrawAscii)
                <fgcolor>                         
    note:       based on DrawAscii function
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void DrawString(char *string,unsigned int posX, unsigned int posY,unsigned int size,unsigned int fgcolor)
{
    while(*string)
    {
        DrawAscii(*string, posX, posY, size, fgcolor);
        *string++;
        switch(DispDir)
        {        
        case DOWN2UP:          
            if(posY > 0) posY-=8*size;              //Change position to next char 
              break;
        case RIGHT2LEFT:        
            if(posX > 0) posX-=8*size;                       
            break;
        case UP2DOWN:          
            if(posY < TFTData.YRes) posY+=8*size;   
            break;
        case LEFT2RIGHT:
        default:        
              if(posX < TFTData.XRes) posX+=8*size; 
        }          
    }
}


void DispPolygon2D(int *pIn, int iCorners, int iColor)
{
	int x, x1,y1;
	x1=*pIn;
	y1=*(pIn+1);
	for(x=2; x<=iCorners; x++)
	{
		DrawLine(*pIn, *(pIn+1), *(pIn+2), *(pIn+3), iColor);
		pIn+=2;
	}
	DrawLine(*pIn, *(pIn+1), x1, y1, iColor);
}