From a26664be9bf6dcdccf05c3f0cbe6c245c0ca41de Mon Sep 17 00:00:00 2001
From: Mateusz Zalega <mateusz@appliedsourcery.com>
Date: Mon, 12 Aug 2019 15:23:28 +0000
Subject: [PATCH] feat(gfx): Replace vendor implementation
This commit substitutes the vendor gfx library with a completely
new implementation. It also adds a text-buffer mode.
Signed-off-by: Mateusz Zalega <mateusz@appliedsourcery.com>
---
bootloader/bootloader-display.c | 21 +-
epicardium/main.c | 11 +-
epicardium/modules/display.c | 67 ++-
hw-tests/bmetest/main.c | 24 +-
hw-tests/bootloader-update/main.c | 29 +-
hw-tests/dual-core/main.c | 9 +-
hw-tests/ecgtest/main.c | 18 +-
hw-tests/hello-world/main.c | 9 +-
hw-tests/imutest/main.c | 31 +-
hw-tests/ips/main.c | 46 +-
lib/card10/display.c | 15 +-
lib/card10/display.h | 5 +
lib/gfx/GUI_DEV/GUI_Paint.c | 683 ------------------------------
lib/gfx/GUI_DEV/GUI_Paint.h | 207 ---------
lib/gfx/LCD/LCD_Driver.c | 39 +-
lib/gfx/LCD/LCD_Driver.h | 3 +
lib/gfx/framebuffer.c | 101 +++++
lib/gfx/framebuffer.h | 39 ++
lib/gfx/gfx.c | 254 +++++++++++
lib/gfx/gfx.h | 59 +++
lib/gfx/meson.build | 4 +-
lib/gfx/textbuffer.c | 251 +++++++++++
lib/gfx/textbuffer.h | 49 +++
23 files changed, 982 insertions(+), 992 deletions(-)
delete mode 100644 lib/gfx/GUI_DEV/GUI_Paint.c
delete mode 100644 lib/gfx/GUI_DEV/GUI_Paint.h
create mode 100644 lib/gfx/framebuffer.c
create mode 100644 lib/gfx/framebuffer.h
create mode 100644 lib/gfx/gfx.c
create mode 100644 lib/gfx/gfx.h
create mode 100644 lib/gfx/textbuffer.c
create mode 100644 lib/gfx/textbuffer.h
diff --git a/bootloader/bootloader-display.c b/bootloader/bootloader-display.c
index 1fe0cae0..abc8dfc2 100644
--- a/bootloader/bootloader-display.c
+++ b/bootloader/bootloader-display.c
@@ -2,7 +2,7 @@
/* Autogenerated */
#include "splash-screen.h"
-#include "GUI_Paint.h"
+#include "gfx.h"
#include "display.h"
/*
@@ -16,19 +16,21 @@ static void bootloader_display_splash(void)
{
int idx = 0;
+ Color white = gfx_color(&display_screen, WHITE);
+ Color black = gfx_color(&display_screen, BLACK);
for (int i = 0; i < sizeof(splash); i++) {
- uint16_t color = (splash[i] & 0x80) ? 0xffff : 0x0000;
+ Color color = (splash[i] & 0x80) ? white : black;
uint8_t length = splash[i] & 0x7f;
for (int j = 0; j < length; j++) {
uint16_t x = idx % 160;
uint16_t y = idx / 160;
- Paint_SetPixel(x, y, color);
+ gfx_setpixel(&display_screen, x, y, color);
idx++;
}
}
- LCD_Update();
+ gfx_update(&display_screen);
}
/*
@@ -44,10 +46,8 @@ void bootloader_display_init(void)
*/
void bootloader_display_header(void)
{
- Paint_Clear(0x0000);
- Paint_DrawString_EN(0, 16 * 0, "Bootloader", &Font16, 0x0000, 0xffff);
- Paint_DrawString_EN(0, 16 * 1, __DATE__, &Font16, 0x0000, 0xffff);
- LCD_Update();
+ txt_puts(&display_textb, "Bootloader\n");
+ txt_puts(&display_textb, __DATE__ "\n");
}
/*
@@ -55,6 +55,7 @@ void bootloader_display_header(void)
*/
void bootloader_display_line(int line, char *string, uint16_t color)
{
- Paint_DrawString_EN(0, 16 * line, string, &Font16, 0x0000, color);
- LCD_Update();
+ Color black = gfx_color(&display_screen, BLACK);
+ gfx_puts(&Font16, &display_screen, 0, 16 * line, string, color, black);
+ gfx_update(&display_screen);
}
diff --git a/epicardium/main.c b/epicardium/main.c
index 89d5c07d..719bb3bb 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -18,8 +18,9 @@
#include "modules/filesystem.h"
#include "api/interrupt-sender.h"
-#include <Heart.h>
-#include "GUI_Paint.h"
+#include "Heart.h"
+#include "gfx.h"
+#include "display.h"
#include "FreeRTOS.h"
#include "task.h"
@@ -50,8 +51,10 @@ int main(void)
card10_init();
card10_diag();
- Paint_DrawImage(Heart, 0, 0, 160, 80);
- LCD_Update();
+ gfx_copy_region_raw(
+ &display_screen, 0, 0, 160, 80, 2, (const void *)(Heart)
+ );
+ gfx_update(&display_screen);
/* TODO: Move this to its own function */
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
diff --git a/epicardium/modules/display.c b/epicardium/modules/display.c
index 1f50acae..afb0401d 100644
--- a/epicardium/modules/display.c
+++ b/epicardium/modules/display.c
@@ -1,11 +1,13 @@
#include "epicardium.h"
#include "tmr_utils.h"
#include "gpio.h"
-#include "GUI_DEV/GUI_Paint.h"
#include "Fonts/fonts.h"
#include "tmr.h"
#include "FreeRTOS.h"
#include "task.h"
+#include "gfx.h"
+#include "display.h"
+#include "LCD_Driver.h"
static TaskHandle_t lock = NULL;
@@ -30,7 +32,7 @@ int epic_disp_print(
if (cl < 0) {
return cl;
} else {
- Paint_DrawString_EN(posx, posy, pString, &Font20, bg, fg);
+ gfx_puts(&Font20, &display_screen, posx, posy, pString, fg, bg);
return 0;
}
}
@@ -41,7 +43,7 @@ int epic_disp_clear(uint16_t color)
if (cl < 0) {
return cl;
} else {
- LCD_Clear(color);
+ gfx_clear_to_color(&display_screen, color);
return 0;
}
}
@@ -52,7 +54,7 @@ int epic_disp_pixel(uint16_t x, uint16_t y, uint16_t color)
if (cl < 0) {
return cl;
} else {
- Paint_SetPixel(x, y, color);
+ gfx_setpixel(&display_screen, x, y, color);
return 0;
}
}
@@ -70,8 +72,15 @@ int epic_disp_line(
if (cl < 0) {
return cl;
} else {
- Paint_DrawLine(
- xstart, ystart, xend, yend, color, linestyle, pixelsize
+ /* TODO add linestyle support to gfx code */
+ gfx_thick_line(
+ &display_screen,
+ xstart,
+ ystart,
+ xend,
+ yend,
+ pixelsize,
+ color
);
return 0;
}
@@ -87,14 +96,33 @@ int epic_disp_rect(
uint16_t pixelsize
) {
int cl = check_lock();
- if (cl < 0) {
+ if (cl < 0)
return cl;
- } else {
- Paint_DrawRectangle(
- xstart, ystart, xend, yend, color, fillstyle, pixelsize
+
+ switch (fillstyle) {
+ case FILLSTYLE_EMPTY:
+ gfx_rectangle(
+ &display_screen,
+ xstart,
+ ystart,
+ xend - xstart,
+ yend - ystart,
+ pixelsize,
+ color
);
- return 0;
+ break;
+ case FILLSTYLE_FILLED:
+ gfx_rectangle_fill(
+ &display_screen,
+ xstart,
+ ystart,
+ xend - xstart,
+ yend - ystart,
+ color
+ );
+ break;
}
+ return 0;
}
int epic_disp_circ(
@@ -106,12 +134,19 @@ int epic_disp_circ(
uint16_t pixelsize
) {
int cl = check_lock();
- if (cl < 0) {
+ if (cl < 0)
return cl;
- } else {
- Paint_DrawCircle(x, y, rad, color, fillstyle, pixelsize);
- return 0;
+
+ switch (fillstyle) {
+ case FILLSTYLE_EMPTY:
+ gfx_circle(&display_screen, x, y, rad, pixelsize, color);
+ break;
+ case FILLSTYLE_FILLED:
+ gfx_circle_fill(&display_screen, x, y, rad, color);
+ break;
}
+
+ return 0;
}
int epic_disp_update()
@@ -121,7 +156,7 @@ int epic_disp_update()
return cl;
}
- LCD_Update();
+ gfx_update(&display_screen);
return 0;
}
diff --git a/hw-tests/bmetest/main.c b/hw-tests/bmetest/main.c
index 5cc2c38f..16244ec8 100644
--- a/hw-tests/bmetest/main.c
+++ b/hw-tests/bmetest/main.c
@@ -11,7 +11,9 @@
#include "gpio.h"
#include "bme680.h"
#include "bosch.h"
-#include "GUI_DEV/GUI_Paint.h"
+#include "gfx.h"
+#include "framebuffer.h"
+#include "display.h"
#include "Fonts/fonts.h"
#include "card10.h"
@@ -73,6 +75,8 @@ int main(void)
/* Set the power mode */
rslt = bme680_set_sensor_mode(&gas_sensor);
+ Color white = gfx_color(&display_screen, WHITE);
+ Color black = gfx_color(&display_screen, BLACK);
while (1) {
TMR_Delay(MXC_TMR0, MSEC(1000), 0);
@@ -86,13 +90,13 @@ int main(void)
char buf[128];
sprintf(buf, "T: %.2Lf degC", data.temperature / 100.0l);
- Paint_DrawString_EN(0, 0, buf, &Font16, 0x0000, 0xffff);
+ gfx_puts(&Font16, &display_screen, 0, 0, buf, white, black);
sprintf(buf, "P: %.2Lf hPa", data.pressure / 100.0l);
- Paint_DrawString_EN(0, 16, buf, &Font16, 0x0000, 0xffff);
+ gfx_puts(&Font16, &display_screen, 0, 16, buf, white, black);
sprintf(buf, "H: %.2Lf %%rH", data.humidity / 1000.0l);
- Paint_DrawString_EN(0, 32, buf, &Font16, 0x0000, 0xffff);
+ gfx_puts(&Font16, &display_screen, 0, 32, buf, white, black);
//printf("%.2f,%.2f,%.2f\n", data.temperature / 100.0f,
// data.pressure / 100.0f, data.humidity / 1000.0f );
@@ -100,12 +104,18 @@ int main(void)
if (data.status & BME680_GASM_VALID_MSK) {
printf(", G: %ld ohms", data.gas_resistance);
sprintf(buf, "G: %ld ohms", data.gas_resistance);
- Paint_DrawString_EN(
- 0, 48, buf, &Font16, 0x0000, 0xffff
+ gfx_puts(
+ &Font16,
+ &display_screen,
+ 0,
+ 48,
+ buf,
+ white,
+ black
);
}
- LCD_Update();
+ gfx_update(&display_screen);
printf("\n");
diff --git a/hw-tests/bootloader-update/main.c b/hw-tests/bootloader-update/main.c
index 9e96aa38..64b49252 100644
--- a/hw-tests/bootloader-update/main.c
+++ b/hw-tests/bootloader-update/main.c
@@ -6,7 +6,7 @@
#include "card10.h"
#include "bootloader-9251ea6.h"
#include "display.h"
-#include "GUI_Paint.h"
+#include "gfx.h"
#include "pmic.h"
#include "flc.h"
@@ -42,29 +42,20 @@ int main(void)
pmic_set_button_callback(pmic_button);
printf("Erasing bootloader.\n");
- Paint_DrawString_EN(
- 0, 16 * 0, "Erasing bootloader", &Font16, 0x0000, 0xffff
- );
- LCD_Update();
+ txt_puts(&display_textb, "Erasing bootloader.\n");
ICC_Disable();
int ret = FLC_MultiPageErase(0x10000000, 0x10000000 + 1024 * 64 - 1);
if (ret != E_NO_ERROR) {
printf("FLC_MultiPageErase failed with %d\n", ret);
- Paint_DrawString_EN(
- 0, 16 * 1, "Fail.", &Font16, 0x0000, 0xffff
- );
- LCD_Update();
+ txt_puts(&display_textb, "Fail.\n");
while (1)
;
}
printf("Writing bootloader.\n");
- Paint_DrawString_EN(
- 0, 16 * 0, "Writing bootloader ", &Font16, 0x0000, 0xffff
- );
- LCD_Update();
+ txt_puts(&display_textb, "Writing bootloader.\n");
ret = FLC_Write(
0x10000000,
@@ -73,21 +64,15 @@ int main(void)
);
if (ret != E_NO_ERROR) {
printf("FLC_Write failed with %d\n", ret);
- Paint_DrawString_EN(
- 0, 16 * 1, "Fail.", &Font16, 0x0000, 0xffff
- );
- LCD_Update();
+ txt_puts(&display_textb, "Fail.\n");
while (1)
;
}
ICC_Enable();
printf("Done.\n");
- Paint_DrawString_EN(0, 16 * 1, "Done.", &Font16, 0x0000, 0xffff);
- Paint_DrawString_EN(
- 0, 16 * 2, "Please restart", &Font16, 0x0000, 0xffff
- );
- LCD_Update();
+ txt_puts(&display_textb, "Done.\n");
+ txt_puts(&display_textb, "Please restart.\n");
while (1) {
card10_poll();
diff --git a/hw-tests/dual-core/main.c b/hw-tests/dual-core/main.c
index 5c279502..60636833 100644
--- a/hw-tests/dual-core/main.c
+++ b/hw-tests/dual-core/main.c
@@ -7,7 +7,8 @@
#include "leds.h"
#include "card10.h"
-#include "GUI_Paint.h"
+#include "gfx.h"
+#include "display.h"
#include "tmr_utils.h"
@@ -21,8 +22,10 @@ int main(void)
card10_init();
card10_diag();
- Paint_DrawImage(Heart, 0, 0, 160, 80);
- LCD_Update();
+ gfx_copy_region_raw(
+ &display_screen, 0, 0, 160, 80, 2, (const void *)(Heart)
+ );
+ gfx_update(&display_screen);
// Release core1
core1_start((void *)0x10080000);
diff --git a/hw-tests/ecgtest/main.c b/hw-tests/ecgtest/main.c
index 965d325c..2ca6cbdd 100644
--- a/hw-tests/ecgtest/main.c
+++ b/hw-tests/ecgtest/main.c
@@ -16,7 +16,9 @@
#include "spi.h"
#include "pb.h"
#include "MAX30003.h"
-#include "GUI_DEV/GUI_Paint.h"
+#include "gfx.h"
+#include "LCD_Driver.h"
+#include "display.h"
#include "pmic.h"
#include "card10.h"
#include <stdbool.h>
@@ -150,7 +152,7 @@ static uint8_t prev;
static void clear(void)
{
- Paint_Clear(BLACK);
+ gfx_clear(&display_screen);
prev = Y_OFFSET;
}
@@ -173,7 +175,7 @@ static void set(uint8_t index, int8_t val)
}
for (int i = min; i < max + 1; i++) {
- LCD_SetUWORD(SIZE_X - index - 1, i, RED);
+ LCD_SetUWORD(SIZE_X - index - 1, i, 0xf800);
}
prev = pos;
@@ -199,7 +201,15 @@ void update(void)
ecg_switch,
internal_pull,
scale);
- Paint_DrawString_EN(0, 0, buf, &Font8, 0x0000, 0xffff);
+ gfx_puts(
+ &Font8,
+ &display_screen,
+ 0,
+ 0,
+ buf,
+ gfx_color(&display_screen, WHITE),
+ gfx_color(&display_screen, BLACK)
+ );
for (int i = 0; i < SIZE_X; i++) {
set(i, (samples[i] / scale));
diff --git a/hw-tests/hello-world/main.c b/hw-tests/hello-world/main.c
index b797233b..87fdab3b 100644
--- a/hw-tests/hello-world/main.c
+++ b/hw-tests/hello-world/main.c
@@ -7,7 +7,8 @@
#include "leds.h"
#include "card10.h"
-#include "GUI_Paint.h"
+#include "gfx.h"
+#include "display.h"
#include "tmr_utils.h"
@@ -29,8 +30,10 @@ int main(void)
card10_init();
card10_diag();
- Paint_DrawImage(Heart, 0, 0, 160, 80);
- LCD_Update();
+ gfx_copy_region_raw(
+ &display_screen, 0, 0, 160, 80, 2, (const void *)(Heart)
+ );
+ gfx_update(&display_screen);
for (int i = 0; i < 11; i++) {
// leds_set_dim(i, 1);
diff --git a/hw-tests/imutest/main.c b/hw-tests/imutest/main.c
index 7e3db466..9472d57f 100644
--- a/hw-tests/imutest/main.c
+++ b/hw-tests/imutest/main.c
@@ -13,7 +13,8 @@
#include "gpio.h"
#include "bhy_uc_driver.h"
#include "pmic.h"
-#include "GUI_DEV/GUI_Paint.h"
+#include "gfx.h"
+#include "display.h"
#include "card10.h"
@@ -48,7 +49,7 @@ void draw_arrow(int angle, int color)
int x2 = x1 - sin * 30;
int y2 = y1 - cos * 30;
- Paint_DrawLine(x1, y1, x2, y2, color, LINE_STYLE_SOLID, DOT_PIXEL_2X2);
+ gfx_thick_line(&display_screen, x1, y1, x2, y2, 2, color);
sin = sinf((angle - 140) * 2 * M_PI / 360.);
cos = cosf((angle - 140) * 2 * M_PI / 360.);
@@ -56,7 +57,7 @@ void draw_arrow(int angle, int color)
int x3 = x2 - sin * 10;
int y3 = y2 - cos * 10;
- Paint_DrawLine(x2, y2, x3, y3, color, LINE_STYLE_SOLID, DOT_PIXEL_2X2);
+ gfx_thick_line(&display_screen, x2, y2, x3, y3, 2, color);
sin = sinf((angle + 140) * 2 * M_PI / 360.);
cos = cosf((angle + 140) * 2 * M_PI / 360.);
@@ -64,7 +65,7 @@ void draw_arrow(int angle, int color)
int x4 = x2 - sin * 10;
int y4 = y2 - cos * 10;
- Paint_DrawLine(x2, y2, x4, y4, color, LINE_STYLE_SOLID, DOT_PIXEL_2X2);
+ gfx_thick_line(&display_screen, x2, y2, x4, y4, 2, color);
}
/***** Functions *****/
@@ -81,8 +82,12 @@ static void sensors_callback_orientation(
int angle = sensor_data->data_vector.x * 360 / 32768;
if (angle != prev) {
- Paint_Clear(BLACK);
- int colors[] = { RED, YELLOW, YELLOW, GREEN };
+ gfx_clear(&display_screen);
+
+ int colors[] = { gfx_color(&display_screen, RED),
+ gfx_color(&display_screen, YELLOW),
+ gfx_color(&display_screen, YELLOW),
+ gfx_color(&display_screen, GREEN) };
int color = colors[sensor_data->data_vector.status];
draw_arrow(sensor_data->data_vector.x * 360 / 32768, color);
@@ -91,12 +96,18 @@ static void sensors_callback_orientation(
//Paint_DrawString_EN(0, 0, buf, &Font12, BLACK, color);
sprintf(buf, "%3d", angle);
- Paint_DrawString_EN(0, 30, buf, &Font24, BLACK, color);
- Paint_DrawCircle(
- 57, 35, 4, color, DRAW_FILL_EMPTY, DOT_PIXEL_1X1
+ gfx_puts(
+ &Font24,
+ &display_screen,
+ 0,
+ 30,
+ buf,
+ color,
+ gfx_color(&display_screen, BLACK)
);
+ gfx_circle(&display_screen, 57, 35, 4, 2, color);
- LCD_Update();
+ gfx_update(&display_screen);
prev = angle;
}
}
diff --git a/hw-tests/ips/main.c b/hw-tests/ips/main.c
index a4fd5ad7..888185ed 100644
--- a/hw-tests/ips/main.c
+++ b/hw-tests/ips/main.c
@@ -5,10 +5,12 @@
/***** Includes *****/
#include "tmr_utils.h"
#include "gpio.h"
-#include "GUI_DEV/GUI_Paint.h"
+#include "gfx.h"
+#include "display.h"
#include "Fonts/fonts.h"
#include "image/image.h"
#include "tmr.h"
+#include "DEV_Config.h"
#include "card10.h"
@@ -24,23 +26,37 @@ int main(void)
card10_init();
card10_diag();
- Paint_DrawString_EN(0, 0, "123", &Font24, 0x000f, 0xfff0);
- Paint_DrawString_EN(0, 23, "ABC", &Font24, BLUE, CYAN);
- Paint_DrawString_CN(20, 42, "΢ѩµç×Ó", &Font24CN, WHITE, RED);
- Paint_DrawRectangle(
- 70, 10, 100, 40, RED, DRAW_FILL_EMPTY, DOT_PIXEL_2X2
- );
- Paint_DrawLine(
- 70, 10, 100, 40, MAGENTA, LINE_STYLE_SOLID, DOT_PIXEL_2X2
+ Color red = gfx_color(&display_screen, RED);
+ Color green = gfx_color(&display_screen, GREEN);
+ Color yellow = gfx_color(&display_screen, YELLOW);
+
+ gfx_puts(&Font24, &display_screen, 0, 0, "123", 0x000f, 0xfff8);
+ gfx_puts(&Font24, &display_screen, 23, 0, "ABC", 0x000f, 0xfff8);
+ gfx_rectangle(&display_screen, 70, 10, 100, 40, 2, red);
+ gfx_thick_line(&display_screen, 70, 10, 100, 40, 2, green);
+ gfx_thick_line(&display_screen, 100, 10, 70, 40, 2, yellow);
+ gfx_circle(&display_screen, 85, 25, 22, 2, green);
+
+ gfx_copy_region_raw(
+ &display_screen,
+ 120,
+ 0,
+ 40,
+ 40,
+ 2,
+ (const void *)(gImage_40X40)
);
- Paint_DrawLine(
- 100, 10, 70, 40, MAGENTA, LINE_STYLE_SOLID, DOT_PIXEL_2X2
+ gfx_copy_region_raw(
+ &display_screen,
+ 0,
+ 0,
+ 160,
+ 80,
+ 2,
+ (const void *)(gImage_160X80)
);
- Paint_DrawCircle(85, 25, 22, GREEN, DRAW_FILL_EMPTY, DOT_PIXEL_2X2);
+ gfx_update(&display_screen);
- Paint_DrawImage(gImage_40X40, 120, 0, 40, 40);
- Paint_DrawImage(gImage_160X80, 0, 0, 160, 80);
- LCD_Update();
DEV_Delay_ms(3000);
while (1) {
diff --git a/lib/card10/display.c b/lib/card10/display.c
index e1d66276..2756ccb7 100644
--- a/lib/card10/display.c
+++ b/lib/card10/display.c
@@ -1,5 +1,7 @@
#include "LCD/LCD_Driver.h"
-#include "GUI_DEV/GUI_Paint.h"
+#include "framebuffer.h"
+#include "gfx.h"
+#include "textbuffer.h"
#include "gpio.h"
#include "tmr.h"
@@ -11,6 +13,9 @@
/***** Globals *****/
const gpio_cfg_t DEV_DC_PIN = { PORT_1, PIN_6, GPIO_FUNC_OUT, GPIO_PAD_NONE };
+struct gfx_region display_screen;
+struct txt_buffer display_textb;
+
// Parameters for PWM output
#define PORT_PWM PORT_0 // port
#define PIN_PWM PIN_28 // pin
@@ -93,10 +98,8 @@ void display_init(void)
PWM_Output();
LCD_SetBacklight(500);
LCD_Init();
- LCD_Clear(BLACK);
-
- Paint_NewImage(LCD_WIDTH, LCD_HEIGHT, 0, WHITE);
- Paint_Clear(BLACK);
- Paint_SetRotate(180);
+ display_screen = gfx_screen(LCD_framebuffer());
+ txt_init(&display_textb, &display_screen, &Font12);
+ gfx_clear(&display_screen);
}
diff --git a/lib/card10/display.h b/lib/card10/display.h
index e4244b58..47f82a37 100644
--- a/lib/card10/display.h
+++ b/lib/card10/display.h
@@ -1,4 +1,9 @@
#ifndef DISPLAY_H
+#include "framebuffer.h"
+#include "textbuffer.h"
+
+extern struct gfx_region display_screen;
+extern struct txt_buffer display_textb;
void display_init(void);
diff --git a/lib/gfx/GUI_DEV/GUI_Paint.c b/lib/gfx/GUI_DEV/GUI_Paint.c
deleted file mode 100644
index 13cbba25..00000000
--- a/lib/gfx/GUI_DEV/GUI_Paint.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*****************************************************************************
-* | File : GUI_Paint.c
-* | Author : Waveshare team
-* | Function : Achieve drawing: draw points, lines, boxes, circles and
-* their size, solid dotted line, solid rectangle hollow
-* rectangle, solid circle hollow circle.
-* | Info :
-* Achieve display characters: Display a single character, string, number
-* Achieve time display: adaptive size display time minutes and seconds
-*----------------
-* | This version: V2.0
-* | Date : 2018-11-15
-* | Info :
-* 1.add: Paint_NewImage()
-* Create an image's properties
-* 2.add: Paint_SelectImage()
-* Select the picture to be drawn
-* 3.add: Paint_SetRotate()
-* Set the direction of the cache
-* 4.add: Paint_RotateImage()
-* Can flip the picture, Support 0-360 degrees,
-* but only 90.180.270 rotation is better
-* 4.add: Paint_SetMirroring()
-* Can Mirroring the picture, horizontal, vertical, origin
-* 5.add: Paint_DrawString_CN()
-* Can display Chinese(GB1312)
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documnetation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is
-* furished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in
-* all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-* THE SOFTWARE.
-*
-******************************************************************************/
-#include "GUI_Paint.h"
-#include "DEV_Config.h"
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h> //memset()
-#include <math.h>
-
-volatile PAINT Paint;
-
-/******************************************************************************
-function: Create Image
-parameter:
- image : Pointer to the image cache
- width : The width of the picture
- Height : The height of the picture
- Color : Whether the picture is inverted
-******************************************************************************/
-void Paint_NewImage(UWORD Width, UWORD Height, UWORD Rotate, UWORD Color)
-{
- Paint.WidthMemory = Width;
- Paint.HeightMemory = Height;
- Paint.Color = Color;
- Paint.WidthByte = Width;
- Paint.HeightByte = Height;
- printf("WidthByte = %d, HeightByte = %d\r\n", Paint.WidthByte, Paint.HeightByte);
- printf(" EPD_WIDTH / 8 = %d\r\n", 122 / 8);
-
- Paint.Rotate = Rotate;
- Paint.Mirror = MIRROR_NONE;
-
- if(Rotate == ROTATE_0 || Rotate == ROTATE_180) {
- Paint.Width = Width;
- Paint.Height = Height;
- } else {
- Paint.Width = Height;
- Paint.Height = Width;
- }
-}
-
-/******************************************************************************
-function: Select Image Rotate
-parameter:
- Rotate : 0,90,180,270
-******************************************************************************/
-void Paint_SetRotate(UWORD Rotate)
-{
- if(Rotate == ROTATE_0 || Rotate == ROTATE_90 || Rotate == ROTATE_180 || Rotate == ROTATE_270) {
- Debug("Set image Rotate %d\r\n", Rotate);
- Paint.Rotate = Rotate;
- } else {
- Debug("rotate = 0, 90, 180, 270\r\n");
- // exit(0);
- }
-}
-
-/******************************************************************************
-function: Select Image mirror
-parameter:
- mirror : Not mirror,Horizontal mirror,Vertical mirror,Origin mirror
-******************************************************************************/
-void Paint_SetMirroring(UBYTE mirror)
-{
- if(mirror == MIRROR_NONE || mirror == MIRROR_HORIZONTAL ||
- mirror == MIRROR_VERTICAL || mirror == MIRROR_ORIGIN) {
- Debug("mirror image x:%s, y:%s\r\n",(mirror & 0x01)? "mirror":"none", ((mirror >> 1) & 0x01)? "mirror":"none");
- Paint.Mirror = mirror;
- } else {
- Debug("mirror should be MIRROR_NONE, MIRROR_HORIZONTAL, \
- MIRROR_VERTICAL or MIRROR_ORIGIN\r\n");
-//exit(0);
- }
-}
-
-/******************************************************************************
-function: Draw Pixels
-parameter:
- Xpoint : At point X
- Ypoint : At point Y
- Color : Painted colors
-******************************************************************************/
-void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
-{
- if(Xpoint > Paint.Width || Ypoint > Paint.Height){
- Debug("Exceeding display boundaries\r\n");
- return;
- }
- UWORD X, Y;
-
- switch(Paint.Rotate) {
- case 0:
- X = Xpoint;
- Y = Ypoint;
- break;
- case 90:
- X = Paint.WidthMemory - Ypoint - 1;
- Y = Xpoint;
- break;
- case 180:
- X = Paint.WidthMemory - Xpoint - 1;
- Y = Paint.HeightMemory - Ypoint - 1;
- break;
- case 270:
- X = Ypoint;
- Y = Paint.HeightMemory - Xpoint - 1;
- break;
-
- default:
- return;
- }
-
- switch(Paint.Mirror) {
- case MIRROR_NONE:
- break;
- case MIRROR_HORIZONTAL:
- X = Paint.WidthMemory - X - 1;
- break;
- case MIRROR_VERTICAL:
- Y = Paint.HeightMemory - Y - 1;
- break;
- case MIRROR_ORIGIN:
- X = Paint.WidthMemory - X - 1;
- Y = Paint.HeightMemory - Y - 1;
- break;
- default:
- return;
- }
-
- // printf("x = %d, y = %d\r\n", X, Y);
- if(X > Paint.WidthMemory || Y > Paint.HeightMemory){
- Debug("Exceeding display boundaries\r\n");
- return;
- }
-
- // UDOUBLE Addr = X / 8 + Y * Paint.WidthByte;
- LCD_SetUWORD(X,Y, Color);
-}
-
-/******************************************************************************
-function: Clear the color of the picture
-parameter:
- Color : Painted colors
-******************************************************************************/
-void Paint_Clear(UWORD Color)
-{
- LCD_Clear(Color);
-}
-
-/******************************************************************************
-function: Clear the color of a window
-parameter:
- Xstart : x starting point
- Ystart : Y starting point
- Xend : x end point
- Yend : y end point
-******************************************************************************/
-void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color)
-{
- UWORD X, Y;
- for (Y = Ystart; Y < Yend; Y++) {
- for (X = Xstart; X < Xend; X++) {//8 pixel = 1 byte
- Paint_SetPixel(X, Y, Color);
- }
- }
-}
-
-/******************************************************************************
-function: Draw Point(Xpoint, Ypoint) Fill the color
-parameter:
- Xpoint : The Xpoint coordinate of the point
- Ypoint : The Ypoint coordinate of the point
- Color : Set color
- Dot_Pixel : point size
-******************************************************************************/
-void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color,
- DOT_PIXEL Dot_Pixel, DOT_STYLE DOT_STYLE)
-{
- if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
- // Debug("Paint_DrawPoint Input exceeds the normal display range\r\n");
- return;
- }
-
- int16_t XDir_Num , YDir_Num;
- if (DOT_STYLE == DOT_FILL_AROUND) {
- for (XDir_Num = 0; XDir_Num < 2*Dot_Pixel - 1; XDir_Num++) {
- for (YDir_Num = 0; YDir_Num < 2 * Dot_Pixel - 1; YDir_Num++) {
- if(Xpoint + XDir_Num - Dot_Pixel < 0 || Ypoint + YDir_Num - Dot_Pixel < 0)
- break;
- // printf("x = %d, y = %d\r\n", Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel);
- Paint_SetPixel(Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel, Color);
- }
- }
- } else {
- for (XDir_Num = 0; XDir_Num < Dot_Pixel; XDir_Num++) {
- for (YDir_Num = 0; YDir_Num < Dot_Pixel; YDir_Num++) {
- Paint_SetPixel(Xpoint + XDir_Num - 1, Ypoint + YDir_Num - 1, Color);
- }
- }
- }
-}
-
-/******************************************************************************
-function: Draw a line of arbitrary slope
-parameter:
- Xstart :Starting Xpoint point coordinates
- Ystart :Starting Xpoint point coordinates
- Xend :End point Xpoint coordinate
- Yend :End point Ypoint coordinate
- Color :The color of the line segment
-******************************************************************************/
-void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,
- UWORD Color, LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel)
-{
- if (Xstart > Paint.Width || Ystart > Paint.Height ||
- Xend > Paint.Width || Yend > Paint.Height) {
- Debug("Paint_DrawLine Input exceeds the normal display range\r\n");
- return;
- }
-
- UWORD Xpoint = Xstart;
- UWORD Ypoint = Ystart;
- int dx = (int)Xend - (int)Xstart >= 0 ? Xend - Xstart : Xstart - Xend;
- int dy = (int)Yend - (int)Ystart <= 0 ? Yend - Ystart : Ystart - Yend;
-
- // Increment direction, 1 is positive, -1 is counter;
- int XAddway = Xstart < Xend ? 1 : -1;
- int YAddway = Ystart < Yend ? 1 : -1;
-
- //Cumulative error
- int Esp = dx + dy;
- char Dotted_Len = 0;
-
- for (;;) {
- Dotted_Len++;
- //Painted dotted line, 2 point is really virtual
- if (Line_Style == LINE_STYLE_DOTTED && Dotted_Len % 3 == 0) {
- //Debug("LINE_DOTTED\r\n");
- Paint_DrawPoint(Xpoint, Ypoint, IMAGE_BACKGROUND, Dot_Pixel, DOT_STYLE_DFT);
- Dotted_Len = 0;
- } else {
- Paint_DrawPoint(Xpoint, Ypoint, Color, Dot_Pixel, DOT_STYLE_DFT);
- }
- if (2 * Esp >= dy) {
- if (Xpoint == Xend)
- break;
- Esp += dy;
- Xpoint += XAddway;
- }
- if (2 * Esp <= dx) {
- if (Ypoint == Yend)
- break;
- Esp += dx;
- Ypoint += YAddway;
- }
- }
-}
-
-/******************************************************************************
-function: Draw a rectangle
-parameter:
- Xstart :Rectangular Starting Xpoint point coordinates
- Ystart :Rectangular Starting Xpoint point coordinates
- Xend :Rectangular End point Xpoint coordinate
- Yend :Rectangular End point Ypoint coordinate
- Color :The color of the Rectangular segment
- Filled : Whether it is filled--- 1 solid 0:empty
-******************************************************************************/
-void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,
- UWORD Color, DRAW_FILL Filled, DOT_PIXEL Dot_Pixel)
-{
- if (Xstart > Paint.Width || Ystart > Paint.Height ||
- Xend > Paint.Width || Yend > Paint.Height) {
- Debug("Input exceeds the normal display range\r\n");
- return;
- }
-
- if (Filled ) {
- UWORD Ypoint;
- for(Ypoint = Ystart; Ypoint < Yend; Ypoint++) {
- Paint_DrawLine(Xstart, Ypoint, Xend, Ypoint, Color , LINE_STYLE_SOLID, Dot_Pixel);
- }
- } else {
- Paint_DrawLine(Xstart, Ystart, Xend, Ystart, Color , LINE_STYLE_SOLID, Dot_Pixel);
- Paint_DrawLine(Xstart, Ystart, Xstart, Yend, Color , LINE_STYLE_SOLID, Dot_Pixel);
- Paint_DrawLine(Xend, Yend, Xend, Ystart, Color , LINE_STYLE_SOLID, Dot_Pixel);
- Paint_DrawLine(Xend, Yend, Xstart, Yend, Color , LINE_STYLE_SOLID, Dot_Pixel);
- }
-}
-
-/******************************************************************************
-function: Use the 8-point method to draw a circle of the
- specified size at the specified position->
-parameter:
- X_Center :Center X coordinate
- Y_Center :Center Y coordinate
- Radius :circle Radius
- Color :The color of the :circle segment
- Filled : Whether it is filled: 1 filling 0:Do not
-******************************************************************************/
-void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius,
- UWORD Color, DRAW_FILL Draw_Fill , DOT_PIXEL Dot_Pixel)
-{
- if (X_Center > Paint.Width || Y_Center >= Paint.Height) {
- Debug("Paint_DrawCircle Input exceeds the normal display range\r\n");
- return;
- }
-
- //Draw a circle from(0, R) as a starting point
- int16_t XCurrent, YCurrent;
- XCurrent = 0;
- YCurrent = Radius;
-
- //Cumulative error,judge the next point of the logo
- int16_t Esp = 3 - (Radius << 1 );
-
- int16_t sCountY;
- if (Draw_Fill == DRAW_FILL_FULL) {
- while (XCurrent <= YCurrent ) { //Realistic circles
- for (sCountY = XCurrent; sCountY <= YCurrent; sCountY ++ ) {
- Paint_DrawPoint(X_Center + XCurrent, Y_Center + sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//1
- Paint_DrawPoint(X_Center - XCurrent, Y_Center + sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//2
- Paint_DrawPoint(X_Center - sCountY, Y_Center + XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//3
- Paint_DrawPoint(X_Center - sCountY, Y_Center - XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//4
- Paint_DrawPoint(X_Center - XCurrent, Y_Center - sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//5
- Paint_DrawPoint(X_Center + XCurrent, Y_Center - sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//6
- Paint_DrawPoint(X_Center + sCountY, Y_Center - XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//7
- Paint_DrawPoint(X_Center + sCountY, Y_Center + XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- }
- if (Esp < 0 )
- Esp += 4 * XCurrent + 6;
- else {
- Esp += 10 + 4 * (XCurrent - YCurrent );
- YCurrent --;
- }
- XCurrent ++;
- }
- } else { //Draw a hollow circle
- while (XCurrent <= YCurrent ) {
- Paint_DrawPoint(X_Center + XCurrent, Y_Center + YCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//1
- Paint_DrawPoint(X_Center - XCurrent, Y_Center + YCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//2
- Paint_DrawPoint(X_Center - YCurrent, Y_Center + XCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//3
- Paint_DrawPoint(X_Center - YCurrent, Y_Center - XCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//4
- Paint_DrawPoint(X_Center - XCurrent, Y_Center - YCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//5
- Paint_DrawPoint(X_Center + XCurrent, Y_Center - YCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//6
- Paint_DrawPoint(X_Center + YCurrent, Y_Center - XCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//7
- Paint_DrawPoint(X_Center + YCurrent, Y_Center + XCurrent, Color, Dot_Pixel, DOT_STYLE_DFT);//0
-
- if (Esp < 0 )
- Esp += 4 * XCurrent + 6;
- else {
- Esp += 10 + 4 * (XCurrent - YCurrent );
- YCurrent --;
- }
- XCurrent ++;
- }
- }
-}
-
-/******************************************************************************
-function: Show English characters
-parameter:
- Xpoint :X coordinate
- Ypoint :Y coordinate
- Acsii_Char :To display the English characters
- Font :A structure pointer that displays a character size
- Color_Background : Select the background color of the English character
- Color_Foreground : Select the foreground color of the English character
-******************************************************************************/
-void Paint_DrawChar(UWORD Xpoint, UWORD Ypoint, const char Acsii_Char,
- sFONT* Font, UWORD Color_Background, UWORD Color_Foreground)
-{
- UWORD Page, Column;
-
- if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
- Debug("Paint_DrawChar Input exceeds the normal display range\r\n");
- return;
- }
-
- uint32_t Char_Offset = (Acsii_Char - ' ') * Font->Height * (Font->Width / 8 + (Font->Width % 8 ? 1 : 0));
- const unsigned char *ptr = &Font->table[Char_Offset];
-
- for (Page = 0; Page < Font->Height; Page ++ ) {
- for (Column = 0; Column < Font->Width; Column ++ ) {
-
- //To determine whether the font background color and screen background color is consistent
- if (FONT_BACKGROUND == Color_Background) { //this process is to speed up the scan
- if (*ptr & (0x80 >> (Column % 8)))
- Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground);
- // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- } else {
- if (*ptr & (0x80 >> (Column % 8))) {
- Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground);
- // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- } else {
- Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background);
- // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- }
- }
- //One pixel is 8 bits
- if (Column % 8 == 7)
- ptr++;
- }// Write a line
- if (Font->Width % 8 != 0)
- ptr++;
- }// Write all
-}
-
-/******************************************************************************
-function: Display the string
-parameter:
- Xstart :X coordinate
- Ystart :Y coordinate
- pString :The first address of the English string to be displayed
- Font :A structure pointer that displays a character size
- Color_Background : Select the background color of the English character
- Color_Foreground : Select the foreground color of the English character
-******************************************************************************/
-void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString,
- sFONT* Font, UWORD Color_Background, UWORD Color_Foreground )
-{
- UWORD Xpoint = Xstart;
- UWORD Ypoint = Ystart;
-
- if (Xstart > Paint.Width || Ystart > Paint.Height) {
- Debug("Paint_DrawString_EN Input exceeds the normal display range\r\n");
- return;
- }
-
- while (* pString != '\0') {
- //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character
- if ((Xpoint + Font->Width ) > Paint.Width ) {
- Xpoint = Xstart;
- Ypoint += Font->Height;
- }
-
- // If the Y direction is full, reposition to(Xstart, Ystart)
- if ((Ypoint + Font->Height ) > Paint.Height ) {
- Xpoint = Xstart;
- Ypoint = Ystart;
- }
- Paint_DrawChar(Xpoint, Ypoint, * pString, Font, Color_Background, Color_Foreground);
-
- //The next character of the address
- pString ++;
-
- //The next word of the abscissa increases the font of the broadband
- Xpoint += Font->Width;
- }
-}
-
-
-/******************************************************************************
-function: Display the string
-parameter:
- Xstart :X coordinate
- Ystart :Y coordinate
- pString :The first address of the Chinese string and English
- string to be displayed
- Font :A structure pointer that displays a character size
- Color_Background : Select the background color of the English character
- Color_Foreground : Select the foreground color of the English character
-******************************************************************************/
-void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Background, UWORD Color_Foreground)
-{
- const char* p_text = pString;
- int x = Xstart, y = Ystart;
- int i, j,Num;
-
- /* Send the string character by character on EPD */
- while (*p_text != 0) {
- if(*p_text <= 0x7F) { //ASCII < 126
- for(Num = 0; Num < font->size; Num++) {
- if(*p_text== font->table[Num].index[0]) {
- const char* ptr = &font->table[Num].matrix[0];
-
- for (j = 0; j < font->Height; j++) {
- for (i = 0; i < font->Width; i++) {
- if (FONT_BACKGROUND == Color_Background) { //this process is to speed up the scan
- if (*ptr & (0x80 >> (i % 8))) {
- Paint_SetPixel(x + i, y + j, Color_Foreground);
- // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- }
- } else {
- if (*ptr & (0x80 >> (i % 8))) {
- Paint_SetPixel(x + i, y + j, Color_Foreground);
- // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- } else {
- Paint_SetPixel(x + i, y + j, Color_Background);
- // Paint_DrawPoint(x + i, y + j, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- }
- }
- if (i % 8 == 7) {
- ptr++;
- }
- }
- if (font->Width % 8 != 0) {
- ptr++;
- }
- }
- break;
- }
- }
- /* Point on the next character */
- p_text += 1;
- /* Decrement the column position by 16 */
- x += font->ASCII_Width;
- } else { //Chinese
- for(Num = 0; Num < font->size; Num++) {
- if((*p_text== font->table[Num].index[0]) && (*(p_text+1) == font->table[Num].index[1])) {
- const char* ptr = &font->table[Num].matrix[0];
-
- for (j = 0; j < font->Height; j++) {
- for (i = 0; i < font->Width; i++) {
- if (FONT_BACKGROUND == Color_Background) { //this process is to speed up the scan
- if (*ptr & (0x80 >> (i % 8))) {
- Paint_SetPixel(x + i, y + j, Color_Foreground);
- // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- }
- } else {
- if (*ptr & (0x80 >> (i % 8))) {
- Paint_SetPixel(x + i, y + j, Color_Foreground);
- // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- } else {
- Paint_SetPixel(x + i, y + j, Color_Background);
- // Paint_DrawPoint(x + i, y + j, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
- }
- }
- if (i % 8 == 7) {
- ptr++;
- }
- }
- if (font->Width % 8 != 0) {
- ptr++;
- }
- }
- break;
- }
- }
- /* Point on the next character */
- p_text += 2;
- /* Decrement the column position by 16 */
- x += font->Width;
- }
- }
-}
-
-/******************************************************************************
-function: Display nummber
-parameter:
- Xstart :X coordinate
- Ystart : Y coordinate
- Nummber : The number displayed
- Font :A structure pointer that displays a character size
- Color_Background : Select the background color of the English character
- Color_Foreground : Select the foreground color of the English character
-******************************************************************************/
-#define ARRAY_LEN 255
-void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber,
- sFONT* Font, UWORD Color_Background, UWORD Color_Foreground )
-{
-
- int16_t Num_Bit = 0, Str_Bit = 0;
- uint8_t Str_Array[ARRAY_LEN] = {0}, Num_Array[ARRAY_LEN] = {0};
- uint8_t *pStr = Str_Array;
-
- if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
- Debug("Paint_DisNum Input exceeds the normal display range\r\n");
- return;
- }
-
- //Converts a number to a string
- while (Nummber) {
- Num_Array[Num_Bit] = Nummber % 10 + '0';
- Num_Bit++;
- Nummber /= 10;
- }
-
- //The string is inverted
- while (Num_Bit > 0) {
- Str_Array[Str_Bit] = Num_Array[Num_Bit - 1];
- Str_Bit ++;
- Num_Bit --;
- }
-
- //show
- Paint_DrawString_EN(Xpoint, Ypoint, (const char*)pStr, Font, Color_Background, Color_Foreground);
-}
-
-/******************************************************************************
-function: Display time
-parameter:
- Xstart :X coordinate
- Ystart : Y coordinate
- pTime : Time-related structures
- Font :A structure pointer that displays a character size
- Color : Select the background color of the English character
-******************************************************************************/
-void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font,
- UWORD Color_Background, UWORD Color_Foreground)
-{
- uint8_t value[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
-
- UWORD Dx = Font->Width;
-
- //Write data into the cache
- Paint_DrawChar(Xstart , Ystart, value[pTime->Hour / 10], Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx , Ystart, value[pTime->Hour % 10], Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx + Dx / 4 + Dx / 2 , Ystart, ':' , Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx * 2 + Dx / 2 , Ystart, value[pTime->Min / 10] , Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx * 3 + Dx / 2 , Ystart, value[pTime->Min % 10] , Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx * 4 + Dx / 2 - Dx / 4, Ystart, ':' , Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx * 5 , Ystart, value[pTime->Sec / 10] , Font, Color_Background, Color_Foreground);
- Paint_DrawChar(Xstart + Dx * 6 , Ystart, value[pTime->Sec % 10] , Font, Color_Background, Color_Foreground);
-}
-
-/******************************************************************************
-function: Display image
-parameter:
- image :Image start address
- xStart : X starting coordinates
- yStart : Y starting coordinates
- xEnd :Image width
- yEnd : Image height
-******************************************************************************/
-void Paint_DrawImage(const unsigned char *image, UWORD xStart, UWORD yStart, UWORD W_Image, UWORD H_Image)
-{
- int i,j;
- for(j = 0; j < H_Image; j++){
- for(i = 0; i < W_Image; i++){
- if(xStart+i < LCD_WIDTH && yStart+j < LCD_HEIGHT)//Exceeded part does not display
- Paint_SetPixel(xStart + i, yStart + j, (*(image + j*W_Image*2 + i*2+1))<<8 | (*(image + j*W_Image*2 + i*2)));
- //Using arrays is a property of sequential storage, accessing the original array by algorithm
- //j*W_Image*2 Y offset
- //i*2 X offset
- }
- }
-
-}
diff --git a/lib/gfx/GUI_DEV/GUI_Paint.h b/lib/gfx/GUI_DEV/GUI_Paint.h
deleted file mode 100644
index 187c9631..00000000
--- a/lib/gfx/GUI_DEV/GUI_Paint.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*****************************************************************************
-* | File : GUI_Paint.h
-* | Author : Waveshare team
-* | Function : Achieve drawing: draw points, lines, boxes, circles and
-* their size, solid dotted line, solid rectangle hollow
-* rectangle, solid circle hollow circle.
-* | Info :
-* Achieve display characters: Display a single character, string, number
-* Achieve time display: adaptive size display time minutes and seconds
-*----------------
-* | This version: V2.0
-* | Date : 2018-11-15
-* | Info :
-* 1.add: Paint_NewImage()
-* Create an image's properties
-* 2.add: Paint_SelectImage()
-* Select the picture to be drawn
-* 3.add: Paint_SetRotate()
-* Set the direction of the cache
-* 4.add: Paint_RotateImage()
-* Can flip the picture, Support 0-360 degrees,
-* but only 90.180.270 rotation is better
-* 4.add: Paint_SetMirroring()
-* Can Mirroring the picture, horizontal, vertical, origin
-* 5.add: Paint_DrawString_CN()
-* Can display Chinese(GB1312)
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documnetation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is
-* furished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in
-* all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-* THE SOFTWARE.
-*
-******************************************************************************/
-#ifndef __GUI_PAINT_H
-#define __GUI_PAINT_H
-
-#include "DEV_Config.h"
-#include "LCD_Driver.h"
-#include "fonts.h"
-#include "Debug.h"
-
-/**
- * Image attributes
-**/
-typedef struct {
- UBYTE *Image;
- UWORD Width;
- UWORD Height;
- UWORD WidthMemory;
- UWORD HeightMemory;
- UWORD Color;
- UWORD Rotate;
- UWORD Mirror;
- UWORD WidthByte;
- UWORD HeightByte;
-} PAINT;
-extern volatile PAINT Paint;
-
-/**
- * Display rotate
-**/
-#define ROTATE_0 0
-#define ROTATE_90 90
-#define ROTATE_180 180
-#define ROTATE_270 270
-
-/**
- * Display Flip
-**/
-typedef enum {
- MIRROR_NONE = 0x00,
- MIRROR_HORIZONTAL = 0x01,
- MIRROR_VERTICAL = 0x02,
- MIRROR_ORIGIN = 0x03,
-} MIRROR_IMAGE;
-#define MIRROR_IMAGE_DFT MIRROR_NONE
-
-/**
- * image color
-**/
-
-#define WHITE 0xFFFF
-#define BLACK 0x0000
-#define BLUE 0x001F
-#define BRED 0XF81F
-#define GRED 0XFFE0
-#define GBLUE 0X07FF
-#define RED 0xF800
-#define MAGENTA 0xF81F
-#define GREEN 0x07E0
-#define CYAN 0x7FFF
-#define YELLOW 0xFFE0
-#define BROWN 0XBC40
-#define BRRED 0XFC07
-#define GRAY 0X8430
-#define DARKBLUE 0X01CF
-#define LIGHTBLUE 0X7D7C
-#define GRAYBLUE 0X5458
-#define LIGHTGREEN 0X841F
-#define LGRAY 0XC618
-#define LGRAYBLUE 0XA651
-#define LBBLUE 0X2B12
-
-
-#define IMAGE_BACKGROUND WHITE
-#define FONT_FOREGROUND BLACK
-#define FONT_BACKGROUND WHITE
-
-/**
- * The size of the point
-**/
-typedef enum {
- DOT_PIXEL_1X1 = 1, // 1 x 1
- DOT_PIXEL_2X2 , // 2 X 2
- DOT_PIXEL_3X3 , // 3 X 3
- DOT_PIXEL_4X4 , // 4 X 4
- DOT_PIXEL_5X5 , // 5 X 5
- DOT_PIXEL_6X6 , // 6 X 6
- DOT_PIXEL_7X7 , // 7 X 7
- DOT_PIXEL_8X8 , // 8 X 8
-} DOT_PIXEL;
-#define DOT_PIXEL_DFT DOT_PIXEL_1X1 //Default dot pilex
-
-/**
- * Point size fill style
-**/
-typedef enum {
- DOT_FILL_AROUND = 1, // dot pixel 1 x 1
- DOT_FILL_RIGHTUP , // dot pixel 2 X 2
-} DOT_STYLE;
-#define DOT_STYLE_DFT DOT_FILL_AROUND //Default dot pilex
-
-/**
- * Line style, solid or dashed
-**/
-typedef enum {
- LINE_STYLE_SOLID = 0,
- LINE_STYLE_DOTTED,
-} LINE_STYLE;
-
-/**
- * Whether the graphic is filled
-**/
-typedef enum {
- DRAW_FILL_EMPTY = 0,
- DRAW_FILL_FULL,
-} DRAW_FILL;
-
-/**
- * Custom structure of a time attribute
-**/
-typedef struct {
- UWORD Year; //0000
- UBYTE Month; //1 - 12
- UBYTE Day; //1 - 30
- UBYTE Hour; //0 - 23
- UBYTE Min; //0 - 59
- UBYTE Sec; //0 - 59
-} PAINT_TIME;
-extern PAINT_TIME sPaint_time;
-
-//init and Clear
-void Paint_NewImage(UWORD Width, UWORD Height, UWORD Rotate, UWORD Color);
-void Paint_SelectImage(UBYTE *image);
-void Paint_SetRotate(UWORD Rotate);
-void Paint_SetMirroring(UBYTE mirror);
-void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color);
-
-void Paint_Clear(UWORD Color);
-void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color);
-
-//Drawing
-void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_FillWay);
-void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel);
-void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DRAW_FILL Filled , DOT_PIXEL Dot_Pixel);
-void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DRAW_FILL Draw_Fill , DOT_PIXEL Dot_Pixel);
-
-//Display string
-void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Acsii_Char, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground);
-void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground);
-void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Background, UWORD Color_Foreground);
-void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground);
-void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground);
-
-//pic
-void Paint_DrawImage(const unsigned char *image,UWORD Startx, UWORD Starty,UWORD Endx, UWORD Endy);
-
-
-#endif
-
-
-
-
-
diff --git a/lib/gfx/LCD/LCD_Driver.c b/lib/gfx/LCD/LCD_Driver.c
index af5d50e3..481d6929 100644
--- a/lib/gfx/LCD/LCD_Driver.c
+++ b/lib/gfx/LCD/LCD_Driver.c
@@ -28,6 +28,8 @@
#
******************************************************************************/
#include "LCD_Driver.h"
+#include "framebuffer.h"
+
static uint8_t screen[LCD_HEIGHT][LCD_WIDTH][2];
/*******************************************************************************
@@ -312,10 +314,45 @@ void LCD_Set(uint8_t *data, int len)
uint8_t *LCD_Framebuffer(void)
{
- return (uint8_t*)screen;
+ return (uint8_t *)screen;
}
void LCD_Update(void)
{
LCD_Set((uint8_t *)screen, sizeof(screen));
}
+
+static Color
+lcd_fb_encode_color_rgb(struct framebuffer *fb, uint8_t r, uint8_t g, uint8_t b)
+{
+ r >>= (8 - 5);
+ g >>= (8 - 6);
+ b >>= (8 - 5);
+
+ // RGB565
+ Color o = 0;
+ o |= (r << 11);
+ o |= (g << 5);
+ o |= b;
+ return o;
+}
+
+static void lcd_fb_update(struct framebuffer *fb)
+{
+ LCD_Update();
+}
+
+static struct framebuffer framebuffer = { .data = screen,
+ .width = LCD_WIDTH,
+ .height = LCD_HEIGHT,
+ .stride = LCD_WIDTH * LCD_HEIGHT * 2,
+ .orientation = FB_O_180,
+
+ .encode_color_rgb =
+ lcd_fb_encode_color_rgb,
+ .update = lcd_fb_update };
+
+struct framebuffer *LCD_framebuffer(void)
+{
+ return &framebuffer;
+}
diff --git a/lib/gfx/LCD/LCD_Driver.h b/lib/gfx/LCD/LCD_Driver.h
index 597956b2..49358115 100644
--- a/lib/gfx/LCD/LCD_Driver.h
+++ b/lib/gfx/LCD/LCD_Driver.h
@@ -31,6 +31,7 @@
#define __LCD_DRIVER_H
#include "DEV_Config.h"
+#include "framebuffer.h"
#define LCD_WIDTH 160 //LCD width
#define LCD_HEIGHT 80 //LCD height
@@ -52,4 +53,6 @@ uint8_t *LCD_Framebuffer(void);
void LCD_Set(uint8_t *data, int len);
void LCD_Update(void);
+struct framebuffer *LCD_framebuffer(void);
+
#endif
diff --git a/lib/gfx/framebuffer.c b/lib/gfx/framebuffer.c
new file mode 100644
index 00000000..672e956a
--- /dev/null
+++ b/lib/gfx/framebuffer.c
@@ -0,0 +1,101 @@
+#include "framebuffer.h"
+
+void fb_clear_to_color(struct framebuffer *fb, Color c)
+{
+ for (int y = 0; y < fb->height; y++) {
+ for (int x = 0; x < fb->width; x++)
+ fb_setpixel(fb, x, y, c);
+ }
+}
+
+void fb_clear(struct framebuffer *fb)
+{
+ Color c = fb->encode_color_rgb(fb, 0, 0, 0);
+ fb_clear_to_color(fb, c);
+}
+
+Color fb_encode_color_rgb(struct framebuffer *fb, int r, int g, int b)
+{
+ return fb->encode_color_rgb(fb, r, g, b);
+}
+
+Color fb_encode_color_rgb_f(struct framebuffer *fb, float r, float g, float b)
+{
+ float r8 = r > 1.0f ? 1.0f : (uint8_t)(r * 255.0f);
+ float g8 = g > 1.0f ? 1.0f : (uint8_t)(g * 255.0f);
+ float b8 = b > 1.0f ? 1.0f : (uint8_t)(b * 255.0f);
+
+ r8 = r8 < .0f ? .0f : r8;
+ g8 = g8 < .0f ? .0f : g8;
+ b8 = b8 < .0f ? .0f : b8;
+
+ return fb->encode_color_rgb(fb, r8, g8, b8);
+}
+
+void fb_copy_raw(struct framebuffer *fb, const void *data, size_t size)
+{
+ size_t to_copy = size < fb->stride ? size : fb->stride;
+ memcpy(fb->data, data, to_copy);
+}
+
+void fb_update(struct framebuffer *fb)
+{
+ fb->update(fb);
+}
+
+size_t fb_bytes_per_pixel(const struct framebuffer *fb)
+{
+ const int pixels = fb->height * fb->width;
+ return fb->stride / pixels;
+}
+
+void *fb_pixel(struct framebuffer *fb, int x, int y)
+{
+ int xo;
+ int yo;
+
+ switch (fb->orientation) {
+ case FB_O_0:
+ xo = x;
+ yo = y;
+ break;
+ case FB_O_90:
+ xo = fb->width - y - 1;
+ yo = x;
+ break;
+ case FB_O_180:
+ xo = fb->width - x - 1;
+ yo = fb->height - y - 1;
+ break;
+ case FB_O_270:
+ xo = y;
+ yo = fb->height - x - 1;
+ break;
+ default:
+ return NULL;
+ }
+
+ if (xo < 0 || yo < 0)
+ return NULL;
+ if (xo >= fb->width || yo >= fb->height)
+ return NULL;
+
+ const size_t bpp = fb_bytes_per_pixel(fb);
+ return (void *)(fb->data) + yo * fb->width * bpp + xo * bpp;
+}
+
+void fb_setpixel(struct framebuffer *fb, int x, int y, Color c)
+{
+ uint8_t *pixel = fb_pixel(fb, x, y);
+ if (pixel == NULL)
+ return;
+
+ const uint8_t *color = (const uint8_t *)(&c);
+ const size_t bpp = fb_bytes_per_pixel(fb);
+ switch (bpp) {
+ default:
+ case 2:
+ pixel[1] = color[0];
+ pixel[0] = color[1];
+ }
+}
diff --git a/lib/gfx/framebuffer.h b/lib/gfx/framebuffer.h
new file mode 100644
index 00000000..e2358c73
--- /dev/null
+++ b/lib/gfx/framebuffer.h
@@ -0,0 +1,39 @@
+#ifndef FRAMEBUFFER_H
+#define FRAMEBUFFER_H
+#include <stdint.h>
+#include <string.h>
+
+typedef unsigned int Color;
+
+enum orientation {
+ FB_O_0,
+ FB_O_90,
+ FB_O_180,
+ FB_O_270,
+};
+
+struct framebuffer {
+ void *data;
+ size_t width;
+ size_t height;
+ size_t stride;
+ int orientation;
+
+ Color (*encode_color_rgb)(struct framebuffer *fb, uint8_t r, uint8_t g,
+ uint8_t b);
+ void (*update)(struct framebuffer *fb);
+};
+
+size_t fb_bytes_per_pixel(const struct framebuffer *fb);
+void *fb_pixel(struct framebuffer *fb, int x, int y);
+void fb_setpixel(struct framebuffer *fb, int x, int y, Color c);
+void fb_clear_to_color(struct framebuffer *fb, Color c);
+void fb_clear(struct framebuffer *fb);
+Color fb_encode_color_rgb(struct framebuffer *fb, int r, int g, int b);
+Color fb_encode_color_rgb_f(struct framebuffer *fb, float r, float g,
+ float b);
+void fb_copy_raw(struct framebuffer *fb, const void *data,
+ size_t size);
+void fb_update(struct framebuffer *fb);
+
+#endif
diff --git a/lib/gfx/gfx.c b/lib/gfx/gfx.c
new file mode 100644
index 00000000..4bc9f35d
--- /dev/null
+++ b/lib/gfx/gfx.c
@@ -0,0 +1,254 @@
+#include "gfx.h"
+#include "framebuffer.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+
+const struct gfx_color_rgb gfx_colors_rgb[COLORS] = {
+ { 255, 255, 255 }, /* WHITE */
+ { 0, 0, 0 }, /* BLACK */
+ { 255, 0, 0 }, /* RED */
+ { 0, 255, 0 }, /* GREEN */
+ { 0, 0, 255 }, /* BLUE */
+ { 255, 255, 0 } /* YELLOW */
+};
+
+void gfx_setpixel(struct gfx_region *r, int x, int y, Color c)
+{
+ if (x < 0 || y < 0)
+ return;
+ if (x >= r->width || y >= r->height)
+ return;
+
+ fb_setpixel(r->fb, r->x + x, r->y + y, c);
+}
+
+struct gfx_region gfx_screen(struct framebuffer *fb)
+{
+ struct gfx_region r = { .fb = fb,
+ .x = 0,
+ .y = 0,
+ .width = fb->width,
+ .height = fb->height };
+ return r;
+}
+
+static inline int letter_bit(sFONT *font, char c, int x, int y)
+{
+ if (x < 0 || y < 0)
+ return 0;
+ if (x >= font->Width || y >= font->Height)
+ return 0;
+ if (c < ' ' || c > '~')
+ return 0;
+
+ size_t bytes_per_row = font->Width / 8 + 1;
+ size_t bytes_per_letter = bytes_per_row * font->Height;
+ int letter = c - ' ';
+ const uint8_t *letter_ptr = font->table + bytes_per_letter * letter;
+ int horz_byte = x / 8;
+ int horz_bit = 7 - x % 8;
+
+ return (*(letter_ptr + y * bytes_per_row + horz_byte) >> horz_bit) & 1;
+}
+
+void gfx_putchar(
+ sFONT *font,
+ struct gfx_region *r,
+ int x,
+ int y,
+ char ch,
+ Color fg,
+ Color bg
+) {
+ for (int yo = 0; yo < font->Height; yo++) {
+ for (int xo = 0; xo < font->Width; xo++) {
+ int lb = letter_bit(font, ch, xo, yo);
+
+ if (fg != bg) {
+ Color c = lb ? fg : bg;
+ gfx_setpixel(r, x + xo, y + yo, c);
+ } else {
+ if (lb) {
+ gfx_setpixel(r, x + xo, y + yo, fg);
+ }
+ }
+ }
+ }
+}
+
+void gfx_puts(
+ sFONT *font,
+ struct gfx_region *r,
+ int x,
+ int y,
+ const char *str,
+ Color fg,
+ Color bg
+) {
+ while (*str) {
+ x += font->Width;
+ if (x >= r->width) {
+ x = 0;
+ y += font->Height;
+ }
+ if (y >= r->height)
+ return;
+ gfx_putchar(font, r, x, y, *str, fg, bg);
+ str++;
+ }
+}
+
+Color gfx_color_rgb_f(struct gfx_region *reg, float r, float g, float b)
+{
+ return fb_encode_color_rgb_f(reg->fb, r, g, b);
+}
+
+Color gfx_color_rgb(struct gfx_region *reg, uint8_t r, uint8_t g, uint8_t b)
+{
+ return fb_encode_color_rgb(reg->fb, r, g, b);
+}
+
+void gfx_update(struct gfx_region *reg)
+{
+ reg->fb->update(reg->fb);
+}
+
+void gfx_clear_to_color(struct gfx_region *reg, Color c)
+{
+ fb_clear_to_color(reg->fb, c);
+}
+
+void gfx_clear(struct gfx_region *reg)
+{
+ gfx_clear_to_color(reg, gfx_color(reg, BLACK));
+}
+
+void gfx_circle(struct gfx_region *reg, int x, int y, int r, int t, Color c)
+{
+ for (int y_ = y - r; y_ <= y + r; y_++) {
+ for (int x_ = x - r; x_ <= x + r; x_++) {
+ int dx = (x_ - x) * (x_ - x);
+ int dy = (y_ - y) * (y_ - y);
+ int outer = (r + t) * (r + t);
+ int inner = r * r;
+ int edge = ((dx + dy) >= inner) && ((dx + dy) <= outer);
+ if (edge)
+ gfx_setpixel(reg, x_, y_, c);
+ }
+ }
+}
+
+void gfx_circle_fill(struct gfx_region *reg, int x, int y, int r, Color c)
+{
+ for (int y_ = y - r; y_ <= y + r; y_++) {
+ for (int x_ = x - r; x_ <= x + r; x_++) {
+ int dx = (x_ - x) * (x_ - x);
+ int dy = (y_ - y) * (y_ - y);
+ int edge = r * r;
+ int fill = (dx + dy) <= edge;
+ if (fill)
+ gfx_setpixel(reg, x_, y_, c);
+ }
+ }
+}
+
+void gfx_rectangle(
+ struct gfx_region *reg, int x, int y, int w, int h, int t, Color c
+) {
+ if (t > 1) {
+ gfx_thick_line(reg, x, y, x + w, y, t, c);
+ gfx_thick_line(reg, x, y + h, x + w, y + h, t, c);
+ gfx_thick_line(reg, x, y, x, y + h, t, c);
+ gfx_thick_line(reg, x + w, y, x + w, y + h, t, c);
+ } else {
+ gfx_line(reg, x, y, x + w, y, c);
+ gfx_line(reg, x, y + h, x + w, y + h, c);
+ gfx_line(reg, x, y, x, y + h, c);
+ gfx_line(reg, x + w, y, x + w, y + h, c);
+ }
+}
+
+void gfx_rectangle_fill(
+ struct gfx_region *reg, int x, int y, int w, int h, Color c
+) {
+ for (int y_ = y; y_ < y + h; y_++) {
+ for (int x_ = x; x_ < x + w; x_++)
+ gfx_setpixel(reg, x_, y_, c);
+ }
+}
+
+void gfx_line(struct gfx_region *reg, int x1, int y1, int x2, int y2, Color c)
+{
+ float dx = x2 - x1;
+ float dy = y2 - y1;
+ float de = fabs(dy / dx);
+ float e = .0f;
+ int y = y1;
+ for (int x = x1; x < x2; x++) {
+ gfx_setpixel(reg, x, y, c);
+ e += de;
+ if (e >= .5f) {
+ y += dy >= .0f ? 1 : -1;
+ e -= 1.0f;
+ }
+ }
+}
+
+void gfx_thick_line(
+ struct gfx_region *reg, int x1, int y1, int x2, int y2, int t, Color c
+) {
+ float dx = x2 - x1;
+ float dy = y2 - y1;
+ float de = fabs(dy / dx);
+ float e = .0f;
+ int y = y1;
+ for (int x = x1; x < x2; x++) {
+ gfx_circle_fill(reg, x, y, t, c);
+ e += de;
+ if (e >= .5f) {
+ y += dy >= .0f ? 1 : -1;
+ e -= 1.0f;
+ }
+ }
+}
+
+Color gfx_color(struct gfx_region *reg, enum gfx_color color)
+{
+ if ((int)(color) >= COLORS)
+ return 0;
+
+ const struct gfx_color_rgb *c = &gfx_colors_rgb[color];
+ return gfx_color_rgb(reg, c->r, c->g, c->b);
+}
+
+void gfx_copy_region_raw(
+ struct gfx_region *reg,
+ int x,
+ int y,
+ int w,
+ int h,
+ size_t bpp,
+ const void *p
+) {
+ for (int y_ = 0; y_ < h; y_++) {
+ for (int x_ = 0; x_ < w; x_++) {
+ Color c;
+
+ switch (bpp) {
+ default:
+ case 2:
+ c = *(const uint16_t *)(p);
+ break;
+ }
+
+ gfx_setpixel(reg, x + x_, y + y_, c);
+ p += bpp;
+ }
+ }
+}
+
+void gfx_copy_raw(struct gfx_region *reg, const void *p, size_t size)
+{
+ fb_copy_raw(reg->fb, p, size);
+}
diff --git a/lib/gfx/gfx.h b/lib/gfx/gfx.h
new file mode 100644
index 00000000..fbfe916e
--- /dev/null
+++ b/lib/gfx/gfx.h
@@ -0,0 +1,59 @@
+#ifndef GFX_H
+#define GFX_H
+#include "fonts.h"
+#include "framebuffer.h"
+#include <stddef.h>
+
+struct gfx_region {
+ struct framebuffer *fb;
+ size_t x;
+ size_t y;
+ size_t width;
+ size_t height;
+};
+
+void gfx_setpixel(struct gfx_region *r, int x, int y, Color c);
+struct gfx_region gfx_screen(struct framebuffer *fb);
+void gfx_putchar(sFONT *font, struct gfx_region *reg, int x, int y, char ch,
+ Color fg, Color bg);
+void gfx_puts(sFONT *font, struct gfx_region *reg, int x, int y,
+ const char *str, Color fg, Color bg);
+Color gfx_color_rgb_f(struct gfx_region *reg, float r, float g, float b);
+Color gfx_color_rgb(struct gfx_region *reg, uint8_t r, uint8_t g, uint8_t b);
+void gfx_clear_to_color(struct gfx_region *reg, Color c);
+void gfx_clear(struct gfx_region *reg);
+void gfx_circle(struct gfx_region *reg, int x, int y, int r, int t, Color c);
+void gfx_circle_fill(struct gfx_region *reg, int x, int y, int r, Color c);
+void gfx_rectangle(struct gfx_region *reg, int x, int y, int w, int h,
+ int t, Color c);
+void gfx_rectangle_fill(struct gfx_region *reg, int x, int y, int w, int h,
+ Color c);
+void gfx_line(struct gfx_region *reg, int x1, int y1, int x2, int y2, Color c);
+void gfx_thick_line(struct gfx_region *reg, int x1, int y1, int x2, int y2,
+ int t, Color c);
+void gfx_update(struct gfx_region *reg);
+
+enum gfx_color {
+ WHITE,
+ BLACK,
+ RED,
+ GREEN,
+ BLUE,
+ YELLOW,
+
+ COLORS
+};
+
+struct gfx_color_rgb {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+} extern const gfx_colors_rgb[COLORS];
+
+Color gfx_color(struct gfx_region *reg, enum gfx_color color);
+
+void gfx_copy_region_raw(struct gfx_region *reg, int x, int y, int w, int h,
+ size_t bpp, const void *p);
+void gfx_copy_raw(struct gfx_region *reg, const void *p, size_t size);
+
+#endif
diff --git a/lib/gfx/meson.build b/lib/gfx/meson.build
index 41b377b1..37b90e43 100644
--- a/lib/gfx/meson.build
+++ b/lib/gfx/meson.build
@@ -7,7 +7,6 @@ includes = include_directories(
sources = files(
'./GUI_DEV/DEV_Config.c',
- './GUI_DEV/GUI_Paint.c',
'./LCD/LCD_Driver.c',
'./Fonts/font8.c',
'./Fonts/font12.c',
@@ -16,6 +15,9 @@ sources = files(
'./Fonts/font20.c',
'./Fonts/font24.c',
'./Fonts/font24CN.c',
+ 'framebuffer.c',
+ 'gfx.c',
+ 'textbuffer.c'
)
lib = static_library(
diff --git a/lib/gfx/textbuffer.c b/lib/gfx/textbuffer.c
new file mode 100644
index 00000000..d2a8a39b
--- /dev/null
+++ b/lib/gfx/textbuffer.c
@@ -0,0 +1,251 @@
+#include "textbuffer.h"
+#include "gfx.h"
+#include <string.h>
+
+void txt_init(struct txt_buffer *txtb, struct gfx_region *reg, sFONT *f)
+{
+ txtb->reg = reg;
+ txtb->font = f;
+ txtb->cursor_column = 0;
+ txtb->cursor_row = 0;
+ txtb->fg_color = gfx_color_rgb_f(reg, 1.0f, 1.0f, 1.0f);
+ txtb->bg_color = gfx_color_rgb_f(reg, .0f, .0f, .0f);
+ txtb->draw_cursor = 1;
+ txtb->auto_update = 1;
+
+ txt_clear(txtb);
+}
+
+static inline size_t width_(struct txt_buffer *tm)
+{
+ return tm->reg->width / tm->font->Width;
+}
+
+static inline size_t height_(struct txt_buffer *tm)
+{
+ return tm->reg->height / tm->font->Height;
+}
+
+size_t txt_width(struct txt_buffer *tm)
+{
+ return width_(tm);
+}
+
+size_t txt_height(struct txt_buffer *tm)
+{
+ return height_(tm);
+}
+
+static void scrollup(struct txt_buffer *tm)
+{
+ const int last_row = height_(tm) - 1;
+ const size_t line_size = width_(tm) * sizeof(struct txt_glyph);
+
+ for (int row = 0; row < last_row; row++)
+ memcpy(&tm->text[row][0], &tm->text[row + 1][0], line_size);
+ for (int col = 0; col < width_(tm); col++) {
+ struct txt_glyph *g = &tm->text[last_row][col];
+ g->ch = ' ';
+ g->fg_color = tm->fg_color;
+ g->bg_color = tm->bg_color;
+ }
+}
+
+static void newline(struct txt_buffer *tm)
+{
+ const int last_row = height_(tm) - 1;
+
+ scrollup(tm);
+ tm->cursor_row = last_row;
+ tm->cursor_column = 0;
+}
+
+static inline void advance_cursor(struct txt_buffer *tm)
+{
+ const int last_row = height_(tm) - 1;
+
+ tm->cursor_column++;
+ if (tm->cursor_column >= width_(tm)) {
+ tm->cursor_column = 0;
+ tm->cursor_row++;
+ if (tm->cursor_row > last_row)
+ newline(tm);
+ }
+}
+
+static void tab(struct txt_buffer *tm)
+{
+ while (tm->cursor_column % 5)
+ txt_putchar(tm, ' ');
+}
+
+static inline struct txt_glyph *getchar_(struct txt_buffer *tm, int x, int y)
+{
+ if (x < 0 || x >= TEXTBUFFER_MAX_WIDTH)
+ return NULL;
+ if (y < 0 || y >= TEXTBUFFER_MAX_HEIGHT)
+ return NULL;
+ return &tm->text[y][x];
+}
+
+void txt_clear(struct txt_buffer *tm)
+{
+ int w = width_(tm);
+ int h = height_(tm);
+ for (int r = 0; r < h; r++) {
+ for (int c = 0; c < w; c++) {
+ struct txt_glyph *g = getchar_(tm, c, r);
+ if (g == NULL)
+ continue;
+
+ g->ch = ' ';
+ g->fg_color = tm->fg_color;
+ g->bg_color = tm->bg_color;
+ }
+ }
+
+ tm->cursor_column = 0;
+ tm->cursor_row = 0;
+
+ if (tm->auto_update)
+ txt_update(tm);
+}
+
+void txt_putchar(struct txt_buffer *tm, char ch)
+{
+ struct txt_glyph *g = getchar_(tm, tm->cursor_column, tm->cursor_row);
+ if (g == NULL)
+ return;
+
+ switch (ch) {
+ case '\n':
+ newline(tm);
+ break;
+ case '\t':
+ tab(tm);
+ break;
+ default:
+ g->ch = ch;
+ g->fg_color = tm->fg_color;
+ g->bg_color = tm->bg_color;
+ advance_cursor(tm);
+ }
+
+ if (tm->auto_update)
+ txt_update(tm);
+}
+
+void txt_puts(struct txt_buffer *tm, const char *str)
+{
+ while (*str) {
+ txt_putchar(tm, *str);
+ str++;
+ }
+}
+
+static inline int cursor_px_column(struct txt_buffer *tm)
+{
+ return tm->font->Width * tm->cursor_column;
+}
+
+static inline int cursor_px_row(struct txt_buffer *tm)
+{
+ return tm->font->Height * tm->cursor_row;
+}
+
+static void draw_cursor_(struct txt_buffer *tm)
+{
+ const int x = cursor_px_column(tm);
+ const int y = cursor_px_row(tm);
+ const int w = tm->font->Width;
+ const int h = tm->font->Height;
+ gfx_rectangle_fill(tm->reg, x, y, w, h, tm->fg_color);
+}
+
+void txt_draw(struct txt_buffer *tm)
+{
+ const int w = width_(tm);
+ const int h = height_(tm);
+ int px_column = 0;
+ int px_row = 0;
+
+ for (int r = 0; r < h; r++) {
+ px_column = 0;
+ for (int c = 0; c < w; c++) {
+ struct txt_glyph *g = getchar_(tm, c, r);
+ if (g == NULL)
+ continue;
+
+ gfx_putchar(
+ tm->font,
+ tm->reg,
+ px_column,
+ px_row,
+ g->ch,
+ g->fg_color,
+ g->bg_color
+ );
+ px_column += tm->font->Width;
+ }
+
+ px_row += tm->font->Height;
+ }
+
+ if (tm->draw_cursor)
+ draw_cursor_(tm);
+}
+
+void txt_set_color_f(
+ struct txt_buffer *tm, enum txt_color sw, float r, float g, float b
+) {
+ Color c = gfx_color_rgb_f(tm->reg, r, g, b);
+
+ switch (c) {
+ case TEXT_FOREGROUND:
+ tm->fg_color = c;
+ break;
+ case TEXT_BACKGROUND:
+ tm->bg_color = c;
+ break;
+ }
+}
+
+void txt_set_color(struct txt_buffer *tm, enum txt_color sw, int r, int g, int b)
+{
+ Color c = gfx_color_rgb(tm->reg, r, g, b);
+
+ switch (c) {
+ case TEXT_FOREGROUND:
+ tm->fg_color = c;
+ break;
+ case TEXT_BACKGROUND:
+ tm->bg_color = c;
+ break;
+ }
+}
+
+void txt_set_cursor(struct txt_buffer *tm, int x, int y, int draw_cursor)
+{
+ tm->draw_cursor = draw_cursor;
+
+ if (x < 0 || x >= width_(tm))
+ return;
+ if (y < 0 || y >= height_(tm))
+ return;
+
+ tm->cursor_column = x;
+ tm->cursor_row = y;
+
+ if (tm->auto_update)
+ txt_update(tm);
+}
+
+void txt_set_transparent(struct txt_buffer *tm)
+{
+ tm->bg_color = tm->fg_color;
+}
+
+void txt_update(struct txt_buffer *tm)
+{
+ gfx_update(tm->reg);
+}
diff --git a/lib/gfx/textbuffer.h b/lib/gfx/textbuffer.h
new file mode 100644
index 00000000..bec52bbe
--- /dev/null
+++ b/lib/gfx/textbuffer.h
@@ -0,0 +1,49 @@
+#ifndef TEXTBUFFER_H
+#define TEXTBUFFER_H
+#include "gfx.h"
+#include "fonts.h"
+#include <stdint.h>
+
+#define TEXTBUFFER_MAX_WIDTH 40
+#define TEXTBUFFER_MAX_HEIGHT 20
+
+struct txt_glyph {
+ char ch;
+ Color fg_color;
+ Color bg_color;
+};
+
+struct txt_buffer {
+ struct gfx_region *reg;
+ sFONT *font;
+ int cursor_column;
+ int cursor_row;
+ Color fg_color;
+ Color bg_color;
+ int draw_cursor;
+ int auto_update;
+
+ struct txt_glyph text[TEXTBUFFER_MAX_HEIGHT][TEXTBUFFER_MAX_WIDTH];
+};
+
+enum txt_color {
+ TEXT_FOREGROUND,
+ TEXT_BACKGROUND
+};
+
+void txt_init(struct txt_buffer *txtb, struct gfx_region *reg, sFONT *f);
+size_t txt_width(struct txt_buffer *tm);
+size_t txt_height(struct txt_buffer *tm);
+void txt_clear(struct txt_buffer *tm);
+void txt_putchar(struct txt_buffer *tm, char ch);
+void txt_puts(struct txt_buffer *tm, const char *str);
+void txt_draw(struct txt_buffer *tm);
+void txt_set_color_f(struct txt_buffer *tm, enum txt_color sw, float r, float g,
+ float b);
+void txt_set_color(struct txt_buffer *tm, enum txt_color sw, int r, int g,
+ int b);
+void txt_set_transparent(struct txt_buffer *tm);
+void txt_set_cursor(struct txt_buffer *tm, int x, int y, int draw_cursor);
+void txt_update(struct txt_buffer *tm);
+
+#endif
--
GitLab