font
parent
9fc44188cc
commit
de454940bc
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
include(FetchContent)
|
||||
|
||||
set(BLT_GRAPHICS_VERSION 1.0.3)
|
||||
set(BLT_GRAPHICS_VERSION 1.0.4)
|
||||
set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
|
||||
|
||||
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "blt/std/types.h"
|
||||
|
||||
#ifndef BLT_WITH_GRAPHICS_FONT_H
|
||||
#define BLT_WITH_GRAPHICS_FONT_H
|
||||
|
||||
|
@ -27,6 +25,8 @@
|
|||
#include <string_view>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include "blt/std/types.h"
|
||||
#include <blt/math/vectors.h>
|
||||
|
||||
namespace blt::gfx::font
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace blt::gfx::font
|
|||
|
||||
font_face_t& set_pixel_sizes(blt::u32 width, blt::u32 height);
|
||||
|
||||
std::optional<int> load_char(char c);
|
||||
[[nodiscard]] std::optional<int> load_char(FT_ULong c) const;
|
||||
|
||||
[[nodiscard]] FT_Face* get() const
|
||||
{
|
||||
|
@ -64,9 +64,20 @@ namespace blt::gfx::font
|
|||
|
||||
struct font_file_t
|
||||
{
|
||||
std::string_view path;
|
||||
blt::u32 character_min_index;
|
||||
blt::u32 character_max_index;
|
||||
font_face_t font;
|
||||
blt::u64 character_min_index;
|
||||
blt::u64 character_max_index;
|
||||
|
||||
font_file_t(font_face_t font, u64 characterMinIndex, u64 characterMaxIndex);
|
||||
};
|
||||
|
||||
struct glyph_t
|
||||
{
|
||||
blt::vec2ui size;
|
||||
blt::vec2ui bearing;
|
||||
blt::i64 advance;
|
||||
|
||||
glyph_t(const vec2ui& size, const vec2ui& bearing, blt::i64 advance);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,16 +20,46 @@
|
|||
#define BLT_WITH_GRAPHICS_FONT_RENDERER_H
|
||||
|
||||
#include <blt/gfx/font/font.h>
|
||||
#include <blt/gfx/texture.h>
|
||||
#include <blt/std/hashmap.h>
|
||||
#include <blt/std/binary_tree.h>
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
|
||||
class font_texture_atlas : public texture_gl2D
|
||||
{
|
||||
public:
|
||||
struct bounded_t
|
||||
{
|
||||
font::glyph_t glyph;
|
||||
blt::vec2ui min;
|
||||
blt::vec2ui max;
|
||||
};
|
||||
|
||||
explicit font_texture_atlas(blt::i32 dimensions);
|
||||
|
||||
blt::u64 add_font(const font::font_file_t& file);
|
||||
|
||||
blt::u64 add_font(const font::font_file_t& file, blt::u64 start);
|
||||
|
||||
bounded_t& get_glyph(blt::u64 c)
|
||||
{ return glyphs.at(c); }
|
||||
|
||||
[[nodiscard]] const bounded_t& get_glyph(blt::u64 c) const
|
||||
{ return glyphs.at(c); }
|
||||
|
||||
private:
|
||||
blt::hashmap_t<blt::u64, bounded_t> glyphs;
|
||||
blt::u32 used_width = 0;
|
||||
blt::u32 used_height = 0;
|
||||
};
|
||||
|
||||
class font_renderer_t
|
||||
{
|
||||
public:
|
||||
explicit font_renderer_t();
|
||||
explicit font_renderer_t(const std::vector<font::font_file_t>& files, blt::i32 dimensions = 4096);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7bf24a11a53d345b58a7437a1b9768f2da78eeb2
|
||||
Subproject commit 05e5fcf7f1091d6c85711ff7ce53d840c17e547b
|
|
@ -18,6 +18,7 @@
|
|||
#include <blt/gfx/font/font.h>
|
||||
#include <blt/std/logging.h>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include "blt/std/assert.h"
|
||||
|
||||
namespace blt::gfx::font
|
||||
|
@ -252,13 +253,19 @@ namespace blt::gfx::font
|
|||
return *this;
|
||||
}
|
||||
|
||||
std::optional<int> font_face_t::load_char(char c)
|
||||
std::optional<int> font_face_t::load_char(FT_ULong c) const
|
||||
{
|
||||
if (int err = FT_Load_Char(*face, c, FT_LOAD_RENDER))
|
||||
return {err};
|
||||
return {};
|
||||
}
|
||||
|
||||
font_file_t::font_file_t(font_face_t font, u64 characterMinIndex, u64 characterMaxIndex):
|
||||
font(std::move(font)), character_min_index(characterMinIndex), character_max_index(characterMaxIndex)
|
||||
{}
|
||||
|
||||
glyph_t::glyph_t(const vec2ui& size, const vec2ui& bearing, blt::i64 advance): size(size), bearing(bearing), advance(advance)
|
||||
{}
|
||||
|
||||
const unsigned int default_font_compressed_size = 91605;
|
||||
const unsigned int default_font_compressed_data[91608 / 4] =
|
||||
|
|
|
@ -18,6 +18,63 @@
|
|||
#include <blt/gfx/renderer/font_renderer.h>
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
font_texture_atlas::font_texture_atlas(blt::i32 dimensions): texture_gl2D(dimensions, dimensions, GL_RED)
|
||||
{}
|
||||
|
||||
blt::u64 font_texture_atlas::add_font(const font::font_file_t& file)
|
||||
{
|
||||
return add_font(file, file.character_min_index);
|
||||
}
|
||||
|
||||
blt::u64 font_texture_atlas::add_font(const font::font_file_t& file, blt::u64 start)
|
||||
{
|
||||
blt::u32 max_height = 0;
|
||||
for (auto i = start; i < file.character_max_index; i++)
|
||||
{
|
||||
// returns an empty optional if there is no error code
|
||||
if (file.font.load_char(i))
|
||||
continue;
|
||||
auto face = *file.font.get();
|
||||
|
||||
auto width = face->glyph->bitmap.width;
|
||||
auto height = face->glyph->bitmap.rows;
|
||||
max_height = std::max(max_height, height);
|
||||
|
||||
// if adding this width overflows, we need to move to the next row.
|
||||
if (used_width + width > static_cast<blt::u32>(getWidth()))
|
||||
{
|
||||
used_height += max_height;
|
||||
max_height = 0;
|
||||
used_width = 0;
|
||||
}
|
||||
|
||||
// if we can't fit the height of this character we should move to the next texture atlas.
|
||||
if (used_height + height > static_cast<blt::u32>(getHeight()))
|
||||
return i;
|
||||
|
||||
auto begin_width = used_width;
|
||||
auto begin_height = used_height;
|
||||
auto end_width = used_width + width;
|
||||
auto end_height = used_height + height;
|
||||
|
||||
// upload the texture
|
||||
upload(face->glyph->bitmap.buffer, GL_RED, 0, static_cast<blt::i32>(begin_width), static_cast<blt::i32>(begin_height),
|
||||
static_cast<blt::i32>(width), static_cast<blt::i32>(height));
|
||||
|
||||
glyphs.insert(std::pair{i, bounded_t{
|
||||
font::glyph_t{
|
||||
{width, height},
|
||||
{face->glyph->bitmap_left, face->glyph->bitmap_top},
|
||||
face->glyph->advance.x},
|
||||
{begin_width, begin_height}, {end_width, end_height}}
|
||||
});
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
font_renderer_t::font_renderer_t(const std::vector<font::font_file_t>& files, blt::i32 dimensions)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -180,33 +180,6 @@ void blt::gfx::texture_gl::setDefaults(GLint type, GLint wrap_type) const
|
|||
#endif
|
||||
}
|
||||
|
||||
void blt::gfx::texture_gl2D::upload(void* data, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width, int sub_height,
|
||||
GLint dataMode) const
|
||||
{
|
||||
if (sub_width < 0)
|
||||
sub_width = m_width;
|
||||
if (sub_height < 0)
|
||||
sub_height = m_height;
|
||||
bind();
|
||||
glTexSubImage2D(textureBindType, level, x_offset, y_offset, sub_width, sub_height, dataColorMode, dataMode, data);
|
||||
generateMipmaps();
|
||||
unbind();
|
||||
}
|
||||
|
||||
void blt::gfx::texture_gl2D::upload(const blt::gfx::texture_data& file_data) const
|
||||
{
|
||||
upload((void*) file_data.data(), file_data.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, file_data.width(), file_data.height());
|
||||
}
|
||||
|
||||
void blt::gfx::texture_gl2D::upload(void* data, int width, int height, GLint dataColorMode, GLint dataMode)
|
||||
{
|
||||
bind();
|
||||
glTexImage2D(textureBindType, 0, textureColorMode, width, height, 0, dataColorMode, dataMode, data);
|
||||
generateMipmaps();
|
||||
unbind();
|
||||
}
|
||||
|
||||
|
||||
void blt::gfx::texture_gl2D::resize(int width, int height)
|
||||
{
|
||||
m_width = width;
|
||||
|
@ -238,6 +211,34 @@ blt::gfx::texture_gl2D::texture_gl2D(const blt::gfx::texture_data& data):
|
|||
unbind();
|
||||
}
|
||||
|
||||
void blt::gfx::texture_gl2D::upload(void* data, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width, int sub_height,
|
||||
GLint dataMode) const
|
||||
{
|
||||
if (sub_width < 0)
|
||||
sub_width = m_width;
|
||||
if (sub_height < 0)
|
||||
sub_height = m_height;
|
||||
bind();
|
||||
glTexSubImage2D(textureBindType, level, x_offset, y_offset, sub_width, sub_height, dataColorMode, dataMode, data);
|
||||
generateMipmaps();
|
||||
unbind();
|
||||
}
|
||||
|
||||
void blt::gfx::texture_gl2D::upload(const blt::gfx::texture_data& file_data) const
|
||||
{
|
||||
upload((void*) file_data.data(), file_data.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, file_data.width(), file_data.height());
|
||||
}
|
||||
|
||||
void blt::gfx::texture_gl2D::upload(void* data, int width, int height, GLint dataColorMode, GLint dataMode)
|
||||
{
|
||||
bind();
|
||||
glTexImage2D(textureBindType, 0, textureColorMode, width, height, 0, dataColorMode, dataMode, data);
|
||||
generateMipmaps();
|
||||
unbind();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void blt::gfx::gl_texture2D_array::upload(void* data, int index, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width,
|
||||
int sub_height) const
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue