Fork of Silabs MemoryLCD library

Dependents:   demoUI whrmDemoUI Host_Software_MAX32664GWEB_HR_EXTENDED Host_Software_MAX32664GWEC_SpO2_HR-_EXTE ... more

C++ library for Sharp Microelectronics 1.28 inch LCD TFT, LS013B7DH03, SPI bus. Forked from Silicon Labs MemoryLCD display driver.

GraphicsDisplay.cpp

Committer:
stevew817
Date:
2015-08-12
Revision:
11:0f8ae10b308d
Parent:
5:26851f9655cf
Child:
12:ca0bcb4777e9

File content as of revision 11:0f8ae10b308d:

/* mbed GraphicsDisplay Display Library Base Class
 * Copyright (c) 2007-2009 sford
 * Released under the MIT License: http://mbed.org/license/mit
 */
 
#include "GraphicsDisplay.h"

#define incx() x++, dxt += d2xt, t += dxt
#define incy() y--, dyt += d2yt, t += dyt

const unsigned char FONT8x8[97][8] = {
{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}}; // DEL
    
GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name) {
    foreground((uint16_t)Black);
    background((uint16_t)White);
    // current pixel location
	_x = 0;
	_y = 0;
	// window settings
	_x1 = 0;
	_x2 = 0;
	_y1 = 0;
	_y2 = 0;
}
    
void GraphicsDisplay::character(int column, int row, int value) { 
    if(externalfont){ // send external font
        unsigned int hor,vert,offset,bpl,j,i,b;
        const unsigned char* sign;
        unsigned char z,w;
        if ((value < 31) || (value > 127)) return;   // test char range
        // read font parameter from start of array
        offset = font[0];                    // bytes / char
        hor = font[1];                       // get hor size of font
        vert = font[2];                      // get vert size of font
        bpl = font[3];                       // bytes per line
        if (char_x + hor > width()) {
            char_x = 0;
            char_y = char_y + vert;
            if (char_y >= height() - font[2]) {
                char_y = 0;
            }
        }     
        window(char_x, char_y,hor,vert); // char box
        sign = &font[((value -32) * offset) + 4]; // start of char bitmap
        w = sign[0];                          // width of actual char
        for (j=0; j<vert; j++) {  //  vert line
            for (i=0; i<hor; i++) {   //  horz line
                z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
                b = 1 << (j & 0x07);
                if (( z & b ) == 0x00) {               
                    putp(_foreground);              
                } 
                else {                     
                    putp(_background);                                
                }
            }
        }
        if ((w + 2) < hor) {                   // x offset to next char
            char_x += w + 2;
            }
            else char_x += hor;
    }   
    // send default font            
    else {
        blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
    }
}

void GraphicsDisplay::window(int x, int y, int w, int h) {
    // current pixel location
    _x = x;
    _y = y;
    // window settings
    _x1 = x;
    _x2 = x + w - 1;
    _y1 = y;
    _y2 = y + h - 1;
}
    
void GraphicsDisplay::putp(int colour) {
    // put pixel at current pixel location
    pixel(_x, _y, colour);
    // update pixel location based on window settings
    _x++;
    if(_x > _x2) {
        _x = _x1;
        _y++;
        if(_y > _y2) {
            _y = _y1;
        }
    }
}

void GraphicsDisplay::rect(int x0, int y0, int x1, int y1, int color) {
    if (x1 > x0) hline(x0,x1,y0,color);
    else  hline(x1,x0,y0,color);
    if (y1 > y0) vline(x0,y0,y1,color);
    else vline(x0,y1,y0,color);
    if (x1 > x0) hline(x0,x1,y1,color);
    else  hline(x1,x0,y1,color);
    if (y1 > y0) vline(x1,y0,y1,color);
    else vline(x1,y1,y0,color);
    return;
}
 
void GraphicsDisplay::fillrect(int x0, int y0, int w, int h, int colour) {
    unsigned long int index=0;
    if (w < 0) {
        x0 = x0 + w;
        w = -w;
    }
    if (h < 0) {
        y0 = y0 + h;
        h = -h;
    }
    window(x0,y0,w,h);
    int num = h*w;
    for( index = 0; index<num; index++ ) {
       putp(colour); 
    }
    return;
}

void GraphicsDisplay::fill(int x, int y, int w, int h, int colour) { 
    fillrect(x, y, w, h, colour);
}

void GraphicsDisplay::circle(int x, int y, int r,int colour){
	int ce = -r;
	int cx = r;
	int cy = 0;
	while(cx >= cy){
		pixel(x+cx,y+cy,colour);
		pixel(x-cx,y-cy,colour);
		pixel(x-cx,y+cy,colour);
		pixel(x+cx,y-cy,colour);
		pixel(x+cy,y+cx,colour);
		pixel(x-cy,y+cx,colour);
		pixel(x-cy,y-cx,colour);
		pixel(x+cy,y-cx,colour);
		ce += 2*cy++ + 1;
		if(ce >= 0){
			ce -= 2*cx---1;	
		}
		
	}

}

// To draw circle set a and b to the same values
void GraphicsDisplay::ellipse(int xc, int yc, int a, int b, unsigned int colour)
{
    /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
    int x = 0, y = b;
    long a2 = (long)a*a, b2 = (long)b*b;
    long crit1 = -(a2/4 + a%2 + b2);
    long crit2 = -(b2/4 + b%2 + a2);
    long crit3 = -(b2/4 + b%2);
    long t = -a2*y;                         // e(x+1/2,y-1/2) - (a^2+b^2)/4
    long dxt = 2*b2*x, dyt = -2*a2*y;
    long d2xt = 2*b2, d2yt = 2*a2;
 
    while (y>=0 && x<=a) {
        pixel(xc+x, yc+y, colour);
        if (x!=0 || y!=0)
            pixel(xc-x, yc-y, colour);
        if (x!=0 && y!=0) {
            pixel(xc+x, yc-y, colour);
            pixel(xc-x, yc+y, colour);
        }
        if (t + b2*x <= crit1 ||            // e(x+1,y-1/2) <= 0
                t + a2*y <= crit3)          // e(x+1/2,y) <= 0
            incx();
        else if (t - a2*y > crit2)          // e(x+1/2,y-1) > 0
            incy();
        else {
            incx();
            incy();
        }
    }
}
// To draw circle set a and b to the same values
void GraphicsDisplay::fillellipse(int xc, int yc, int a, int b, unsigned int colour)
{
    /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
    int x = 0, y = b;
    int rx = x, ry = y;
    unsigned int width = 1;
    unsigned int height = 1;
    long a2 = (long)a*a, b2 = (long)b*b;
    long crit1 = -(a2/4 + a%2 + b2);
    long crit2 = -(b2/4 + b%2 + a2);
    long crit3 = -(b2/4 + b%2);
    long t = -a2*y;                         // e(x+1/2,y-1/2) - (a^2+b^2)/4
    long dxt = 2*b2*x, dyt = -2*a2*y;
    long d2xt = 2*b2, d2yt = 2*a2;
    if (b == 0) {
        fillrect(xc-a, yc, 2*a+1, 1, colour);
        return;
    }
    while (y>=0 && x<=a) {
        if (t + b2*x <= crit1 ||            // e(x+1,y-1/2) <= 0
                t + a2*y <= crit3) {        // e(x+1/2,y) <= 0
            if (height == 1)
                ;                           // draw nothing
            else if (ry*2+1 > (height-1)*2) {
                fillrect(xc-rx, yc-ry, width, height-1, colour);
                fillrect(xc-rx, yc+ry+1, width, 1-height, colour);
                ry -= height-1;
                height = 1;
            } else {
                fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
                ry -= ry;
                height = 1;
            }
            incx();
            rx++;
            width += 2;
        } else if (t - a2*y > crit2) {      // e(x+1/2,y-1) > 0
            incy();
            height++;
        } else {
            if (ry*2+1 > height*2) {
                fillrect(xc-rx, yc-ry, width, height, colour);
                fillrect(xc-rx, yc+ry+1, width, -height, colour);
            } else {
                fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
            }
            incx();
            incy();
            rx++;
            width += 2;
            ry -= height;
            height = 1;
        }
    }
    if (ry > height) {
        fillrect(xc-rx, yc-ry, width, height, colour);
        fillrect(xc-rx, yc+ry+1, width, -height, colour);
    } else {
        fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
    }
}
 
 
void GraphicsDisplay::line(int x0, int y0, int x1, int y1, int colour) {
    //window(x0, y, w, h);
    int   dx = 0, dy = 0;
    int   dx_sym = 0, dy_sym = 0;
    int   dx_x2 = 0, dy_x2 = 0;
    int   di = 0;
    dx = x1-x0;
    dy = y1-y0;
 
    if (dx == 0) {        /* vertical line */
        if (y1 > y0) vline(x0,y0,y1,colour);
        else vline(x0,y1,y0,colour);
        return;
    }
    if (dx > 0) {
        dx_sym = 1;
    } else {
        dx_sym = -1;
    }
    if (dy == 0) {        /* horizontal line */
        if (x1 > x0) hline(x0,x1,y0,colour);
        else  hline(x1,x0,y0,colour);
        return;
    }
    if (dy > 0) {
        dy_sym = 1;
    } else {
        dy_sym = -1;
    }
    dx = dx_sym*dx;
    dy = dy_sym*dy;
    dx_x2 = dx*2;
    dy_x2 = dy*2;
    if (dx >= dy) {
        di = dy_x2 - dx;
        while (x0 != x1) {
 
            pixel(x0, y0, colour);
            x0 += dx_sym;
            if (di<0) {
                di += dy_x2;
            } else {
                di += dy_x2 - dx_x2;
                y0 += dy_sym;
            }
        }
        pixel(x0, y0, colour);
    } else {
        di = dx_x2 - dy;
        while (y0 != y1) {
            pixel(x0, y0, colour);
            y0 += dy_sym;
            if (di < 0) {
                di += dx_x2;
            } else {
                di += dx_x2 - dy_x2;
                x0 += dx_sym;
            }
        }
        pixel(x0, y0, colour);
    }
    return;
}
 
void GraphicsDisplay::hline(int x0, int x1, int y, int colour) {
    int w;
    w = x1 - x0 + 1;
    window(x0,y,w,1);
    for (int x=0; x<w; x++) {
        putp(colour);
    }
    return;
}
 
void GraphicsDisplay::vline(int x, int y0, int y1, int colour) {
    int h;
    h = y1 - y0 + 1;
    window(x,y0,1,h);
    for (int y=0; y<h; y++) {
        putp(colour);
    }
    return;
}

void GraphicsDisplay::cls() {
    fill(0, 0, width(), height(), _background);
}
    
void GraphicsDisplay::blit(int x, int y, int w, int h, const int *colour) { 
    window(x, y, w, h);
    for(int i=0; i<w*h; i++) {
        putp(colour[i]);
    }
}
    
void GraphicsDisplay::blitbit(int x, int y, int w, int h, const char* colour) {
    window(x, y, w, h);
    for(int i = 0; i < w*h; i++) {
        char byte = colour[i >> 3];
        int offset = i & 0x7;
        int c = ((byte << (offset)) & 0x80) ? _foreground : _background;
        putp(c);
    }
}
    
int GraphicsDisplay::columns() { 
    return width() / 8; 
}

int GraphicsDisplay::rows() { 
    return height() / 8; 
}