Skip to content
Snippets Groups Projects
Commit a26664be authored by Mateusz Zalega's avatar Mateusz Zalega Committed by rahix
Browse files

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: default avatarMateusz Zalega <mateusz@appliedsourcery.com>
parent e87cdd45
Branches
Tags
No related merge requests found
Showing
with 679 additions and 991 deletions
......@@ -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);
}
......@@ -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;
......
#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;
}
......
......@@ -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");
......
......@@ -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();
......
......@@ -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);
......
......@@ -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));
......
......@@ -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);
......
......@@ -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;
}
}
......
......@@ -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) {
......
#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);
}
#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);
......
/*****************************************************************************
* | 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
}
}
}
/*****************************************************************************
* | 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
......@@ -28,6 +28,8 @@
#
******************************************************************************/
#include "LCD_Driver.h"
#include "framebuffer.h"
static uint8_t screen[LCD_HEIGHT][LCD_WIDTH][2];
/*******************************************************************************
......@@ -319,3 +321,38 @@ 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;
}
......@@ -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
#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];
}
}
#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
#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);
}
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment