summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlvntky <klevent1903@gmail.com>2024-11-21 19:25:48 +0300
committerlvntky <klevent1903@gmail.com>2024-11-21 19:25:48 +0300
commitc3514b55109e3fb62de3935e9e09516b289b2845 (patch)
tree1d93a297a90b5141022b4b687e6600a5fcb7bed9
parent0fa46770ba044b95dd8c253b7d1e12ca324e1556 (diff)
[feature] some font loading but not works
-rwxr-xr-xexample/empty_examplebin16824 -> 17064 bytes
-rw-r--r--example/empty_example.c63
-rw-r--r--fbgl.h201
3 files changed, 190 insertions, 74 deletions
diff --git a/example/empty_example b/example/empty_example
index 8f1efd7..91358c5 100755
--- a/example/empty_example
+++ b/example/empty_example
Binary files differ
diff --git a/example/empty_example.c b/example/empty_example.c
index 85aa2eb..6eadd5f 100644
--- a/example/empty_example.c
+++ b/example/empty_example.c
@@ -7,27 +7,44 @@
int main()
{
- printf("version %s\n", fbgl_version_info());
- printf("name %s\n", fbgl_name_info());
- fbgl_t buffer;
- if (fbgl_init("/dev/fb0", &buffer) == -1) {
- fprintf(stdout, "error could not oppen fb device");
- return -1;
- }
- fbgl_set_bg(&buffer, 0xFF0000);
-
- for (size_t i = 0; i < 100; ++i) {
- for (size_t j = 0; j < 100; ++j) {
- fbgl_put_pixel(i, j, 0x00FFFF, &buffer);
- }
- }
- int l = 0;
- while (1) {
- if(fbgl_check_esc_key()) {
- fprintf(stdout, "esc pressed", fbgl_check_esc_key());
-
- }
- }
-
- return 0;
+ printf("version %s\n", fbgl_version_info());
+ printf("name %s\n", fbgl_name_info());
+
+ 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, 0xFFFFFF); // Set background color to red
+
+
+
+ // Load the PSF2 font
+ fbgl_psf2_header_t *font = fbgl_load_psf2_font("../asset/font.psf");
+ if (!font) {
+ fprintf(stderr, "Error: failed to load PSF2 font.\n");
+ fbgl_destroy(&buffer);
+ return -1;
+ }
+
+ printf("Loaded PSF2 Font: %d glyphs, %dx%d px per character\n", font->numglyphs, font->width, font->height);
+
+ // Render sample text
+ fbgl_render_text(&buffer, buffer.width, buffer.height, 100, 100, "Hello, framebuffer!", font);
+
+ // Main loop checking for ESC key
+ int l = 0;
+ while (1) {
+ if (fbgl_check_esc_key()) {
+ fprintf(stdout, "ESC pressed\n");
+ break;
+ }
+ }
+
+ // Free the font memory
+ fbgl_free_psf2_font(font);
+
+ fbgl_destroy(&buffer);
+ return 0;
}
diff --git a/fbgl.h b/fbgl.h
index 1057501..c15e0aa 100644
--- a/fbgl.h
+++ b/fbgl.h
@@ -41,6 +41,18 @@ typedef struct fbgl_window {
fbgl_t *fb; // Pointer to the framebuffer context
} fbgl_window_t;
+typedef struct fbgl_psf2_header {
+ uint8_t magic[2]; // Magic number, should be {0x72, 0xB5}
+ uint8_t version; // Version of PSF2 (usually 0)
+ uint8_t header_size; // Size of the header (usually 32 bytes)
+ uint16_t flags; // Flags (usually 0)
+ uint16_t numglyphs; // Number of glyphs (characters)
+ uint16_t bytes_per_glyph; // Number of bytes per glyph (depends on font size)
+ uint16_t height; // Height of each character in pixels
+ uint16_t width; // Width of each character in pixels
+ uint8_t *glyphs; // Pointer to the glyph data
+} fbgl_psf2_header_t;
+
#ifdef FBGL_HIDE_CURSOR
#include <linux/kd.h>
int fbgl_hide_cursor(int fd)
@@ -75,7 +87,7 @@ void fbgl_enable_raw_mode();
void fbgl_disable_raw_mode();
void fbgl_cleanup(int sig);
int fbgl_check_esc_key();
-void fbgl_set_signal_handlers();
+void fbgl_set_signal_handlers();
/*Create and destroy methods*/
int fbgl_init(const char *device, fbgl_t *fb);
@@ -101,6 +113,16 @@ uint32_t *fb_get_data(void);
int fb_get_width(void);
int fb_get_height(void);
+/**
+* PSF2 Font Methods
+*/
+fbgl_psf2_header_t *fbgl_load_psf2_font(const char *font_file);
+void fbgl_render_char(fbgl_t *framebuffer, int fb_width, int fb_height, int x,
+ int y, char ch, fbgl_psf2_header_t *font);
+void fbgl_render_text(fbgl_t *framebuffer, int fb_width, int fb_height, int x,
+ int y, const char *text, fbgl_psf2_header_t *font);
+void fbgl_free_psf2_font(fbgl_psf2_header_t *font);
+
#ifdef FBGL_IMPLEMENTATION
char const *fbgl_name_info(void)
@@ -139,9 +161,9 @@ int fbgl_init(const char *device, fbgl_t *fb)
}
#ifdef FBGL_HIDE_CURSOR
-fbgl_hide_cursor(fb->fd);
- fbgl_set_signal_handlers();
- fbgl_enable_raw_mode();
+ fbgl_hide_cursor(fb->fd);
+ fbgl_set_signal_handlers();
+ fbgl_enable_raw_mode();
#endif //FBGL_HIDE_CURSOR
fb->width = fb->vinfo.xres;
@@ -176,9 +198,9 @@ void fbgl_destroy(fbgl_t *fb)
close(fb->fd);
fb->fd = -1;
- #ifdef FBGL_HIDE_CURSOR
+#ifdef FBGL_HIDE_CURSOR
fbgl_disable_raw_mode();
- #endif // FBGL_HIDE_CURSOR
+#endif // FBGL_HIDE_CURSOR
}
void fbgl_set_bg(fbgl_t *fb, uint32_t color)
@@ -207,76 +229,153 @@ void fbgl_put_pixel(int x, int y, uint32_t color, fbgl_t *fb)
size_t index = y * fb->width + x;
fb->pixels[index] = color;
- }
+}
- void fbgl_enable_raw_mode()
+void fbgl_enable_raw_mode()
{
- struct termios raw;
+ struct termios raw;
- if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) {
- perror("tcgetattr");
- exit(EXIT_FAILURE);
- }
- raw = orig_termios;
- raw.c_lflag &= ~(ECHO | ICANON);
- if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) {
- perror("tcsetattr");
- exit(EXIT_FAILURE);
- }
+ if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) {
+ perror("tcgetattr");
+ exit(EXIT_FAILURE);
+ }
+ raw = orig_termios;
+ raw.c_lflag &= ~(ECHO | ICANON);
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) {
+ perror("tcsetattr");
+ exit(EXIT_FAILURE);
+ }
}
void fbgl_disable_raw_mode()
{
- if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) {
- perror("tcsetattr");
- }
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) {
+ perror("tcsetattr");
+ }
}
void fbgl_cleanup(int sig)
{
- fbgl_disable_raw_mode();
- printf("\033[2J\033[H"); // Clear the terminal screen and move the cursor to top-left
- exit(sig);
+ fbgl_disable_raw_mode();
+ printf("\033[2J\033[H"); // Clear the terminal screen and move the cursor to top-left
+ exit(sig);
}
int fbgl_check_esc_key()
{
- char c;
- struct timeval tv = {0, 0};
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(STDIN_FILENO, &fds);
-
- // Check if there's input available
- if (select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) == -1) {
- perror("select");
- return 0;
+ char c;
+ struct timeval tv = { 0, 0 };
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(STDIN_FILENO, &fds);
+
+ // Check if there's input available
+ if (select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) == -1) {
+ perror("select");
+ return 0;
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &fds)) {
+ if (read(STDIN_FILENO, &c, 1) == -1) {
+ perror("read");
+ return 0;
+ }
+ return c == 27; // ASCII value of the `Esc` key
+ }
+
+ return 0;
+}
+
+void fbgl_set_signal_handlers()
+{
+ struct sigaction sa;
+ sa.sa_handler = fbgl_cleanup;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+
+ if (sigaction(SIGINT, &sa, NULL) == -1 ||
+ sigaction(SIGTERM, &sa, NULL) == -1) {
+ perror("sigaction");
+ exit(EXIT_FAILURE);
+ }
+}
+
+fbgl_psf2_header_t *fbgl_load_psf2_font(const char *font_file)
+{
+ fbgl_psf2_header_t *font = NULL;
+ int fd = open(font_file, O_RDONLY);
+ if (fd == -1) {
+ perror("Error opening font file");
+ return NULL;
+ }
+
+ // Read the font header
+ font = (fbgl_psf2_header_t *)malloc(sizeof(fbgl_psf2_header_t));
+ if (read(fd, font, sizeof(fbgl_psf2_header_t)) !=
+ sizeof(fbgl_psf2_header_t)) {
+ perror("Error reading font header");
+ free(font);
+ close(fd);
+ return NULL;
+ }
+
+ // Check magic number
+ if (font->magic[0] != 0x72 || font->magic[1] != 0xB5) {
+ fprintf(stderr, "Invalid PSF2 font magic number.\n");
+ free(font);
+ close(fd);
+ return NULL;
+ }
+
+ // Read the font glyph data
+ font->glyphs =
+ (uint8_t *)malloc(font->numglyphs * font->bytes_per_glyph);
+ if (read(fd, font->glyphs, font->numglyphs * font->bytes_per_glyph) !=
+ font->numglyphs * font->bytes_per_glyph) {
+ perror("Error reading glyph data");
+ free(font->glyphs);
+ free(font);
+ close(fd);
+ return NULL;
+ }
+
+ close(fd);
+ return font;
}
- if (FD_ISSET(STDIN_FILENO, &fds)) {
- if (read(STDIN_FILENO, &c, 1) == -1) {
- perror("read");
- return 0;
+ void fbgl_render_char(fbgl_t *framebuffer, int fb_width, int fb_height, int x, int y, char ch, fbgl_psf2_header_t *font)
+{
+ if (!framebuffer || !font) return;
+
+ int glyph_idx = (uint8_t)ch; // Get the glyph index for the character
+ if (glyph_idx >= font->numglyphs) return;
+
+ uint8_t *glyph_data = font->glyphs + (glyph_idx * font->bytes_per_glyph);
+ for (int j = 0; j < font->height; ++j) {
+ for (int i = 0; i < font->width; ++i) {
+ if (glyph_data[j] & (1 << (7 - i))) {
+ fbgl_put_pixel(x + i, y + j, 0xFFFFFF, framebuffer);
+ }
}
- return c == 27; // ASCII value of the `Esc` key
}
-
- return 0;
}
-void fbgl_set_signal_handlers()
+void fbgl_render_text(fbgl_t *framebuffer, int fb_width, int fb_height, int x, int y, const char *text, fbgl_psf2_header_t *font)
{
- struct sigaction sa;
- sa.sa_handler = fbgl_cleanup;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGINT, &sa, NULL) == -1 || sigaction(SIGTERM, &sa, NULL) == -1) {
- perror("sigaction");
- exit(EXIT_FAILURE);
+ while (*text) {
+ fbgl_render_char(framebuffer, fb_width, fb_height, x, y, *text, font);
+ x += font->width;
+ ++text;
}
}
+void fbgl_free_psf2_font(fbgl_psf2_header_t *font)
+{
+ if (font) {
+ free(font->glyphs);
+ free(font);
+ }
+}
#endif