From 68650da6f53cafdbeae3cc964784ff0619a8d2f8 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Fri, 24 Jul 2026 15:52:04 +0300 Subject: [PATCH] Support margins & offsets in monospace_font, and add a new default 5x7 font --- libs/fonts/include/psemek/fonts/font.hpp | 2 + .../include/psemek/fonts/monospace_font.hpp | 4 +- libs/fonts/source/default_fonts.cpp | 36 +++++++++++++++++- libs/fonts/source/monospace_font.cpp | 9 ++++- libs/gfx/CMakeLists.txt | 1 + libs/gfx/include/psemek/gfx/painter.hpp | 3 +- libs/gfx/resources/font_5x7.png | Bin 0 -> 1236 bytes 7 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 libs/gfx/resources/font_5x7.png diff --git a/libs/fonts/include/psemek/fonts/font.hpp b/libs/fonts/include/psemek/fonts/font.hpp index 1b73bd7c..c3dec36c 100644 --- a/libs/fonts/include/psemek/fonts/font.hpp +++ b/libs/fonts/include/psemek/fonts/font.hpp @@ -85,6 +85,8 @@ namespace psemek::fonts::inline v1 }; std::unique_ptr make_default_monospace_9x12_font(); + std::unique_ptr make_default_monospace_5x7_font(); + std::unique_ptr make_default_9x12_font(); std::unique_ptr make_default_10x12_bold_font(); diff --git a/libs/fonts/include/psemek/fonts/monospace_font.hpp b/libs/fonts/include/psemek/fonts/monospace_font.hpp index 046474ce..8918a23b 100644 --- a/libs/fonts/include/psemek/fonts/monospace_font.hpp +++ b/libs/fonts/include/psemek/fonts/monospace_font.hpp @@ -8,7 +8,7 @@ namespace psemek::fonts struct monospace_font : font { - monospace_font(character_range range, std::string_view name, math::vector size, gfx::texture_2d atlas, std::vector> texcoords); + monospace_font(character_range range, std::string_view name, math::vector size, math::vector offset, math::vector margin, gfx::texture_2d atlas, std::vector> texcoords); font_type type() const override { return font_type::bitmap; } @@ -30,6 +30,8 @@ namespace psemek::fonts character_range range_; std::string_view name_; math::vector size_; + math::vector offset_; + math::vector margin_; gfx::texture_2d atlas_; std::vector> texcoords_; diff --git a/libs/fonts/source/default_fonts.cpp b/libs/fonts/source/default_fonts.cpp index 0ede52fc..7b9246d5 100644 --- a/libs/fonts/source/default_fonts.cpp +++ b/libs/fonts/source/default_fonts.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -45,7 +46,40 @@ namespace psemek::fonts::inline v1 texcoords[c - range.begin] = b; } - return std::make_unique(range, name, size, std::move(atlas), std::move(texcoords)); + // NB: Margin is baked into the glyphs + return std::make_unique(range, name, size, math::vector{0, 0}, math::vector{0, 0}, std::move(atlas), std::move(texcoords)); + } + + std::unique_ptr make_default_monospace_5x7_font() + { + character_range range{32, 128}; + std::string_view name = "default_monospace_5x7"; + math::vector size{5, 9}; + + gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_image(io::memory_istream{gfx::resource::font_5x7_png.data})); + atlas.nearest_filter(); + atlas.clamp(); + gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_G, gl::RED); + gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_B, gl::RED); + gl::TexParameteri(atlas.target, gl::TEXTURE_SWIZZLE_A, gl::RED); + + std::vector> texcoords(range.end - range.begin); + + for (char32_t c = range.begin; c < range.end; ++c) + { + int const row = 16; + int x = (c - range.begin) % row; + int y = (c - range.begin) / row; + + math::box b; + b[0].min = x * 7 + 1; + b[0].max = b[0].min + 5; + b[1].min = y * 11 + 1; + b[1].max = b[1].min + 9; + texcoords[c - range.begin] = b; + } + + return std::make_unique(range, name, size, math::vector{0, -2}, math::vector{1, 1}, std::move(atlas), std::move(texcoords)); } static std::unique_ptr make_default_font(std::string_view name, math::vector const & size, rs::resource const & atlas_resource, rs::resource const & glyphs_resource) diff --git a/libs/fonts/source/monospace_font.cpp b/libs/fonts/source/monospace_font.cpp index 920f7b3e..1fd30ddc 100644 --- a/libs/fonts/source/monospace_font.cpp +++ b/libs/fonts/source/monospace_font.cpp @@ -6,10 +6,12 @@ namespace psemek::fonts { - monospace_font::monospace_font(character_range range, std::string_view name, math::vector size, gfx::texture_2d atlas, std::vector> texcoords) + monospace_font::monospace_font(character_range range, std::string_view name, math::vector size, math::vector offset, math::vector margin, gfx::texture_2d atlas, std::vector> texcoords) : range_{range} , name_{name} , size_{size} + , offset_{offset} + , margin_{margin} , atlas_{std::move(atlas)} , texcoords_{std::move(texcoords)} { @@ -53,7 +55,9 @@ namespace psemek::fonts { char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?'; math::vector const size = math::cast(this->size()) * options.scale; - math::vector const advance = math::pointwise_mult(advance_dir(options.direction), size); + math::vector const margin = math::cast(margin_) * options.scale; + math::vector const offset = math::cast(offset_) * options.scale; + math::vector const advance = math::pointwise_mult(advance_dir(options.direction), size + margin); std::vector result; @@ -70,6 +74,7 @@ namespace psemek::fonts g.character = supports_character(c) ? c : unknown; g.position = {{{pen[0], pen[0] + size[0]}, {pen[1], pen[1] + size[1]}}}; } + g.position += offset; result.push_back(g); pen += advance; } diff --git a/libs/gfx/CMakeLists.txt b/libs/gfx/CMakeLists.txt index 5864a1fd..7d5101e6 100644 --- a/libs/gfx/CMakeLists.txt +++ b/libs/gfx/CMakeLists.txt @@ -12,6 +12,7 @@ if(NOT KHR_PLATFORM_FILE) endif() psemek_add_public_resources(psemek-gfx + resources/font_5x7.png psemek/gfx/resource/font_5x7_png resources/font_9x12.png psemek/gfx/resource/font_9x12_png resources/font_10x12_bold.png psemek/gfx/resource/font_10x12_bold_png ) diff --git a/libs/gfx/include/psemek/gfx/painter.hpp b/libs/gfx/include/psemek/gfx/painter.hpp index d22cbb24..8dd223aa 100644 --- a/libs/gfx/include/psemek/gfx/painter.hpp +++ b/libs/gfx/include/psemek/gfx/painter.hpp @@ -22,6 +22,7 @@ namespace psemek::gfx enum class font { + font_5x7, font_9x12, }; @@ -41,7 +42,7 @@ namespace psemek::gfx struct text_options { - font f = font::font_9x12; + font f = font::font_5x7; math::vector scale = {1.f, 1.f}; x_align x = x_align::center; y_align y = y_align::center; diff --git a/libs/gfx/resources/font_5x7.png b/libs/gfx/resources/font_5x7.png new file mode 100644 index 0000000000000000000000000000000000000000..f480e528de451c07cfa40c9e2b26a2947a618c36 GIT binary patch literal 1236 zcmV;_1S|WAP)z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA1U*SaK~#9!?Ooe)#2^SwGXDQB zZy!3@u~y)4(daJB^r3Mz2twe9$$1>d>qy#`F7$`5*NeU0Yv#Pnt|J*dVO1=-$Is@F+y0YSl~aIph1jQXxwUU+k4~o?$@(SlqZCL z%^aoqMfaolgB9pqy_}NTcIo$)1ts;dTD3H$MnPOZ>OSr$)T-F}8AvhO-m`U~mggfE z9IZ?ge?u)W!XkDMZsem!t=N?l`BdKK3QSr&kx%kd@r3nKKWR)Vh_R#}p0owwb0zep z=CeqVAQyp35u_9bQ{!rsEg?aXd~yqTwBji~FKtIO0gX(Wt@l{XYCONE=31hJB)M25 zDIMjO+x(Afi(IIv*Xi+tj$1~UcaJ&FElaMjogfOgAubeomPX11F$e^`f-TTvd5G(M zI@d!nQtdO4QUZd7Y93qfJkS!|c>!xAVA8tK5z(?Ih_P$}Xxwrp@|z<@naFRfytKfC z(vr4@(yRdo*Kb77q}g*sdDWmhQRtN!N<))e4Krw41k8r;FXe5KyZK1vof%5gminy< zd(AF-dfbIt6*U6MAF*>VqN>cQygJFJ%0|#}ORsZp;#3XG2vo%bl2gg`2)N8s@?oh_ zg`!ZZPP2F2YE`?qPlV^EYeoyjgrz64UgvLR2%_B;?7PlWI4^$viL`5<@D;RcOd0~PbrbBU9r^nM4~j*L08BEt!N8(1i2nF0-*JaMB>-XoFy_Phz_K@WgHQG+-U@Q zqQ-J`nd^t5JD!jq;nR8o*YbuZ%Pu}y7bFox%Jo#GNwqZ6nA$JC zSX^)WWtzted%b0a(QnGP@G;v{X!F?fmq&aXqi#pOnZPkbCCZW;@qULw^Oi$S$S6M} y7sXqFkzYXhmS}RRAm*FX0FBF9jS@=RoPGc@H?h%vmH@K=0000