36 return m_glyphs.count(code) != 0;
41 return std::get<0>(m_glyphs.try_emplace(code))->second;
46 if (
auto it = m_glyphs.find(code); it != m_glyphs.end())
60 auto ceil2 = [](std::uint32_t x) -> std::uint32_t
72 std::uint32_t bitmap_w = 0;
73 std::uint32_t bitmap_h = 0;
77 std::uint32_t max_glyph_w = 0;
78 std::uint32_t max_glyph_h = 0;
79 for (
auto it = m_glyphs.begin(); it != m_glyphs.end(); ++it)
81 max_glyph_w =
std::max(max_glyph_w, it->second.bitmap_width);
82 max_glyph_h =
std::max(max_glyph_h, it->second.bitmap_height);
86 bitmap_w = ceil2(max_glyph_w);
87 bitmap_h = ceil2(max_glyph_h);
91 bitmap_w = m_texture->get_image_view()->get_image()->get_dimensions()[0];
92 bitmap_h = m_texture->get_image_view()->get_image()->get_dimensions()[1];
97 std::unordered_map<char32_t, const typename geom::rect_pack<std::uint32_t>::node_type*> glyph_map;
102 for (
auto it = m_glyphs.begin(); it != m_glyphs.end(); ++it)
105 const auto* node = glyph_pack.
pack(it->second.bitmap_width, it->second.bitmap_height);
112 glyph_map[it->first] = node;
116 if (glyph_map.size() != m_glyphs.size())
132 if (bitmap_w > bitmap_h)
133 bitmap_h = ceil2(++bitmap_h);
135 bitmap_w = ceil2(++bitmap_w);
136 glyph_pack.
resize(bitmap_w, bitmap_h);
149 bitmap_w != m_texture->get_image_view()->get_image()->get_dimensions()[0] ||
150 bitmap_h != m_texture->get_image_view()->get_image()->get_dimensions()[1])
156 m_sampler = std::make_shared<gl::sampler>
166 const std::uint32_t mip_count =
static_cast<std::uint32_t
>(std::bit_width(
std::max(bitmap_w, bitmap_h)));
167 m_texture = std::make_shared<gl::texture_2d>
169 std::make_shared<gl::image_view_2d>
171 std::make_shared<gl::image_2d>
187 for (
auto it = m_glyphs.begin(); it != m_glyphs.end(); ++it)
190 const auto* node = glyph_map[it->first];
193 m_texture->get_image_view()->get_image()->write
196 node->bounds.min.x(),
197 node->bounds.min.y(),
199 it->second.bitmap_width,
200 it->second.bitmap_height,
207 it->second.position = {node->bounds.min.x(), node->bounds.min.y()};
211 m_texture->get_image_view()->get_image()->generate_mipmaps();
219 if (
auto it = m_glyphs.find(code); it != m_glyphs.end())
221 return it->second.metrics;
223 throw std::invalid_argument(
"Cannot fetch metrics of unknown bitmap glyph");
228 if (
auto it = m_glyphs.find(code); it != m_glyphs.end())
238 if (
auto it = m_glyphs.find(code); it != m_glyphs.end())
const node_type * pack(scalar_type w, scalar_type h)
Packs a rect into the rect pack.
void resize(scalar_type w, scalar_type h)
Clears the pack and resizes the root node bounds.
void clear()
Clear the pack, deallocating all nodes.
Raster font in which glyphs are stored as arrays of pixels.
bitmap_font()
Creates an empty bitmap font.
virtual const glyph_metrics & get_glyph_metrics(char32_t code) const
Returns metrics describing a glyph.
virtual bool contains(char32_t code) const
Returns true if the font contains a glyph with the given character code.
bool pack(bool resize=true)
Packs all glyph bitmaps into the font bitmap.
void remove(char32_t code)
Removes a glyph from the font.
bitmap_glyph & insert(char32_t code)
Inserts a glyph into the font.
void clear()
Removes all glyphs from the font.
const bitmap_glyph * get_glyph(char32_t code) const
Returns a pointer to the glyph corresponding to a UTF-32 character code, or nullptr if no such glyph ...
Abstract base class for fonts.
@ clamp_to_edge
Clamp to edge wrap mode.
@ linear
Linear filtering.
@ linear
Linear filtering.
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Single glyph in a bitmap font.
Metrics describing properties of a font.
Metrics describing properties of a glyph.