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.
Revision 11:0f8ae10b308d, committed 2015-08-12
- Comitter:
- stevew817
- Date:
- Wed Aug 12 14:06:07 2015 +0000
- Parent:
- 10:231fa7861d1f
- Child:
- 12:ca0bcb4777e9
- Commit message:
- Implement Paul Staron's enhancements to the display driver classes, from https://developer.mbed.org/users/star297/code/MemoryLCD/rev/b64f87859c57
Changed in this revision
--- a/GraphicsDisplay.cpp Wed Aug 12 13:32:01 2015 +0000
+++ b/GraphicsDisplay.cpp Wed Aug 12 14:06:07 2015 +0000
@@ -5,6 +5,9 @@
#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
@@ -118,7 +121,47 @@
}
void GraphicsDisplay::character(int column, int row, int value) {
- blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
+ 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) {
@@ -146,11 +189,38 @@
}
}
+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) {
- window(x, y, w, h);
- for(int i=0; i<w*h; i++) {
- putp(colour);
- }
+ fillrect(x, y, w, h, colour);
}
void GraphicsDisplay::circle(int x, int y, int r,int colour){
@@ -174,7 +244,187 @@
}
}
-
+
+// 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);
}
--- a/GraphicsDisplay.h Wed Aug 12 13:32:01 2015 +0000
+++ b/GraphicsDisplay.h Wed Aug 12 14:06:07 2015 +0000
@@ -30,8 +30,20 @@
virtual void putp(int colour);
virtual void cls();
+ virtual void rect(int x0, int y0, int x1, int y1, int colour);
+ virtual void fillrect(int x0, int y0, int w, int h, int colour);
+ // fill equals fillrect, name has been kept to not break compatibility
virtual void fill(int x, int y, int w, int h, int colour);
+
+ // To draw circle using ellipse, set a and b to the same values
+ virtual void ellipse(int xc, int yc, int a, int b, unsigned int colour);
+ virtual void fillellipse(int xc, int yc, int a, int b, unsigned int colour);
virtual void circle(int x, int y, int r, int colour);
+
+ virtual void hline(int x0, int x1, int y, int colour);
+ virtual void vline(int x0, int y0, int y1, int colour);
+ virtual void line(int x0, int y0, int x1, int y1, int colour);
+
virtual void blit(int x, int y, int w, int h, const int *colour);
virtual void blitbit(int x, int y, int w, int h, const char* colour);
--- a/TextDisplay.cpp Wed Aug 12 13:32:01 2015 +0000
+++ b/TextDisplay.cpp Wed Aug 12 14:06:07 2015 +0000
@@ -47,9 +47,23 @@
}
}
+void TextDisplay::set_font(const unsigned char * f) {
+ font = f;
+ if(font==NULL) {
+ externalfont = 0; // set display.font
+ locate(0, 0);
+ }
+ else{
+ externalfont = 1;
+ locate(0, 0);
+ }
+}
+
void TextDisplay::locate(int column, int row) {
_column = column;
_row = row;
+ char_x = column;
+ char_y = row;
}
int TextDisplay::_getc() {
--- a/TextDisplay.h Wed Aug 12 13:32:01 2015 +0000
+++ b/TextDisplay.h Wed Aug 12 14:06:07 2015 +0000
@@ -47,12 +47,21 @@
*/
virtual int columns() = 0;
+ // Sets external font usage, eg. dispaly.set_font(Arial12x12);
+ // This uses pixel positioning.
+ // display.set_font(NULL); returns to internal default font.
+ void set_font(const unsigned char * f);
+
+ // set position of the next character or string print.
+ // External font, set pixel x(column),y(row) position.
+ // internal(default) font, set character column and row position
+ virtual void locate(int column, int row);
+
// functions that come for free, but can be overwritten
/** clear screen
*/
virtual void cls();
- virtual void locate(int column, int row);
virtual void foreground(uint16_t colour);
virtual void background(uint16_t colour);
// putc (from Stream)
@@ -63,10 +72,16 @@
virtual int _putc(int value);
virtual int _getc();
-
+
+ // external font functions
+ const unsigned char* font;
+ int externalfont;
+
// character location
uint16_t _column;
uint16_t _row;
+ unsigned int char_x;
+ unsigned int char_y;
// colours
uint16_t _foreground;