Support margins & offsets in monospace_font, and add a new default 5x7 font
All checks were successful
Run tests / Run tests (push) Successful in 7m26s

This commit is contained in:
Nikita Lisitsa 2026-07-24 15:52:04 +03:00
parent d4abc645f4
commit 68650da6f5
7 changed files with 50 additions and 5 deletions

View file

@ -85,6 +85,8 @@ namespace psemek::fonts::inline v1
};
std::unique_ptr<font> make_default_monospace_9x12_font();
std::unique_ptr<font> make_default_monospace_5x7_font();
std::unique_ptr<font> make_default_9x12_font();
std::unique_ptr<font> make_default_10x12_bold_font();

View file

@ -8,7 +8,7 @@ namespace psemek::fonts
struct monospace_font
: font
{
monospace_font(character_range range, std::string_view name, math::vector<int, 2> size, gfx::texture_2d atlas, std::vector<math::box<float, 2>> texcoords);
monospace_font(character_range range, std::string_view name, math::vector<int, 2> size, math::vector<int, 2> offset, math::vector<int, 2> margin, gfx::texture_2d atlas, std::vector<math::box<float, 2>> 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<int, 2> size_;
math::vector<int, 2> offset_;
math::vector<int, 2> margin_;
gfx::texture_2d atlas_;
std::vector<math::box<float, 2>> texcoords_;

View file

@ -4,6 +4,7 @@
#include <psemek/gfx/resource/font_9x12_png.hpp>
#include <psemek/gfx/resource/font_10x12_bold_png.hpp>
#include <psemek/gfx/resource/font_5x7_png.hpp>
#include <psemek/fonts/resources/font_9x12_glyphs_txt.hpp>
#include <psemek/fonts/resources/font_10x12_bold_glyphs_txt.hpp>
@ -45,7 +46,40 @@ namespace psemek::fonts::inline v1
texcoords[c - range.begin] = b;
}
return std::make_unique<monospace_font>(range, name, size, std::move(atlas), std::move(texcoords));
// NB: Margin is baked into the glyphs
return std::make_unique<monospace_font>(range, name, size, math::vector{0, 0}, math::vector{0, 0}, std::move(atlas), std::move(texcoords));
}
std::unique_ptr<font> make_default_monospace_5x7_font()
{
character_range range{32, 128};
std::string_view name = "default_monospace_5x7";
math::vector<int, 2> size{5, 9};
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_image<std::uint8_t>(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<math::box<float, 2>> 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<float, 2> 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<monospace_font>(range, name, size, math::vector{0, -2}, math::vector{1, 1}, std::move(atlas), std::move(texcoords));
}
static std::unique_ptr<font> make_default_font(std::string_view name, math::vector<int, 2> const & size, rs::resource const & atlas_resource, rs::resource const & glyphs_resource)

View file

@ -6,10 +6,12 @@
namespace psemek::fonts
{
monospace_font::monospace_font(character_range range, std::string_view name, math::vector<int, 2> size, gfx::texture_2d atlas, std::vector<math::box<float, 2>> texcoords)
monospace_font::monospace_font(character_range range, std::string_view name, math::vector<int, 2> size, math::vector<int, 2> offset, math::vector<int, 2> margin, gfx::texture_2d atlas, std::vector<math::box<float, 2>> 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<float, 2> const size = math::cast<float>(this->size()) * options.scale;
math::vector<float, 2> const advance = math::pointwise_mult(advance_dir(options.direction), size);
math::vector<float, 2> const margin = math::cast<float>(margin_) * options.scale;
math::vector<float, 2> const offset = math::cast<float>(offset_) * options.scale;
math::vector<float, 2> const advance = math::pointwise_mult(advance_dir(options.direction), size + margin);
std::vector<glyph> 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;
}

View file

@ -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
)

View file

@ -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<float, 2> scale = {1.f, 1.f};
x_align x = x_align::center;
y_align y = y_align::center;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB