aboutsummaryrefslogtreecommitdiffstats
path: root/glcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'glcd.c')
-rw-r--r--glcd.c278
1 files changed, 99 insertions, 179 deletions
diff --git a/glcd.c b/glcd.c
index 01e166a8..2c6b3bba 100644
--- a/glcd.c
+++ b/glcd.c
@@ -3,89 +3,15 @@
#include <stdlib.h>
#include <math.h>
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*
- * Interface implementation. The interface is write only
- */
-
-static size_t writes(void *ip, const uint8_t *bp, size_t n) {
- (void)ip;
- return lcdWriteString(bp, n);
-}
-
-static size_t reads(void *ip, uint8_t *bp, size_t n) {
- (void)ip;
- (void)bp;
- (void)n;
- return 0;
-}
-
-static msg_t put(void *ip, uint8_t b) {
- (void)ip;
- return lcdDrawChar((char)b);
-}
-
-static msg_t get(void *ip) {
- (void)ip;
- return RDY_OK;
-}
-
-static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
- (void)ip;
- (void)timeout;
- /* TODO: handle timeout */
- return lcdDrawChar((char)b);
-}
-
-static msg_t gett(void *ip, systime_t timeout) {
- (void)ip;
- (void)timeout;
- return RDY_OK;
-}
-
-static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
- (void)ip;
- (void)time;
- return lcdWriteString(bp, n);
-}
-
-static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
- (void)ip;
- (void)bp;
- (void)n;
- (void)time;
- return 0;
-}
-
-static chnflags_t getflags(void *ip) {
- _chn_get_and_clear_flags_impl(ip);
-}
-
-static const struct GLCDDriverVMT vmt = {
- writes, reads, put, get,
- putt, gett, writet, readt,
- getflags
-};
-
uint16_t lcd_width, lcd_height;
-uint16_t bgcolor = White, fgcolor = Black;
-uint16_t cx = 0, cy = 0;
-static uint8_t tpText = 0;
-const uint8_t* font;
void lcdInit(GLCDDriver *glcdp) {
- glcdp->vmt = &vmt;
lld_lcdInit();
lcd_width = lcdGetWidth();
lcd_height = lcdGetHeight();
lcdSetOrientation(portrait);
- lcdSetFontTransparency(transparent);
- lcdSetFont(font_MediumBold);
}
uint16_t lcdGetHeight(void) {
@@ -120,6 +46,14 @@ void lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t co
lld_lcdFillArea(x0, y0, x1, y1, color);
}
+void lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *buffer, size_t n) {
+ lld_lcdSetWindow(x0, y0, x1, y1);
+
+ lld_lcdWriteStreamStart();
+ lld_lcdWriteStream(buffer, n);
+ lld_lcdWriteStreamStop();
+}
+
void lcdClear(uint16_t color) {
lld_lcdClear(color);
}
@@ -193,135 +127,118 @@ void lcdDrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t co
}
}
-void lcdSetFont(const uint8_t *newFont) {
- font = newFont;
-}
-
-void lcdSetFontTransparency(uint8_t transparency) {
- tpText = transparency;
-}
-
-msg_t lcdDrawChar(char c) {
+int lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText) {
+ /* Working pointer */
const uint8_t* ptr;
- uint8_t fontHeight = lcdGetCurFontHeight();
- uint8_t sps = font[FONT_TABLE_PAD_AFTER_CHAR_IDX];
- uint16_t chi;
- uint16_t x,y;
-
- // No support for nongraphic characters, so just ignore them
+ uint8_t x, y;
+
+ /* Variables to store character details */
+ uint8_t charWidth;
+ uint8_t charHeight = lcdGetFontHeight(font);
+ uint8_t padAfterChar = font[FONT_TABLE_PAD_AFTER_CHAR_IDX];
+
+ /* Local var to hold offset in font table */
+ uint16_t charStartOffset;
+
+ /* Working buffer for fast non-transparent text rendering [patch by Badger] */
+ static uint16_t buf[20*16];
+
+ /* No support for nongraphic characters, so just ignore them */
if(c < 0x20 || c > 0x7F) {
- if(c == '\n')
- lcdLineBreak();
return RDY_OK;
}
- chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c-0x20)*2]);
-
- ptr = font + chi;
-
- uint8_t fontWidth = *(ptr++);
-
- if(cx + fontWidth > lcdGetWidth())
- lcdLineBreak();
-
- for(x = 0; x < fontWidth; x++) {
- chi = *(uint16_t*)ptr;
- for(y = 0; y < fontHeight; y++) {
- if(chi & 0x01)
- lcdDrawPixel(cx+x, cy+y, fgcolor);
- else if(!tpText)
- lcdDrawPixel(cx+x, cy+y, bgcolor);
-
- chi >>= 1;
+ /* Read the offset of the character data in the font table from the lookup table */
+ charStartOffset = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c - 0x20) * 2]);
+
+ /* After we're done, position the pointer at the offset.
+ * The first byte that is immediately read will be the font width
+ * After that, actual 16-bit font data follows, first column down */
+ ptr = font + charStartOffset;
+ charWidth = *(ptr++);
+
+ /* Loop through the data and display. The font data is LSB first, down the column */
+ for(x = 0; x < charWidth; x++) {
+ /* Get the font bitmap data for the column */
+ uint16_t charData = *(uint16_t*)ptr;
+
+ for(y = 0; y < charHeight; y++) {
+ /* Draw the LSB on the screen accordingly. */
+ if(!tpText) {
+ /* Store data into working buffer (patch by Badger),
+ * Then write it all onto the LCD in one stroke */
+ buf[y*charWidth + x] = (charData & 0x01) ? color : bkcolor;
+ } else {
+ /* Just draw the needed pixels onto the LCD */
+ if (charData & 0x01)
+ lcdDrawPixel(cx+x, cy+y, color);
+ }
+
+ /* Shift the data down by one bit */
+ charData >>= 1;
}
+
+ /* Increment pointer by 2 bytes to the next column */
ptr += 2;
}
- cx += fontWidth;
- if(sps != 0) {
- if(!tpText)
- lcdFillArea(cx, cy, cx+sps, cy+fontHeight, bgcolor);
- cx += sps;
- }
-
- /* TODO: proper return codes */
- return RDY_OK;
-}
-
-size_t lcdWriteString(const char *str, size_t n) {
- size_t l = 0;
- for(l = 0; l < n; l++) {
- if(lcdDrawChar(*str++) != RDY_OK)
- break;
+ if(!tpText) {
+ /* [Patch by Badger] Write all in one stroke */
+ lcdWriteArea(cx, cy, cx+charWidth, cy+charHeight, buf, charWidth*charHeight);
+
+ /* Do padding after character, if needed for solid text rendering
+ * TODO: To be optimised */
+ if (padAfterChar != 0) {
+ lcdFillArea(cx+charWidth, cy+charHeight, cx+charWidth+padAfterChar, cy+charHeight, bkcolor);
+ }
}
- return l;
+ /* Return the width of the character, we need it so that lcdDrawString may work
+ * We don't have a static address counter */
+ return charWidth + padAfterChar;
}
-size_t lcdPutString(const char *str) {
- size_t l = 0;
- while(*str) {
- if(lcdDrawChar(*str++) != RDY_OK)
- break;
-
- l++;
+/* WARNING: No boundary checks! Unpredictable behaviour if text exceeds boundary */
+void lcdDrawString(uint16_t x, uint16_t y, const char *str, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText) {
+ uint16_t cx=x, cy=y;
+
+ while (*str) {
+ cx += lcdDrawChar(cx, cy, *str++, font, color, bkcolor, tpText);
}
-
- return l;
-}
-
-void lcdMoveCursor(uint16_t x, uint16_t y, uint16_t color, uint16_t bkcolor) {
- cx = x;
- cy = y;
- bgcolor = bkcolor;
- fgcolor = color;
-}
-
-void lcdDrawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bkcolor) {
- uint16_t _bg = bgcolor, _fg = fgcolor;
- cx = x;
- cy = y;
- bgcolor = bkcolor;
- fgcolor = color;
- lcdPutString(str);
- bgcolor = _bg;
- fgcolor = _fg;
}
-uint16_t lcdMeasureChar(char c) {
- const uint8_t *ptr;
-
- // First get spaces after each character, usually 0 but can change
- uint8_t sps = font[FONT_TABLE_PAD_AFTER_CHAR_IDX];
+uint16_t lcdMeasureChar(char c, font_t font) {
+ /* Variables to store character details */
+ uint8_t charWidth;
+ uint8_t padAfterChar = font[FONT_TABLE_PAD_AFTER_CHAR_IDX];
+
+ /* Local var to hold offset in font table */
+ uint16_t charStartOffset;
- uint16_t chi;
-
- if(c < 0x20 || c > 0x7F)
+ /* No support for nongraphic characters, so just ignore them */
+ if(c < 0x20 || c > 0x7F) {
return 0;
+ }
- chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c-0x20)*2]);
-
- ptr = font + chi;
-
- uint8_t fontWidth = *(ptr++);
+ /* Read the offset of the character data in the font table from the lookup table */
+ charStartOffset = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c - 0x20) * 2]);
- return fontWidth + sps;
+ /* Retrurn the byte at the offset, that's our charWidth */
+ charWidth = *(font + charStartOffset);
+
+ return charWidth+padAfterChar;
}
-uint16_t lcdMeasureString(const char *str) {
+uint16_t lcdMeasureString(const char *str, font_t font) {
uint16_t result = 0;
- while (*str)result += lcdMeasureChar(*str++);
+ /* Measure each char width, add it, return the result */
+ while (*str)
+ result += lcdMeasureChar(*str++, font);
return result;
}
-void lcdLineBreak() {
- // x=0 seems too much on the edge. So I keep it at 3
- cx = 3;
- cy += lcdGetCurFontHeight();
-}
-
uint16_t lcdBGR2RGB(uint16_t color) {
uint16_t r, g, b, rgb;
@@ -360,15 +277,15 @@ void lcdDrawRect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t fil
}
}
-void lcdDrawRectString(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const char *str, uint16_t fontColor, uint16_t bkColor) {
+void lcdDrawRectString(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const char* str, font_t font, uint16_t fontColor, uint16_t bkColor) {
uint16_t off_left, off_up;
- off_left = ((x1-x0)-lcdMeasureString(str))/2;
+ off_left = ((x1-x0)-lcdMeasureString(str, font))/2;
off_up = ((y1-y0) - lcdGetCurFontHeight()) / 2;
lcdDrawRect(x0, y0, x1, y1, 1, bkColor);
-
- lcdDrawString(x0+off_left, y0+off_up, str, fontColor, bkColor);
+ /* Abhishek: default to solid text for this? */
+ lcdDrawString(x0+off_left, y0+off_up, str, font, fontColor, bkColor, solid);
}
void lcdDrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint8_t filled, uint16_t color) {
@@ -401,3 +318,6 @@ void lcdDrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint8_t filled, uint
} while(a <= b);
}
+void lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) {
+ lld_lcdVerticalScroll(x0,y0,x1,y1,lines);
+}