From 22b5816d5d2ff079091d45cc87b6ca92d66eb482 Mon Sep 17 00:00:00 2001 From: lvntky Date: Fri, 22 Nov 2024 11:59:42 +0300 Subject: [feature] line drawing algorithm --- example/.gitignore | 2 + example/empty_example | Bin 17240 -> 0 bytes example/empty_example.c | 7 ++- example/line.c | 26 +++++++++++ fbgl.h | 122 +++++++++++++++++++++++++++++++++--------------- 5 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 example/.gitignore delete mode 100755 example/empty_example create mode 100644 example/line.c diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..07ac165 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,2 @@ +build/ +core.* diff --git a/example/empty_example b/example/empty_example deleted file mode 100755 index cf2f9a0..0000000 Binary files a/example/empty_example and /dev/null differ diff --git a/example/empty_example.c b/example/empty_example.c index 9ef21b3..aee9232 100644 --- a/example/empty_example.c +++ b/example/empty_example.c @@ -16,8 +16,8 @@ int main() fprintf(stdout, "Error: could not open framebuffer device\n"); return -1; } + int color = 0x00000000; - fbgl_set_bg(&buffer, 0xFFFFFF); // Set background color to red FT_Library library = fbgl_freetype_init(); if (!library) { @@ -38,10 +38,15 @@ int main() // Main loop checking for ESC key int l = 0; while (1) { + if (fbgl_check_esc_key()) { fprintf(stdout, "ESC pressed\n"); break; } + //fbgl_set_bg(&buffer, i++); // Set background color to + for(int i = 0x000000; i <= 0xFFFFFF; i++) { + fbgl_set_bg(&buffer, i); + } } fbgl_destroy(&buffer); return 0; diff --git a/example/line.c b/example/line.c new file mode 100644 index 0000000..9d937cd --- /dev/null +++ b/example/line.c @@ -0,0 +1,26 @@ +#define FBGL_IMPLEMENTATION +#include "../fbgl.h" + +int main(int argc, char *argv[]) +{ + fbgl_t buffer; + if (fbgl_init("/dev/fb0", &buffer) == -1) { + fprintf(stdout, "Error: could not open framebuffer device\n"); + return -1; + } + + fbgl_set_bg(&buffer, 0xFF0000); + fbgl_point_t start = { 0, 0 }; + fbgl_point_t end = { 1020, 1020}; + for(int i = 0; i < 1890; i++) { + start.x = i; + fbgl_draw_line(start, end, 0xFFFFFF, &buffer); + for(int j = 0; j < 10000000; j++){} + } + fbgl_draw_line(start, end, 0x000000, &buffer); + + while (1) { + } + + return 0; +} diff --git a/fbgl.h b/fbgl.h index 9fb6948..bf9e928 100644 --- a/fbgl.h +++ b/fbgl.h @@ -58,6 +58,11 @@ typedef struct fbgl_psf2_header { uint8_t *glyphs; // Pointer to the glyph data } fbgl_psf2_header_t; +typedef struct fbgl_point { + size_t x; + size_t y; +} fbgl_point_t; + #ifdef FBGL_HIDE_CURSOR #include int fbgl_hide_cursor(int fd) @@ -82,8 +87,10 @@ int fbgl_hide_cursor(int fd) #ifdef FBGL_USE_FREETYPE FT_Library fbgl_freetype_init(); void fbgl_freetype_cleanup(FT_Library library); -FT_Face fbgl_load_font(FT_Library library, const char *font_path, int font_size); -void fbgl_render_freetype_text(fbgl_t *fb, FT_Library library, FT_Face face, const char *text, int x, int y); +FT_Face fbgl_load_font(FT_Library library, const char *font_path, + int font_size); +void fbgl_render_freetype_text(fbgl_t *fb, FT_Library library, FT_Face face, + const char *text, int x, int y); #endif //FBGL_USE_FREETYPE #ifdef __cplusplus @@ -110,7 +117,7 @@ void fbgl_destroy(fbgl_t *fb); */ void fbgl_clear(uint32_t color); void fbgl_put_pixel(int x, int y, uint32_t color, fbgl_t *fb); -void fbgl_draw_line(int x0, int y0, int x1, int y1, uint32_t color); +void fbgl_draw_line(fbgl_point_t x, fbgl_point_t y, uint32_t color, fbgl_t* fb); void fbgl_set_bg(); /** @@ -305,50 +312,89 @@ void fbgl_set_signal_handlers() #endif #ifdef FBGL_USE_FREETYPE -FT_Library fbgl_freetype_init() { - FT_Library library; - if (FT_Init_FreeType(&library)) { - fprintf(stderr, "Could not init FreeType Library\n"); - return NULL; - } - return library; +FT_Library fbgl_freetype_init() +{ + FT_Library library; + if (FT_Init_FreeType(&library)) { + fprintf(stderr, "Could not init FreeType Library\n"); + return NULL; + } + return library; } -void fbgl_freetype_cleanup(FT_Library library) { - if (library) { - FT_Done_FreeType(library); - } +void fbgl_freetype_cleanup(FT_Library library) +{ + if (library) { + FT_Done_FreeType(library); + } } -FT_Face fbgl_load_font(FT_Library library, const char *font_path, int font_size) { - FT_Face face; - if (FT_New_Face(library, font_path, 0, &face)) { - fprintf(stderr, "Could not open font: %s\n", font_path); - return NULL; - } - FT_Set_Pixel_Sizes(face, 0, font_size); // Set font size - return face; +FT_Face fbgl_load_font(FT_Library library, const char *font_path, int font_size) +{ + FT_Face face; + if (FT_New_Face(library, font_path, 0, &face)) { + fprintf(stderr, "Could not open font: %s\n", font_path); + return NULL; + } + FT_Set_Pixel_Sizes(face, 0, font_size); // Set font size + return face; } -void fbgl_render_freetype_text(fbgl_t *fb, FT_Library library, FT_Face face, const char *text, int x, int y) { - while (*text) { - FT_Load_Char(face, *text, FT_LOAD_RENDER); - FT_Bitmap bitmap = face->glyph->bitmap; - - // Draw the bitmap to framebuffer - for (int j = 0; j < bitmap.rows; j++) { - for (int i = 0; i < bitmap.width; i++) { - if (bitmap.buffer[j * bitmap.width + i]) { // Check pixel is not empty - fbgl_put_pixel(x + i, y + j, 0xFF0000, fb); // Draw white pixel - } - } - } - x += face->glyph->advance.x >> 6; // Move to the next character position - ++text; - } +void fbgl_render_freetype_text(fbgl_t *fb, FT_Library library, FT_Face face, + const char *text, int x, int y) +{ + while (*text) { + FT_Load_Char(face, *text, FT_LOAD_RENDER); + FT_Bitmap bitmap = face->glyph->bitmap; + + // Draw the bitmap to framebuffer + for (int j = 0; j < bitmap.rows; j++) { + for (int i = 0; i < bitmap.width; i++) { + if (bitmap.buffer[j * bitmap.width + + i]) { // Check pixel is not empty + fbgl_put_pixel(x + i, y + j, 0xFF0000, + fb); // Draw white pixel + } + } + } + x += face->glyph->advance.x >> + 6; // Move to the next character position + ++text; + } } #endif // FBGL_USE_FREETYPE +void fbgl_draw_line(fbgl_point_t x, fbgl_point_t y, uint32_t color, fbgl_t *buffer) +{ + int dx = abs(y.x - x.x); + int dy = abs(y.y - x.y); + + int sx = (x.x < y.x) ? 1 : -1; + int sy = (x.y < y.y) ? 1 : -1; + + int err = dx - dy; + + while (1) { + // Set the pixel at the current position + fbgl_put_pixel(x.x, x.y, color, buffer); + + // If we've reached the end point, break + if (x.x == y.x && x.y == y.y) + break; + + int e2 = 2 * err; + + if (e2 > -dy) { + err -= dy; + x.x += sx; + } + + if (e2 < dx) { + err += dx; + x.y += sy; + } + } +} #ifdef __cplusplus } // extern "C" -- cgit v1.2.3