summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlvntky <klevent1903@gmail.com>2024-11-26 01:46:12 +0300
committerlvntky <klevent1903@gmail.com>2024-11-26 01:46:12 +0300
commit31afd2a2540430139200e50fd9cf546dc93fbfa9 (patch)
treeb7bc83cae8b780a6b62bcfb4311a7beb8dc42cf7
parentd4611757ca2f710b3295847834a47217d19746ef (diff)
[feature] font rendering updated, but not works
-rw-r--r--CMakeLists.txt4
-rw-r--r--asset/font/tamsyn.psfbin0 -> 4421 bytes
-rw-r--r--asset/font/tamzen_font.psfbin0 -> 4970 bytes
-rw-r--r--examples/empty_example.c53
-rw-r--r--examples/text.c28
-rw-r--r--fbgl.h187
6 files changed, 141 insertions, 131 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 02aa36d..10cb5e7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,10 +23,10 @@ function(add_example NAME)
add_dependencies(run-examples "run_${NAME}")
endfunction()
-add_example(empty_example)
add_example(line)
add_example(rectangle)
add_example(red)
add_example(texture)
add_example(raw_mode)
-add_example(framebuf_info) \ No newline at end of file
+add_example(framebuf_info)
+add_example(text)
diff --git a/asset/font/tamsyn.psf b/asset/font/tamsyn.psf
new file mode 100644
index 0000000..0054a2b
--- /dev/null
+++ b/asset/font/tamsyn.psf
Binary files differ
diff --git a/asset/font/tamzen_font.psf b/asset/font/tamzen_font.psf
new file mode 100644
index 0000000..6cfe468
--- /dev/null
+++ b/asset/font/tamzen_font.psf
Binary files differ
diff --git a/examples/empty_example.c b/examples/empty_example.c
deleted file mode 100644
index 352824a..0000000
--- a/examples/empty_example.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#define FBGL_IMPLEMENTATION
-//#define FBGL_HIDE_CURSOR
-#define FBGL_USE_FREETYPE
-#include "fbgl.h"
-
-#include <stdio.h>
-#include <stddef.h>
-
-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 open framebuffer device\n");
- return -1;
- }
- int color = 0x00000000;
-
- FT_Library library = fbgl_freetype_init();
- if (!library) {
- fbgl_destroy(&buffer);
- return -1;
- }
-
- FT_Face face = fbgl_load_font(library, "../asset/font_2.ttf",
- 24); // Adjust path and size
- if (!face) {
- fbgl_freetype_cleanup(library);
- fbgl_destroy(&buffer);
- return -1;
- }
-
- // Render text to framebuffer
- fbgl_render_freetype_text(&buffer, library, face, "Hello, World!", 50,
- 50);
-
- // 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/examples/text.c b/examples/text.c
new file mode 100644
index 0000000..0982a37
--- /dev/null
+++ b/examples/text.c
@@ -0,0 +1,28 @@
+#define FBGL_IMPLEMENTATION
+#include "fbgl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> // for usleep
+#include <stdint.h>
+
+int main(int argc, char *argv[])
+{
+ fbgl_t buf;
+ fbgl_init("/dev/fb0", &buf);
+
+ fbgl_set_bg(&buf, 0x000000);
+
+ fbgl_psf2_font_t *font = fbgl_load_psf2_font(argv[1]);
+
+ size_t framerate = 30 * 30;
+ fbgl_render_psf2_text(&buf, font, "hello fbgl", 100, 100, 0xFFFFFF);
+
+ for(size_t i = 0; i < framerate; i++) {
+ usleep(50000);
+ }
+
+ fbgl_destroy_psf2_font(font);
+ fbgl_destroy(&buf);
+
+ return 0;
+}
diff --git a/fbgl.h b/fbgl.h
index 03dd073..51342f6 100644
--- a/fbgl.h
+++ b/fbgl.h
@@ -15,7 +15,7 @@
//
// Contributors:
// @lvntky
-// @dario-loi
+// @dario-loi
//
// LICENSE
//
@@ -70,18 +70,6 @@ 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;
-
typedef struct fbgl_point {
int32_t x;
int32_t y;
@@ -93,6 +81,18 @@ typedef struct fbgl_tga_texture {
uint32_t *data;
} fbgl_tga_texture_t;
+typedef struct fbgl_psf2_font {
+ uint32_t magic; // Magic number: 0x864ab572
+ uint32_t version; // PSF version (should be 0)
+ uint32_t headersize; // Offset of the bitmaps in the file
+ uint32_t flags; // Font flags
+ uint32_t glyph_count; // Number of glyphs
+ uint32_t glyph_size; // Bytes per glyph
+ uint32_t char_width; // Glyph width in pixels
+ uint32_t char_height; // Glyph height in pixels
+ uint8_t *glyphs; // Pointer to glyph data
+} fbgl_psf2_font_t;
+
typedef struct fbgl_keyboard {
bool keys[FBGL_MAX_KEYS]; // Current state of each key
bool prev_keys[FBGL_MAX_KEYS]; // Previous state of each key
@@ -128,15 +128,6 @@ int fbgl_hide_cursor(int fd)
}
#endif // FBGL_HIDE_CURSOR
-#ifdef FBGL_USE_FREETYPE
-FT_Library fbgl_freetype_init(void);
-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);
-#endif // FBGL_USE_FREETYPE
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -190,6 +181,13 @@ void fbgl_draw_texture(fbgl_t *fb, fbgl_tga_texture_t const *texture, int32_t x,
int32_t y);
/**
+* Text
+*/
+fbgl_psf2_font_t *fbgl_load_psf2_font(const char *path);
+void fbgl_destroy_psf2_font(fbgl_psf2_font_t *font);
+void fbgl_render_psf2_text(fbgl_t *fb, fbgl_psf2_font_t *font, const char *text,
+ int x, int y, uint32_t color);
+/**
* Keyboard
*/
int fbgl_keyboard_init(void);
@@ -380,60 +378,6 @@ void fbgl_set_signal_handlers(void)
}
}
-#ifdef FBGL_USE_FREETYPE
-FT_Library fbgl_freetype_init(void)
-{
- 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);
- }
-}
-
-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, int32_t x, int32_t y)
-{
- while (*text) {
- FT_Load_Char(face, *text, FT_LOAD_RENDER);
- FT_Bitmap bitmap = face->glyph->bitmap;
-
- // Draw the bitmap to framebuffer
- for (uint32_t j = 0; j < bitmap.rows; j++) {
- for (uint32_t 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)
{
@@ -681,6 +625,97 @@ float fbgl_get_fps(void)
return 0.0f; // Avoid division by zero
}
}
+fbgl_psf2_font_t *fbgl_load_psf2_font(const char *path)
+{
+ FILE *file = fopen(path, "rb");
+ if (!file) {
+ perror("Failed to open font file");
+ return NULL;
+ }
+
+ // Read the PSF2 header
+ fbgl_psf2_font_t *font = malloc(sizeof(fbgl_psf2_font_t));
+ if (!font) {
+ perror("Failed to allocate memory for font");
+ fclose(file);
+ return NULL;
+ }
+
+ if (fread(font, sizeof(uint32_t), 8, file) != 8) {
+ perror("Failed to read font header");
+ free(font);
+ fclose(file);
+ return NULL;
+ }
+ /*
+ // Verify the magic number
+ if (font->magic != 0x864ab572) {
+ fprintf(stderr, "Invalid PSF2 magic number\n");
+ free(font);
+ fclose(file);
+ return NULL;
+ }
+ */
+ // Load glyphs
+ font->glyphs = malloc(font->glyph_count * font->glyph_size);
+ if (!font->glyphs) {
+ perror("Failed to allocate memory for glyphs");
+ free(font);
+ fclose(file);
+ return NULL;
+ }
+
+ if (fread(font->glyphs, font->glyph_size, font->glyph_count, file) !=
+ font->glyph_count) {
+ perror("Failed to read glyph data");
+ free(font->glyphs);
+ free(font);
+ fclose(file);
+ return NULL;
+ }
+
+ fclose(file);
+ return font;
+}
+void fbgl_destroy_psf2_font(fbgl_psf2_font_t *font)
+{
+ if (font) {
+ free(font->glyphs);
+ free(font);
+ }
+}
+void fbgl_render_psf2_text(fbgl_t *fb, fbgl_psf2_font_t *font, const char *text,
+ int x, int y, uint32_t color)
+{
+ if (!fb || !font || !text)
+ return;
+
+ int cursor_x = x, cursor_y = y;
+
+ for (const char *c = text; *c; c++) {
+ uint32_t glyph_index = (uint8_t)*c;
+
+ if (glyph_index >= font->glyph_count) {
+ glyph_index =
+ 0; // Use a fallback glyph (e.g., space or undefined)
+ }
+
+ uint8_t *glyph = font->glyphs + glyph_index * font->glyph_size;
+
+ for (uint32_t row = 0; row < font->char_height; row++) {
+ for (uint32_t col = 0; col < font->char_width; col++) {
+ if (glyph[row] &
+ (1 << (font->char_width - 1 - col))) {
+ fbgl_put_pixel(cursor_x + col,
+ cursor_y + row, color,
+ fb);
+ }
+ }
+ }
+
+ cursor_x += font->char_width; // Move to the next character
+ }
+}
#endif // FBGL_IMPLEMENTATION