refactor font loading

This commit is contained in:
2019-12-01 18:24:59 +01:00
parent 0905827b8d
commit c8bce21b95
30 changed files with 180 additions and 84 deletions

Binary file not shown.

Binary file not shown.

BIN
data/fonts/roboto-black.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
data/fonts/roboto-bold.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
data/fonts/roboto-light.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/fonts/roboto-thin.ttf Normal file

Binary file not shown.

View File

@@ -168,10 +168,6 @@ void App::initAssets()
{
LOG("initializing assets");
FontManager::init();
LOG("initializing assets loading fonts");
FontManager::load("arial-17", "data/fonts/Roboto-Regular.ttf", 17, display_density * zoom);
FontManager::load("arial-20", "data/fonts/Roboto-Regular.ttf", 20, display_density * zoom);
FontManager::load("arial-30", "data/fonts/Roboto-Regular.ttf", 30, display_density * zoom);
LOG("initializing assets create sampler");
sampler.create(GL_NEAREST);

View File

@@ -9,6 +9,32 @@
std::map<std::string, Font> FontManager::m_fonts;
Sampler FontManager::m_sampler;
Font::Font(Font&& other) noexcept
{
w = other.w;
h = other.h;
bounds = other.bounds;
size = other.size;
scale = other.size;
font_tex = std::move(other.font_tex);
path = std::move(other.path);
id = std::move(other.id);
chars = std::move(other.chars);
}
void Font::operator=(Font&& other) noexcept
{
w = other.w;
h = other.h;
bounds = other.bounds;
size = other.size;
scale = other.size;
font_tex = std::move(other.font_tex);
path = std::move(other.path);
id = std::move(other.id);
chars = std::move(other.chars);
}
bool Font::load(const std::string& ttf, int font_size, float font_scale)
{
Asset file;
@@ -59,15 +85,24 @@ void FontManager::init()
m_sampler.create();
}
bool FontManager::load(const std::string& id, const char* ttf, int sz, float scale)
bool FontManager::load(const std::string& id, const std::string& ttf, int sz, float scale)
{
return m_fonts[id].load(ttf, sz, scale);
}
const Font& FontManager::get(const std::string& id)
const Font& FontManager::get(const std::string& name, int size, const std::string& weight, bool italic)
{
auto id = fmt::format("{}-{}{}-{}", name, weight, italic ? "-italic" : "", size);
auto it = m_fonts.find(id);
if (it == m_fonts.end())
{
LOG("load font %s", id.c_str());
auto path = fmt::format("data/fonts/{}-{}{}.ttf", name, weight, italic ? "-italic" : "");
m_fonts[id].load(path, size, App::I->display_density * App::I->zoom);
return m_fonts[id];
}
return it->second;
}
void FontManager::change_scale(float scale)
{
@@ -136,10 +171,14 @@ bool TextMesh::create()
return true;
}
void TextMesh::update(const std::string& id, const std::string& text)
void TextMesh::update(const std::string& text, const std::string& font, int size, const std::string& weight, bool italic)
{
font_id = id;
auto& f = FontManager::get(id);
this->font = font;
this->size = size;
this->weight = weight;
this->italic = italic;
auto& f = FontManager::get(font, size, weight, italic);
float spacing = (f.bounds.w - f.bounds.y);
float avg_width = f.bounds.z - f.bounds.x;
cur_box = glm::vec4(0, f.bounds.y, 5, spacing);
@@ -227,7 +266,7 @@ void TextMesh::update(const std::string& id, const std::string& text)
void TextMesh::draw()
{
auto& f = FontManager::get(font_id);
auto& f = FontManager::get(font, size, weight, italic);
if (f.font_tex.ready())
{
glActiveTexture(GL_TEXTURE0);

View File

@@ -13,12 +13,18 @@ public:
// {mix, max}
glm::vec4 bounds{ 0 };
int size = 0;
stbtt_fontinfo font;
Texture2D font_tex;
std::string path;
std::string id;
std::vector<stbtt_bakedchar> chars;
float scale = 1.f;
Font() noexcept = default;
Font(const Font&) = delete;
void operator=(const Font&) = delete;
Font(Font&& other) noexcept;
void operator=(Font&& other) noexcept;
bool load(const std::string& ttf, int sz, float scale);
void change_scale(float scale);
void calc_bounds();
@@ -30,8 +36,8 @@ public:
static std::map<std::string, Font> m_fonts;
static Sampler m_sampler;
static void init();
static bool load(const std::string& id, const char* ttf, int sz, float scale);
static const Font& get(const std::string& id);
static bool load(const std::string& id, const std::string& ttf, int sz, float scale);
static const Font& get(const std::string& name, int size, const std::string& weight, bool italic);
static void invalidate() { m_fonts.clear(); }
static void change_scale(float scale);
};
@@ -50,10 +56,13 @@ public:
int font_array_count = 0;
int max_width = 0;
GLuint font_buffers[2] = {0, 0};
std::string font_id;
std::string font;
std::string weight;
int italic;
int size;
glm::vec2 bb = { 0, 0 };
glm::vec4 cur_box;
bool create();
void update(const std::string& id, const std::string& text);
void update(const std::string& text, const std::string& font, int size, const std::string& weight, bool italic);
void draw();
};

View File

@@ -673,8 +673,6 @@ void NodeCanvas::create_buffers()
m_cache_rtt.create((int)new_size.x, (int)new_size.y, -1, GL_RGBA8);
m_rtt.create((int)new_size.x, (int)new_size.y, -1, GL_RGBA8, true);
m_blender_bg.create((int)new_size.x, (int)new_size.y, GL_RGBA8);
if (auto img = root()->find<NodeImageTexture>("tex-debug"))
img->tex.assign(m_canvas->m_mixer.getTextureID());
}
void NodeCanvas::set_density(float d)

View File

@@ -45,8 +45,6 @@ void NodeDialogBrowse::init_controls()
msgbox->btn_ok->on_click = [this,msgbox](Node*){
auto path = current->m_path;
int idx = container->get_child_index(current);
if (auto image_tex = current->find<NodeImageTexture>("thumb-tex"))
image_tex->tex.destroy();
container->remove_child(current);
if (!container->m_children.empty())
{
@@ -106,11 +104,6 @@ void NodeDialogBrowse::init_controls()
void NodeDialogBrowse::clear_list()
{
for (auto& n : container->m_children)
{
if (auto item = std::static_pointer_cast<NodeDialogBrowseItem>(n))
item->m_thumb->tex.destroy();
}
container->remove_all_children();
}
@@ -153,8 +146,8 @@ void NodeDialogBrowse::init_list()
// load thumb
if (auto image_tex = node->find<NodeImageTexture>("thumb-tex"))
{
image_tex->tex.destroy();
image_tex->tex.create(thumb);
image_tex->tex = std::make_shared<Texture2D>();
image_tex->tex->create(thumb);
}
container->add_child(node);
}

View File

@@ -60,7 +60,7 @@ void NodeDialogCloud::load_thumbs_thread()
align->SetAlign(YGAlignCenter);
align->SetJustify(YGJustifyCenter);
auto* text = align->add_child<NodeText>();
text->set_font("arial-30");
text->set_font_size(30);
text->set_text("Connecting to the server...");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);
@@ -138,8 +138,8 @@ void NodeDialogCloud::load_thumbs_thread()
thumb.copy_from((uint8_t*)rgb.data());
auto image_tex = node->find<NodeImageTexture>("thumb-tex");
image_tex->tex.destroy();
image_tex->tex.create(thumb);
image_tex->tex = std::make_shared<Texture2D>();
image_tex->tex->create(thumb);
app_redraw();
}

View File

@@ -40,7 +40,7 @@ void NodeDialogExportPPBR::init_controls()
btn_header_clear = find<NodeButton>("header-clear");
btn_header_clear->on_click = [this] (Node*) {
m_header_image.reset();
img_header->tex.destroy();
img_header->tex->destroy();
txt_header_descr->SetVisibility(true);
};
btn_header_gen = find<NodeButton>("header-gen");
@@ -74,7 +74,8 @@ void NodeDialogExportPPBR::open_header()
m_header_image = std::make_shared<Image>();
m_header_image->load(path);
m_header_image->resize(256, 128);
img_header->tex.create(*m_header_image);
img_header->tex = std::make_shared<Texture2D>();
img_header->tex->create(*m_header_image);
txt_header_descr->SetVisibility(false);
});
}

View File

@@ -60,7 +60,7 @@ void NodeDialogOpen::init_controls()
{
current = nullptr;
auto image_tex = find<NodeImageTexture>("thumb-tex");
image_tex->tex.destroy();
image_tex->tex.reset();
}
Asset::delete_file(path);
msgbox->destroy();
@@ -83,8 +83,8 @@ void NodeDialogOpen::init_controls()
return;
Image thumb = Canvas::I->thumbnail_read(target->m_path);
auto image_tex = find<NodeImageTexture>("thumb-tex");
image_tex->tex.destroy();
image_tex->tex.create(thumb);
image_tex->tex = std::make_shared<Texture2D>();
image_tex->tex->create(thumb);
selected_path = target->m_path;
selected_file = target->m_file_name;
selected_name = selected_file.substr(0, selected_file.length() - strlen(".ppi"));

View File

@@ -18,8 +18,8 @@ void NodeImageTexture::clone_copy(Node* dest) const
void NodeImageTexture::draw()
{
tex.bind();
auto& sampler = tex.has_mips ? NodeImage::m_sampler_mips : NodeImage::m_sampler;
tex ? tex->bind() : glBindTexture(GL_TEXTURE_2D, 0);
auto& sampler = tex && tex->has_mips ? NodeImage::m_sampler_mips : NodeImage::m_sampler;
sampler.bind(0);
glEnable(GL_BLEND);
ShaderManager::use(kShader::Texture);
@@ -27,6 +27,5 @@ void NodeImageTexture::draw()
ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
NodeImage::m_plane.draw_fill();
sampler.unbind();
tex.unbind();
glDisable(GL_BLEND);
}

View File

@@ -5,14 +5,8 @@
class NodeImageTexture : public Node
{
public:
Texture2D tex;
std::shared_ptr<Texture2D> tex;
virtual Node* clone_instantiate() const override;
virtual void clone_copy(Node* dest) const override;
// TODO: maybe we can save the texture data and restore later
//virtual void restore_context() override
//{
// Node::restore_context();
// create();
//}
virtual void draw() override;
};

View File

@@ -82,9 +82,10 @@ void NodePanelGrid::init_controls()
{
m_file_path = path;
m_hm_image = img.resize(128, 128);
m_hm_preview->tex.create(m_hm_image);
m_hm_preview->tex.create_mipmaps();
auto sz = m_hm_preview->tex.size();
m_hm_preview->tex = std::make_shared<Texture2D>();
m_hm_preview->tex->create(m_hm_image);
m_hm_preview->tex->create_mipmaps();
auto sz = m_hm_preview->tex->size();
m_hm_preview->SetAspectRatio(sz.x / sz.y);
m_hm_plane.create(1, 1, m_hm_image, get_resolution(), get_height());
m_hm_preview->SetHeight(100);
@@ -99,7 +100,7 @@ void NodePanelGrid::init_controls()
{
m_hm_plane.create(1, 1, 100 * get_resolution());
m_hm_image.destroy();
m_hm_preview->tex.destroy();
m_hm_preview->tex.reset();
m_hm_preview->SetHeight(0);
};
@@ -109,9 +110,10 @@ void NodePanelGrid::init_controls()
if (img.load_file(m_file_path))
{
m_hm_image = img.resize(128, 128);
m_hm_preview->tex.create(m_hm_image);
m_hm_preview->tex.create_mipmaps();
auto sz = m_hm_preview->tex.size();
m_hm_preview->tex = std::make_shared<Texture2D>();
m_hm_preview->tex->create(m_hm_image);
m_hm_preview->tex->create_mipmaps();
auto sz = m_hm_preview->tex->size();
m_hm_preview->SetAspectRatio(sz.x / sz.y);
m_hm_plane.create(1, 1, m_hm_image, get_resolution(), get_height());
m_hm_preview->SetHeight(100);

View File

@@ -42,7 +42,7 @@ std::future<bool> NodeRemotePage::load_url(const std::string& url,
align->SetAlign(YGAlignCenter);
align->SetJustify(YGJustifyCenter);
auto text = align->add_child_ref<NodeText>();
text->set_font("arial-30");
text->set_font_size(30);
text->set_text("Connecting to the server...");
m_url = url;

View File

@@ -14,12 +14,13 @@ void NodeText::clone_copy(Node* dest) const
NodeText* n = static_cast<NodeText*>(dest);
n->m_text_mesh.max_width = m_text_mesh.max_width;
n->m_text_mesh.create();
n->m_text_mesh.update(font_id, m_text);
n->m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
n->m_text = m_text;
n->m_font = m_font;
n->m_color = m_color;
n->m_font_name = m_font_name;
n->m_font_size = m_font_size;
n->font_id = font_id;
n->m_font_weight = m_font_weight;
n->m_font_italic = m_font_italic;
n->m_color = m_color;
n->m_multiline = m_multiline;
n->m_off = m_off;
n->m_text_align_v = m_text_align_v;
@@ -29,20 +30,30 @@ void NodeText::clone_copy(Node* dest) const
void NodeText::create()
{
Node::create();
if (!m_font.empty())
if (!m_font_name.empty())
{
font_id = fmt::format("{}-{}", m_font, m_font_size);
m_text_mesh.create();
m_text_mesh.update(font_id, m_text);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
}
void NodeText::set_font(const std::string& fontID)
void NodeText::set_font(const std::string& name, int size, const std::string& weight, bool italic)
{
font_id = fontID;
m_font_name = name;
m_font_size = size;
m_font_weight = weight;
m_font_italic = italic;
m_text_mesh.create();
m_text_mesh.update(font_id, m_text);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
void NodeText::set_font_size(int size)
{
m_font_size = size;
m_text_mesh.create();
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
@@ -77,7 +88,7 @@ void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* att
m_text = unescape(attr->Value());
break;
case kAttribute::FontFace:
m_font = attr->Value();
m_font_name = attr->Value();
break;
case kAttribute::FontSize:
m_font_size = attr->IntValue();
@@ -100,7 +111,7 @@ void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* att
void NodeText::set_text(const std::string& s)
{
m_text = s;
m_text_mesh.update(font_id, s);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
@@ -112,7 +123,7 @@ void NodeText::set_text_format(const char* fmt, ...)
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
m_text = buffer;
m_text_mesh.update(font_id, buffer);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
@@ -164,6 +175,6 @@ void NodeText::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
{
auto pad = GetPadding();
m_text_mesh.max_width = m_multiline ? new_size.x - (pad[1] + pad[3]) : 0;
m_text_mesh.update(font_id, m_text);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}

View File

@@ -13,10 +13,11 @@ public:
};
TextMesh m_text_mesh;
std::string m_text;
std::string m_font = "arial";
std::string m_font_name = "roboto";
glm::vec4 m_color{ 1, 1, 1, 1 };
std::string m_font_weight = "regular";
int m_font_size = 17;
std::string font_id;
bool m_font_italic = false;
bool m_multiline = false;
glm::vec2 m_off = { 0, 0 };
@@ -32,6 +33,7 @@ public:
void set_text(const std::string& s);
void set_text_format(const char* fmt, ...);
void set_font(const std::string& fontID);
void set_font(const std::string& name, int size, const std::string& weight, bool italic);
void set_font_size(int size);
void update_layout();
};

View File

@@ -35,12 +35,13 @@ void NodeTextInput::clone_copy(Node* dest) const
NodeTextInput* n = static_cast<NodeTextInput*>(dest);
n->m_text_mesh.max_width = m_text_mesh.max_width;
n->m_text_mesh.create();
n->m_text_mesh.update(font_id, m_text);
n->m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
n->m_text = m_text;
n->m_font = m_font;
n->m_color = m_color;
n->m_font_name = m_font_name;
n->m_font_size = m_font_size;
n->font_id = font_id;
n->m_font_weight = m_font_weight;
n->m_font_italic = m_font_italic;
n->m_color = m_color;
n->m_multiline = m_multiline;
n->m_off = m_off;
n->m_text_align_v = m_text_align_v;
@@ -130,7 +131,7 @@ kEventResult NodeTextInput::handle_event(Event* e)
void NodeTextInput::set_text(const std::string& s)
{
m_text = s;
m_text_mesh.update(font_id, s);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
@@ -142,7 +143,26 @@ void NodeTextInput::set_text_format(const char* fmt, ...)
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
m_text = buffer;
m_text_mesh.update(font_id, buffer);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
void NodeTextInput::set_font(const std::string& name, int size, const std::string& weight, bool italic)
{
m_font_name = name;
m_font_size = size;
m_font_weight = weight;
m_font_italic = italic;
m_text_mesh.create();
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
void NodeTextInput::set_font_size(int size)
{
m_font_size = size;
m_text_mesh.create();
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
@@ -182,11 +202,10 @@ void NodeTextInput::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float
void NodeTextInput::create()
{
NodeBorder::create();
if (!m_font.empty())
if (!m_font_name.empty())
{
font_id = fmt::format("{}-{}", m_font, m_font_size);
m_text_mesh.create();
m_text_mesh.update(font_id, m_text);
m_text_mesh.update(m_text, m_font_name, m_font_size, m_font_weight, m_font_italic);
update_layout();
}
}

View File

@@ -16,10 +16,11 @@ public:
TextMesh m_text_mesh;
std::string m_text;
std::string m_font = "arial";
std::string m_font_name = "roboto";
glm::vec4 m_color{ 1, 1, 1, 1 };
std::string m_font_weight = "regular";
int m_font_size = 17;
std::string font_id;
bool m_font_italic = false;
bool m_multiline = false;
bool m_cursor_visible = false;
@@ -41,6 +42,8 @@ public:
void set_text(const std::string& s);
void set_text_format(const char* fmt, ...);
void set_font(const std::string& name, int size, const std::string& weight, bool italic);
void set_font_size(int size);
void update_layout();
bool has_focus() noexcept;
};

View File

@@ -142,6 +142,30 @@ Image Texture2D::get_image() const noexcept
return ret;
}
Texture2D::Texture2D(Texture2D&& other) noexcept
{
m_tex = other.m_tex;
m_width = other.m_width;
m_height = other.m_height;
m_format = other.m_format;
m_iformat = other.m_iformat;
auto_destroy = other.auto_destroy;
has_mips = other.has_mips;
other.m_tex = false;
}
void Texture2D::operator=(Texture2D&& other) noexcept
{
m_tex = other.m_tex;
m_width = other.m_width;
m_height = other.m_height;
m_format = other.m_format;
m_iformat = other.m_iformat;
auto_destroy = other.auto_destroy;
has_mips = other.has_mips;
other.m_tex = false;
}
bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data)
{
App::I->render_task([=]
@@ -247,7 +271,7 @@ glm::vec2 Texture2D::size() const
Texture2D::~Texture2D()
{
if (auto_destroy)
//if (auto_destroy)
{
LOG("Texture2D auto destroy");
destroy();

View File

@@ -9,6 +9,13 @@ class Texture2D
GLint m_format = 0;
GLint m_iformat = 0;
public:
Texture2D() noexcept = default;
Texture2D(const Texture2D&) = delete;
void operator=(const Texture2D&) = delete;
Texture2D(Texture2D&& other) noexcept;
void operator=(Texture2D&& other) noexcept;
~Texture2D();
bool auto_destroy = false;
bool has_mips = false;
bool create(int width, int height, GLint internal_format = GL_RGBA8, GLint format = GL_RGBA, const uint8_t* data = nullptr);
@@ -24,7 +31,6 @@ public:
void create_mipmaps();
glm::vec2 size() const;
Image get_image() const noexcept;
~Texture2D();
};
struct TextureCube