font
parent
9fc44188cc
commit
de454940bc
|
@ -1,7 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 1.0.3)
|
set(BLT_GRAPHICS_VERSION 1.0.4)
|
||||||
set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
|
set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
|
||||||
|
|
||||||
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
|
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "blt/std/types.h"
|
|
||||||
|
|
||||||
#ifndef BLT_WITH_GRAPHICS_FONT_H
|
#ifndef BLT_WITH_GRAPHICS_FONT_H
|
||||||
#define BLT_WITH_GRAPHICS_FONT_H
|
#define BLT_WITH_GRAPHICS_FONT_H
|
||||||
|
|
||||||
|
@ -27,6 +25,8 @@
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include "blt/std/types.h"
|
||||||
|
#include <blt/math/vectors.h>
|
||||||
|
|
||||||
namespace blt::gfx::font
|
namespace blt::gfx::font
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ namespace blt::gfx::font
|
||||||
|
|
||||||
font_face_t& set_pixel_sizes(blt::u32 width, blt::u32 height);
|
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
|
[[nodiscard]] FT_Face* get() const
|
||||||
{
|
{
|
||||||
|
@ -64,9 +64,20 @@ namespace blt::gfx::font
|
||||||
|
|
||||||
struct font_file_t
|
struct font_file_t
|
||||||
{
|
{
|
||||||
std::string_view path;
|
font_face_t font;
|
||||||
blt::u32 character_min_index;
|
blt::u64 character_min_index;
|
||||||
blt::u32 character_max_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
|
#define BLT_WITH_GRAPHICS_FONT_RENDERER_H
|
||||||
|
|
||||||
#include <blt/gfx/font/font.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
|
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
|
class font_renderer_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit font_renderer_t();
|
explicit font_renderer_t(const std::vector<font::font_file_t>& files, blt::i32 dimensions = 4096);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7bf24a11a53d345b58a7437a1b9768f2da78eeb2
|
Subproject commit 05e5fcf7f1091d6c85711ff7ce53d840c17e547b
|
|
@ -18,6 +18,7 @@
|
||||||
#include <blt/gfx/font/font.h>
|
#include <blt/gfx/font/font.h>
|
||||||
#include <blt/std/logging.h>
|
#include <blt/std/logging.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
#include "blt/std/assert.h"
|
#include "blt/std/assert.h"
|
||||||
|
|
||||||
namespace blt::gfx::font
|
namespace blt::gfx::font
|
||||||
|
@ -252,13 +253,19 @@ namespace blt::gfx::font
|
||||||
return *this;
|
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))
|
if (int err = FT_Load_Char(*face, c, FT_LOAD_RENDER))
|
||||||
return {err};
|
return {err};
|
||||||
return {};
|
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_size = 91605;
|
||||||
const unsigned int default_font_compressed_data[91608 / 4] =
|
const unsigned int default_font_compressed_data[91608 / 4] =
|
||||||
|
|
|
@ -19,5 +19,62 @@
|
||||||
|
|
||||||
namespace blt::gfx
|
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
|
#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)
|
void blt::gfx::texture_gl2D::resize(int width, int height)
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
|
@ -238,6 +211,34 @@ blt::gfx::texture_gl2D::texture_gl2D(const blt::gfx::texture_data& data):
|
||||||
unbind();
|
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,
|
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
|
int sub_height) const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue