From d2448d151edad03fb2ca2274cb02426f5fb69582 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Sun, 19 May 2024 11:39:07 -0400 Subject: add font loading and rendering to daguerre --- libraries/daguerre/include/daguerre.hpp | 68 ++++++++++++++++++++++++++++++--- libraries/daguerre/source/daguerre.cpp | 45 ++++++++++++++++++++++ 2 files changed, 108 insertions(+), 5 deletions(-) (limited to 'libraries/daguerre') diff --git a/libraries/daguerre/include/daguerre.hpp b/libraries/daguerre/include/daguerre.hpp index 62d10f0..c236cb9 100644 --- a/libraries/daguerre/include/daguerre.hpp +++ b/libraries/daguerre/include/daguerre.hpp @@ -14,6 +14,16 @@ namespace daguerre { uint8_t b; }; + static inline void default_overlay(hilbert_color &dest, const rgb24 &src) { + dest = __euler_encode_color(src.r, src.g, src.b); + } + + static inline void default_overlay(rgb24 &dest, const bool &src) { + dest.r = src ? 255 : 0; + dest.g = src ? 255 : 0; + dest.b = src ? 255 : 0; + } + template class image { @@ -100,7 +110,7 @@ namespace daguerre { //from [from_x, from_x + width) x [from_y, from_y + height). template < class to_color_t, class from_color_t, - void overlay(to_color_t &dest, const from_color_t &src)> + void overlay(to_color_t &dest, const from_color_t &src) = default_overlay> void overlay_region( image &to, unsigned to_x, unsigned to_y, const image &from, unsigned from_x, unsigned from_y, @@ -116,12 +126,60 @@ namespace daguerre { } - static inline void encode(hilbert_color &dest, const rgb24 &src) { - dest = __euler_encode_color(src.r, src.g, src.b); - } - image get_hilbert_framebuffer(); bool try_load_ppm(std::FILE *input, image &into); + static inline bool try_load_ppm(const char *path, image &into) { + std::FILE *f = std::fopen(path, "r"); + if (!f) + return false; + bool success = try_load_ppm(f, into); + std::fclose(f); + return success; + } + + //TODO: unicode + template + class fixed_bitmap_font { + + public: + unsigned width; + unsigned height; + image glyphs[128]; + + template + void overlay_text( + image &target, unsigned x, + unsigned y, const char *text) const { + + while (1) { + uint8_t ch = (uint8_t)*text; + if (ch == 0) + return; + if (ch < 128) { + overlay_region( + target, x, y, glyphs[ch], 0, 0, width, height); + x += width; + } + ++text; + } + + } + + }; + + bool try_load_psf(std::FILE *input, fixed_bitmap_font &into); + + static inline bool try_load_psf( + const char *path, fixed_bitmap_font &into) { + std::FILE *f = std::fopen(path, "r"); + if (!f) + return false; + bool success = try_load_psf(f, into); + std::fclose(f); + return success; + } + } diff --git a/libraries/daguerre/source/daguerre.cpp b/libraries/daguerre/source/daguerre.cpp index 7c13a88..2f7fe4d 100644 --- a/libraries/daguerre/source/daguerre.cpp +++ b/libraries/daguerre/source/daguerre.cpp @@ -26,6 +26,7 @@ namespace daguerre { return n; } + //only supports p6 format bool try_load_ppm(std::FILE *input, image &into) { char header[3]; @@ -62,4 +63,48 @@ namespace daguerre { } + //assumes the font is in psf2 format, and has a unicode table + bool try_load_psf(std::FILE *input, fixed_bitmap_font &into) { + + uint32_t header[8]; + if (std::fread(header, 4, 8, input) != 8) + return false; + + const uint32_t glyphs_start = header[2]; + const uint32_t glyph_count = header[4]; + const uint32_t glyph_length = header[5]; + into.height = header[6]; + into.width = header[7]; + + const uint32_t unicode_start = glyphs_start + glyph_count * glyph_length; + std::fseek(input, unicode_start, SEEK_SET); + + uint32_t indices[128]; + + for (uint32_t index = 0; index < glyph_count; ++index) { + uint8_t ch; + std::fread(&ch, 1, 1, input); + if (ch < 128) + indices[ch] = index; + do + std::fread(&ch, 1, 1, input); + while (ch != 0xff); + } + + for (uint8_t ch = 0; ch < 128; ++ch) { + std::fseek(input, glyphs_start + glyph_length * indices[ch], SEEK_SET); + into.glyphs[ch] = image(into.width, into.height); + for (unsigned h = 0; h < into.height; ++h) + for (unsigned wb = 0; wb < into.width; wb += 8) { + uint8_t byte; + std::fread(&byte, 1, 1, input); + for (unsigned x = 0; x < 8 && wb + x < into.width; ++x) + into.glyphs[ch].set(wb + x, h, (byte >> (7 - x)) & 1); + } + } + + return true; + + } + } -- cgit v1.2.3