diff --git a/bootloader/bootloader-display.c b/bootloader/bootloader-display.c index 1fe0cae0ffee19dcf226db64248af754e3c87ac7..abc8dfc209218c80046e46be7a12d1639f4644ec 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 89d5c07d43bdc8b1e28c15f2366c9bdaeb966e0f..719bb3bba1f6666d8dc8f889b015a9c42e192378 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 1f50acae5cb60a5c199b9864194ffdcd62954e5e..afb0401d2ad0e97666972345d2e120e132f1cc48 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 5cc2c38f0bbb7b733debfec9211e13498b4023fa..16244ec81b1eef71b8c28cc259c86c9ef18ff056 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 9e96aa384c2c4331586ecf1da0dce4ebc6a04139..64b492525405431dbc439dfa8571d99147a95c27 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 5c27950215bd835ce488ba17225ab309b0f0468c..60636833753d48b3812833266f01876297037a1d 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 965d325c56d3d70b239e0c77bf71ac7812928865..2ca6cbdd84f9f3279af06eebccbc282b37f41fe9 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 b797233be16784476f33da9201ecd1cab2b70a32..87fdab3ba7d8bf33eea462ce5b71d0bf1eacbd5e 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 7e3db4667bc2d226a375cfebedb15bf7cbf91ed0..9472d57f0a8b5f363935df3e05d8b03a8a2df615 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 a4fd5ad78571b05b5ed5092371ef45e97a81f65b..888185ed07e856e29d47b9559c59efeeee9e91ca 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 e1d66276646f480cde27c063f162d7bd85dd6138..2756ccb7b1a78a2993ad4b96715ad4d846c77475 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 e4244b58a672eed1706ea4c81e4e268fee4147b8..47f82a37f275babff016ab5b32299b0e2e23a475 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 13cbba25f907ac0056d5dc17d0b7830714f6fc6d..0000000000000000000000000000000000000000 --- 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 187c9631470cef6b9e8e5b4da8450602923571dd..0000000000000000000000000000000000000000 --- 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 af5d50e37f886dc6fa212cdca62b60e4594c6f22..481d6929ffdca96dc4711788621200d9faecd9b9 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 597956b2f7620dce0ab7f9034cc1ccdea953ab83..49358115beea4ac4a7f8ec30b2b827149c6dfdad 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 0000000000000000000000000000000000000000..672e956a3467999a9d8c232acb3510f4711786cb --- /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 0000000000000000000000000000000000000000..e2358c73464e7af26cc287c2348c537e5da15bcd --- /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 0000000000000000000000000000000000000000..4bc9f35da40eb1808df664ce7da0d7d41186d106 --- /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 0000000000000000000000000000000000000000..fbfe916e53133b7a463e044813edd97793bad814 --- /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 41b377b1fbe12469e8411b23f597b2af51f40e5c..37b90e436950b8e2b164dcb0bede57373281d4ce 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 0000000000000000000000000000000000000000..d2a8a39bcbc5dd1deb6d19ebad5a927e95fa31a3 --- /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 0000000000000000000000000000000000000000..bec52bbeaad535dcb749de568236f91e200be929 --- /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