drawChar in worker
This commit is contained in:
parent
e4094ad468
commit
f6ce96a444
3 changed files with 90 additions and 28 deletions
87
glcd/glcd.c
87
glcd/glcd.c
|
@ -1,10 +1,16 @@
|
|||
#include "glcd.h"
|
||||
#include "glcdWorker.h"
|
||||
|
||||
#define EMSG(a) const struct a *emsg = (const struct a*)msg
|
||||
|
||||
uint16_t lcd_width, lcd_height;
|
||||
static Thread *workerThread = NULL;
|
||||
|
||||
/* internal functions; don't include in header */
|
||||
inline glcd_result_t _lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
|
||||
inline glcd_result_t _lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *buffer, size_t n);
|
||||
glcd_result_t _lcdDrawChar(struct glcd_msg_draw_char *m);
|
||||
|
||||
static WORKING_AREA(waGLCDWorkerThread, GLCD_WORKER_SIZE);
|
||||
static msg_t ThreadGLCDWorker(void *arg) {
|
||||
(void)arg;
|
||||
|
@ -43,18 +49,13 @@ static msg_t ThreadGLCDWorker(void *arg) {
|
|||
|
||||
case GLCD_FILL_AREA: {
|
||||
EMSG(glcd_msg_fill_area);
|
||||
lld_lcdFillArea(emsg->x0, emsg->y0, emsg->x1, emsg->y1, emsg->color);
|
||||
result = GLCD_DONE;
|
||||
result = _lcdFillArea(emsg->x0, emsg->y0, emsg->x1, emsg->y1, emsg->color);
|
||||
break;
|
||||
}
|
||||
|
||||
case GLCD_WRITE_AREA: {
|
||||
EMSG(glcd_msg_write_area);
|
||||
lld_lcdSetWindow(emsg->x0, emsg->y0, emsg->x1, emsg->y1);
|
||||
lld_lcdWriteStreamStart();
|
||||
lld_lcdWriteStream(emsg->buffer, emsg->size);
|
||||
lld_lcdWriteStreamStop();
|
||||
result = GLCD_DONE;
|
||||
result = _lcdWriteArea(emsg->x0, emsg->y0, emsg->x1, emsg->y1, emsg->buffer, emsg->size);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -105,6 +106,17 @@ static msg_t ThreadGLCDWorker(void *arg) {
|
|||
result = GLCD_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
case GLCD_DRAW_CHAR: {
|
||||
EMSG(glcd_msg_draw_char);
|
||||
result = _lcdDrawChar(emsg);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
result = GLCD_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done, release msg again. */
|
||||
|
@ -181,6 +193,12 @@ glcd_result_t lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, ui
|
|||
return (glcd_result_t)chMsgSend(workerThread, (msg_t)&msg);
|
||||
}
|
||||
|
||||
inline glcd_result_t _lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) {
|
||||
lld_lcdFillArea(x0, y0, x1, y1, color);
|
||||
|
||||
return GLCD_DONE;
|
||||
}
|
||||
|
||||
glcd_result_t lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *buffer, size_t n) {
|
||||
struct glcd_msg_write_area msg;
|
||||
|
||||
|
@ -195,6 +213,15 @@ glcd_result_t lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, u
|
|||
return (glcd_result_t)chMsgSend(workerThread, (msg_t)&msg);
|
||||
}
|
||||
|
||||
inline glcd_result_t _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();
|
||||
|
||||
return GLCD_DONE;
|
||||
}
|
||||
|
||||
glcd_result_t lcdClear(uint16_t color) {
|
||||
struct glcd_msg_clear msg;
|
||||
|
||||
|
@ -324,14 +351,32 @@ void lcdDrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t co
|
|||
}
|
||||
|
||||
uint16_t lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText) {
|
||||
struct glcd_msg_draw_char msg;
|
||||
|
||||
msg.action = GLCD_DRAW_CHAR;
|
||||
msg.cx = cx;
|
||||
msg.cy = cy;
|
||||
msg.c = c;
|
||||
msg.font = font;
|
||||
msg.color = color;
|
||||
msg.bkcolor = bkcolor;
|
||||
msg.tpText = tpText;
|
||||
msg.ret_width = 0;
|
||||
|
||||
chMsgSend(workerThread, (msg_t)&msg);
|
||||
|
||||
return msg.ret_width;
|
||||
}
|
||||
|
||||
glcd_result_t _lcdDrawChar(struct glcd_msg_draw_char *m) {
|
||||
/* Working pointer */
|
||||
const uint8_t* ptr;
|
||||
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];
|
||||
uint8_t charHeight = lcdGetFontHeight(m->font);
|
||||
uint8_t padAfterChar = m->font[FONT_TABLE_PAD_AFTER_CHAR_IDX];
|
||||
|
||||
/* Local var to hold offset in font table */
|
||||
uint16_t charStartOffset;
|
||||
|
@ -340,17 +385,17 @@ uint16_t lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t col
|
|||
static uint16_t buf[20*16];
|
||||
|
||||
/* No support for nongraphic characters, so just ignore them */
|
||||
if(c < 0x20 || c > 0x7F) {
|
||||
return RDY_OK;
|
||||
if(m->c < 0x20 || m->c > 0x7F) {
|
||||
return GLCD_DONE;
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
charStartOffset = *(uint16_t*)(&m->font[FONT_TABLE_CHAR_LOOKUP_IDX + (m->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;
|
||||
ptr = m->font + charStartOffset;
|
||||
charWidth = *(ptr++);
|
||||
|
||||
/* Loop through the data and display. The font data is LSB first, down the column */
|
||||
|
@ -360,14 +405,14 @@ uint16_t lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t col
|
|||
|
||||
for(y = 0; y < charHeight; y++) {
|
||||
/* Draw the LSB on the screen accordingly. */
|
||||
if(!tpText) {
|
||||
if(!m->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;
|
||||
buf[y*charWidth + x] = (charData & 0x01) ? m->color : m->bkcolor;
|
||||
} else {
|
||||
/* Just draw the needed pixels onto the LCD */
|
||||
if (charData & 0x01)
|
||||
lcdDrawPixel(cx+x, cy+y, color);
|
||||
lcdDrawPixel(m->cx+x, m->cy+y, m->color);
|
||||
}
|
||||
|
||||
/* Shift the data down by one bit */
|
||||
|
@ -378,20 +423,22 @@ uint16_t lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t col
|
|||
ptr += 2;
|
||||
}
|
||||
|
||||
if(!tpText) {
|
||||
if(!m->tpText) {
|
||||
/* [Patch by Badger] Write all in one stroke */
|
||||
lcdWriteArea(cx, cy, cx+charWidth, cy+charHeight, buf, charWidth*charHeight);
|
||||
_lcdWriteArea(m->cx, m->cy, m->cx+charWidth, m->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);
|
||||
_lcdFillArea(m->cx+charWidth, m->cy+charHeight, m->cx+charWidth+padAfterChar, m->cy+charHeight, m->bkcolor);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
m->ret_width = charWidth + padAfterChar;
|
||||
|
||||
return GLCD_DONE;
|
||||
}
|
||||
|
||||
/* WARNING: No boundary checks! Unpredictable behaviour if text exceeds boundary */
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "hal.h"
|
||||
#include "fonts.h"
|
||||
#include "fastMath.h"
|
||||
#include "glcdWorker.h"
|
||||
|
||||
#if !defined(LCD_USE_FSMC) && !defined(LCD_USE_GPIO) && !defined(LCD_USE_SPI)
|
||||
#include "glcdconf.h"
|
||||
|
@ -50,6 +49,13 @@ typedef struct GLCDDriver GLCDDriver;
|
|||
struct GLCDDriver {
|
||||
};
|
||||
|
||||
enum glcd_result { GLCD_DONE,
|
||||
GLCD_FAILED,
|
||||
GLCD_PROGRESS,
|
||||
};
|
||||
|
||||
typedef enum glcd_result glcd_result_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef GLCD_WORKER_H
|
||||
#define GLCD_WORKER_H
|
||||
|
||||
#include "glcd.h"
|
||||
|
||||
#define GLCD_WORKER_SIZE 512
|
||||
|
||||
enum glcd_action { GLCD_SET_POWERMODE,
|
||||
|
@ -15,15 +17,9 @@ enum glcd_action { GLCD_SET_POWERMODE,
|
|||
GLCD_WRITE_STREAM_STOP,
|
||||
GLCD_WRITE_STREAM,
|
||||
GLCD_VERTICAL_SCROLL,
|
||||
GLCD_DRAW_CHAR,
|
||||
};
|
||||
|
||||
enum glcd_result { GLCD_DONE,
|
||||
GLCD_FAILED,
|
||||
GLCD_PROGRESS,
|
||||
};
|
||||
|
||||
typedef enum glcd_result glcd_result_t;
|
||||
|
||||
#define _glcd_msg_base \
|
||||
enum glcd_action action;
|
||||
|
||||
|
@ -120,5 +116,18 @@ struct glcd_msg_vertical_scroll {
|
|||
int16_t lines;
|
||||
};
|
||||
|
||||
struct glcd_msg_draw_char {
|
||||
_glcd_msg_base;
|
||||
|
||||
uint16_t cx;
|
||||
uint16_t cy;
|
||||
uint16_t color;
|
||||
uint16_t bkcolor;
|
||||
uint16_t ret_width;
|
||||
char c;
|
||||
const uint8_t *font;
|
||||
bool_t tpText;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue