diff options
Diffstat (limited to 'modules/text_server_adv')
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 137 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.h | 7 |
2 files changed, 133 insertions, 11 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 4cd5dada4d..0ae8219e23 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -994,8 +994,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( int w = (bounds.r - bounds.l); int h = (bounds.t - bounds.b); - int mw = w + p_rect_margin * 2; - int mh = h + p_rect_margin * 2; + int mw = w + p_rect_margin * 4; + int mh = h + p_rect_margin * 4; ERR_FAIL_COND_V(mw > 4096, FontGlyph()); ERR_FAIL_COND_V(mh > 4096, FontGlyph()); @@ -1029,7 +1029,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + p_rect_margin) * tex.texture_w + j + tex_pos.x + p_rect_margin) * 4; + int ofs = ((i + tex_pos.y + p_rect_margin * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * 4; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), FontGlyph()); wr[ofs + 0] = (uint8_t)(CLAMP(image(j, i)[0] * 256.f, 0.f, 255.f)); wr[ofs + 1] = (uint8_t)(CLAMP(image(j, i)[1] * 256.f, 0.f, 255.f)); @@ -1049,8 +1049,9 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( chr.texture_idx = tex_pos.index; - chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = Vector2(bounds.l, -bounds.t); + chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2); + chr.rect.position = Vector2(bounds.l - p_rect_margin, -bounds.t - p_rect_margin); + chr.rect.size = chr.uv_rect.size; } return chr; @@ -1062,8 +1063,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma int w = bitmap.width; int h = bitmap.rows; - int mw = w + p_rect_margin * 2; - int mh = h + p_rect_margin * 2; + int mw = w + p_rect_margin * 4; + int mh = h + p_rect_margin * 4; ERR_FAIL_COND_V(mw > 4096, FontGlyph()); ERR_FAIL_COND_V(mh > 4096, FontGlyph()); @@ -1083,7 +1084,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + p_rect_margin) * tex.texture_w + j + tex_pos.x + p_rect_margin) * color_size; + int ofs = ((i + tex_pos.y + p_rect_margin * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * color_size; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), FontGlyph()); switch (bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: { @@ -1124,8 +1125,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma chr.texture_idx = tex_pos.index; chr.found = true; - chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling; + chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2); + chr.rect.position = Vector2(xofs - p_rect_margin, -yofs - p_rect_margin) * p_data->scale / p_data->oversampling; chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling; return chr; } @@ -1796,6 +1797,29 @@ bool TextServerAdvanced::font_is_antialiased(const RID &p_font_rid) const { return fd->antialiased; } +void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->mipmaps != p_generate_mipmaps) { + for (KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) { + for (int i = 0; i < E.value->textures.size(); i++) { + E.value->textures.write[i].dirty = true; + } + } + fd->mipmaps = p_generate_mipmaps; + } +} + +bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, false); + + MutexLock lock(fd->mutex); + return fd->mipmaps; +} + void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -2276,6 +2300,9 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } tex.texture = Ref<ImageTexture>(); tex.texture.instantiate(); @@ -2559,6 +2586,86 @@ void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const gl[p_glyph].found = true; } +RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, RID()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size_outline(fd, p_size); + + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), RID()); + if (!_ensure_glyph(fd, size, p_glyph)) { + return RID(); // Invalid or non graphicl glyph, do not display errors. + } + + const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + ERR_FAIL_COND_V(gl[p_glyph].texture_idx < -1 || gl[p_glyph].texture_idx >= fd->cache[size]->textures.size(), RID()); + + if (RenderingServer::get_singleton() != nullptr) { + if (gl[p_glyph].texture_idx != -1) { + if (fd->cache[size]->textures[gl[p_glyph].texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph].texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } + return fd->cache[size]->textures[gl[p_glyph].texture_idx].texture->get_rid(); + } + } + + return RID(); +} + +Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Size2()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size_outline(fd, p_size); + + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Size2()); + if (!_ensure_glyph(fd, size, p_glyph)) { + return Size2(); // Invalid or non graphicl glyph, do not display errors. + } + + const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + ERR_FAIL_COND_V(gl[p_glyph].texture_idx < -1 || gl[p_glyph].texture_idx >= fd->cache[size]->textures.size(), Size2()); + + if (RenderingServer::get_singleton() != nullptr) { + if (gl[p_glyph].texture_idx != -1) { + if (fd->cache[size]->textures[gl[p_glyph].texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph].texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } + return fd->cache[size]->textures[gl[p_glyph].texture_idx].texture->get_size(); + } + } + + return Size2(); +} + Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); @@ -2865,6 +2972,9 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } if (tex.texture.is_null()) { tex.texture.instantiate(); tex.texture->create_from_image(img); @@ -2941,6 +3051,9 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } if (tex.texture.is_null()) { tex.texture.instantiate(); tex.texture->create_from_image(img); @@ -3304,7 +3417,9 @@ void TextServerAdvanced::shaped_text_set_bidi_override(const RID &p_shaped, cons } sd->bidi_override.clear(); for (int i = 0; i < p_override.size(); i++) { - sd->bidi_override.push_back(p_override[i]); + if (p_override[i].get_type() == Variant::VECTOR2I) { + sd->bidi_override.push_back(p_override[i]); + } } invalidate(sd, false); } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 8afba6adca..fa59566a94 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -216,6 +216,7 @@ class TextServerAdvanced : public TextServerExtension { Mutex mutex; bool antialiased = true; + bool mipmaps = false; bool msdf = false; int msdf_range = 14; int msdf_source_size = 48; @@ -483,6 +484,9 @@ public: virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override; virtual bool font_is_antialiased(const RID &p_font_rid) const override; + virtual void font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) override; + virtual bool font_get_generate_mipmaps(const RID &p_font_rid) const override; + virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override; virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override; @@ -567,6 +571,9 @@ public: virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override; + virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; |