psemek/libs/ui/source/default_fonts.cpp

97 lines
3 KiB
C++

#include <psemek/ui/font.hpp>
#include <psemek/ui/monospace_font.hpp>
#include <psemek/ui/kerned_font.hpp>
#include <psemek/gfx/resource/font_9x12_png.hpp>
#include <psemek/ui/resources/font_9x12_glyphs_txt.hpp>
#include <psemek/gfx/resource/font_10x12_bold_png.hpp>
#include <psemek/ui/resources/font_10x12_bold_glyphs_txt.hpp>
#include <psemek/io/memory_stream.hpp>
#include <sstream>
namespace psemek::ui
{
std::unique_ptr<font> make_default_monospace_9x12_font()
{
character_range range{32, 128};
std::string_view name = "default_monospace_9x12";
geom::vector<int, 2> size{9, 12};
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_png_monochrome(io::memory_istream{gfx::resource::font_9x12_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<geom::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;
geom::box<float, 2> b;
b[0].min = x * 11 + 1;
b[0].max = b[0].min + 9;
b[1].min = y * 14 + 1;
b[1].max = b[1].min + 12;
texcoords[c - range.begin] = b;
}
return std::make_unique<monospace_font>(range, name, size, std::move(atlas), std::move(texcoords));
}
static std::unique_ptr<font> make_default_font(std::string_view name, geom::vector<int, 2> const & size, rs::resource const & atlas_resource, rs::resource const & glyphs_resource)
{
gfx::texture_2d atlas = gfx::texture_2d::from_pixmap(gfx::read_png_monochrome(io::memory_istream{atlas_resource.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);
bmfont_data data;
data.name = name;
data.size = size;
data.baseline = 2;
{
std::istringstream is{std::string(glyphs_resource.data)};
std::string line;
while (std::getline(is, line))
{
if (auto pos = line.find('#'); pos != std::string::npos)
line = line.substr(0, pos);
if (line.empty()) continue;
std::istringstream is{std::move(line)};
int c;
is >> c;
auto & glyph = data.glyphs[c];
is >> glyph.start_x >> glyph.start_y >> glyph.size_x >> glyph.size_y >> glyph.offset_x >> glyph.offset_y >> glyph.advance;
}
}
return std::make_unique<kerned_font>(std::move(data), std::move(atlas));
}
std::unique_ptr<font> make_default_9x12_font()
{
return make_default_font("default_9x12", {9, 12}, gfx::resource::font_9x12_png, ui::resources::font_9x12_glyphs_txt);
}
std::unique_ptr<font> make_default_10x12_bold_font()
{
return make_default_font("default_10x12_bold", {10, 12}, gfx::resource::font_10x12_bold_png, ui::resources::font_10x12_bold_glyphs_txt);
}
}