diff options
Diffstat (limited to 'scene/resources/dynamic_font.cpp')
-rw-r--r-- | scene/resources/dynamic_font.cpp | 263 |
1 files changed, 159 insertions, 104 deletions
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index eea4d12d0e..d76d364737 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -46,7 +46,6 @@ bool DynamicFontData::CacheID::operator<(CacheID right) const { } Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cache_id) { - if (size_cache.has(p_cache_id)) { return Ref<DynamicFontAtSize>(size_cache[p_cache_id]); } @@ -65,13 +64,11 @@ Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cach } void DynamicFontData::set_font_ptr(const uint8_t *p_font_mem, int p_font_mem_size) { - font_mem = p_font_mem; font_mem_size = p_font_mem_size; } void DynamicFontData::set_font_path(const String &p_path) { - font_path = p_path; } @@ -80,7 +77,6 @@ String DynamicFontData::get_font_path() const { } void DynamicFontData::set_force_autohinter(bool p_force) { - force_autohinter = p_force; } @@ -103,7 +99,6 @@ void DynamicFontData::_bind_methods() { } DynamicFontData::DynamicFontData() { - antialiased = true; force_autohinter = false; hinting = DynamicFontData::HINTING_NORMAL; @@ -118,7 +113,6 @@ DynamicFontData::~DynamicFontData() { HashMap<String, Vector<uint8_t>> DynamicFontAtSize::_fontdata; Error DynamicFontAtSize::_load() { - int error = FT_Init_FreeType(&library); ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType."); @@ -127,11 +121,9 @@ Error DynamicFontAtSize::_load() { if (OS::get_singleton()->get_name() == "Android" && font->font_mem == nullptr && font->font_path != String()) { // cache font only once for each font->font_path if (_fontdata.has(font->font_path)) { - font->set_font_ptr(_fontdata[font->font_path].ptr(), _fontdata[font->font_path].size()); } else { - FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ); if (!f) { FT_Done_FreeType(library); @@ -149,7 +141,6 @@ Error DynamicFontAtSize::_load() { } if (font->font_mem == nullptr && font->font_path != String()) { - FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ); if (!f) { FT_Done_FreeType(library); @@ -170,7 +161,6 @@ Error DynamicFontAtSize::_load() { fargs.stream = &stream; error = FT_Open_Face(library, &fargs, 0, &face); } else if (font->font_mem) { - memset(&stream, 0, sizeof(FT_StreamRec)); stream.base = (unsigned char *)font->font_mem; stream.size = font->font_mem_size; @@ -192,12 +182,10 @@ Error DynamicFontAtSize::_load() { //error = FT_New_Face( library, src_path.utf8().get_data(),0,&face ); if (error == FT_Err_Unknown_File_Format) { - FT_Done_FreeType(library); ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Unknown font format."); } else if (error) { - FT_Done_FreeType(library); ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Error loading font."); } @@ -221,6 +209,8 @@ Error DynamicFontAtSize::_load() { ascent = (face->size->metrics.ascender / 64.0) / oversampling * scale_color_font; descent = (-face->size->metrics.descender / 64.0) / oversampling * scale_color_font; + underline_position = -face->underline_position / 64.0 / oversampling * scale_color_font; + underline_thickness = face->underline_thickness / 64.0 / oversampling * scale_color_font; linegap = 0; valid = true; @@ -230,38 +220,44 @@ Error DynamicFontAtSize::_load() { float DynamicFontAtSize::font_oversampling = 1.0; float DynamicFontAtSize::get_height() const { - return ascent + descent; } float DynamicFontAtSize::get_ascent() const { - return ascent; } -float DynamicFontAtSize::get_descent() const { +float DynamicFontAtSize::get_descent() const { return descent; } -const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { +float DynamicFontAtSize::get_underline_position() const { + return underline_position; +} + +float DynamicFontAtSize::get_underline_thickness() const { + return underline_thickness; +} + +const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { const Character *chr = char_map.getptr(p_char); ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(nullptr, nullptr))); if (!chr->found) { - //not found, try in fallbacks for (int i = 0; i < p_fallbacks.size(); i++) { - DynamicFontAtSize *fb = const_cast<DynamicFontAtSize *>(p_fallbacks[i].ptr()); - if (!fb->valid) + if (!fb->valid) { continue; + } fb->_update_char(p_char); const Character *fallback_chr = fb->char_map.getptr(p_char); ERR_CONTINUE(!fallback_chr); - if (!fallback_chr->found) + if (!fallback_chr->found) { continue; + } return Pair<const Character *, DynamicFontAtSize *>(fallback_chr, fb); } @@ -275,10 +271,10 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this)); } -Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { - - if (!valid) +Size2 DynamicFontAtSize::get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { + if (!valid) { return Size2(1, 1); + } const_cast<DynamicFontAtSize *>(this)->_update_char(p_char); Pair<const Character *, DynamicFontAtSize *> char_pair_with_font = _find_char_with_font(p_char, p_fallbacks); @@ -294,10 +290,25 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V return ret; } -float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const { +String DynamicFontAtSize::get_available_chars() const { + String chars; + + FT_UInt gindex; + FT_ULong charcode = FT_Get_First_Char(face, &gindex); + while (gindex != 0) { + if (charcode != 0) { + chars += char32_t(charcode); + } + charcode = FT_Get_Next_Char(face, charcode, &gindex); + } + + return chars; +} - if (!valid) +float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const { + if (!valid) { return 0; + } const_cast<DynamicFontAtSize *>(this)->_update_char(p_char); @@ -336,7 +347,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT modulate.r = modulate.g = modulate.b = 1.0; } RID texture = font->textures[ch->texture_idx].texture->get_rid(); - RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), RID(), Color(1, 1, 1, 1), false); + RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, false); } advance = ch->advance; @@ -346,20 +357,20 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT } unsigned long DynamicFontAtSize::_ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { - FileAccess *f = (FileAccess *)stream->descriptor.pointer; if (f->get_position() != offset) { f->seek(offset); } - if (count == 0) + if (count == 0) { return 0; + } return f->get_buffer(buffer, count); } -void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) { +void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) { FileAccess *f = (FileAccess *)stream->descriptor.pointer; f->close(); memdelete(f); @@ -385,27 +396,27 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp int mh = p_height; for (int i = 0; i < textures.size(); i++) { - const CharTexture &ct = textures[i]; - if (ct.texture->get_format() != p_image_format) + if (ct.texture->get_format() != p_image_format) { continue; + } - if (mw > ct.texture_size || mh > ct.texture_size) //too big for this texture + if (mw > ct.texture_size || mh > ct.texture_size) { //too big for this texture continue; + } ret.y = 0x7FFFFFFF; ret.x = 0; for (int j = 0; j < ct.texture_size - mw; j++) { - int max_y = 0; for (int k = j; k < j + mw; k++) { - int y = ct.offsets[k]; - if (y > max_y) + if (y > max_y) { max_y = y; + } } if (max_y < ret.y) { @@ -414,8 +425,9 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp } } - if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size) + if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size) { continue; //fail, could not fit it here + } ret.index = i; break; @@ -427,10 +439,12 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp ret.y = 0; int texsize = MAX(id.size * oversampling * 8, 256); - if (mw > texsize) + if (mw > texsize) { texsize = mw; //special case, adapt to it? - if (mh > texsize) + } + if (mh > texsize) { texsize = mh; //special case, adapt to it? + } texsize = next_power_of_2(texsize); @@ -444,13 +458,27 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp //zero texture uint8_t *w = tex.imgdata.ptrw(); ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.imgdata.size(), ret); - for (int i = 0; i < texsize * texsize * p_color_size; i++) { - w[i] = 0; + + // Initialize the texture to all-white pixels to prevent artifacts when the + // font is displayed at a non-default scale with filtering enabled. + if (p_color_size == 2) { + for (int i = 0; i < texsize * texsize * p_color_size; i += 2) { + w[i + 0] = 255; + w[i + 1] = 0; + } + } else { + for (int i = 0; i < texsize * texsize * p_color_size; i += 4) { + w[i + 0] = 255; + w[i + 1] = 255; + w[i + 2] = 255; + w[i + 3] = 0; + } } } tex.offsets.resize(texsize); - for (int i = 0; i < texsize; i++) //zero offsets + for (int i = 0; i < texsize; i++) { //zero offsets tex.offsets.write[i] = 0; + } textures.push_back(tex); ret.index = textures.size() - 1; @@ -484,7 +512,6 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + rect_margin) * tex.texture_size + j + tex_pos.x + rect_margin) * color_size; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), Character::not_found()); switch (bitmap.pixel_mode) { @@ -516,7 +543,6 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b //blit to image and texture { - Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, require_format, tex.imgdata)); if (tex.texture.is_null()) { @@ -547,26 +573,31 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b return chr; } -DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_char) { +DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(char32_t p_char) { Character ret = Character::not_found(); - if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0) + if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0) { return ret; + } FT_Stroker stroker; - if (FT_Stroker_New(library, &stroker) != 0) + if (FT_Stroker_New(library, &stroker) != 0) { return ret; + } FT_Stroker_Set(stroker, (int)(id.outline_size * oversampling * 64.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0); FT_Glyph glyph; FT_BitmapGlyph glyph_bitmap; - if (FT_Get_Glyph(face->glyph, &glyph) != 0) + if (FT_Get_Glyph(face->glyph, &glyph) != 0) { goto cleanup_stroker; - if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) + } + if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) { goto cleanup_glyph; - if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, nullptr, 1) != 0) + } + if (FT_Glyph_To_Bitmap(&glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, nullptr, 1) != 0) { goto cleanup_glyph; + } glyph_bitmap = (FT_BitmapGlyph)glyph; ret = _bitmap_to_character(glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, glyph->advance.x / 65536.0); @@ -578,10 +609,10 @@ cleanup_stroker: return ret; } -void DynamicFontAtSize::_update_char(CharType p_char) { - - if (char_map.has(p_char)) +void DynamicFontAtSize::_update_char(char32_t p_char) { + if (char_map.has(p_char)) { return; + } _THREAD_SAFE_METHOD_ @@ -618,16 +649,18 @@ void DynamicFontAtSize::_update_char(CharType p_char) { character = _make_outline_char(p_char); } else { error = FT_Render_Glyph(face->glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); - if (!error) + if (!error) { character = _bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0); + } } char_map[p_char] = character; } void DynamicFontAtSize::update_oversampling() { - if (oversampling == font_oversampling || !valid) + if (oversampling == font_oversampling || !valid) { return; + } FT_Done_FreeType(library); textures.clear(); @@ -638,7 +671,6 @@ void DynamicFontAtSize::update_oversampling() { } DynamicFontAtSize::DynamicFontAtSize() { - valid = false; rect_margin = 1; ascent = 1; @@ -649,7 +681,6 @@ DynamicFontAtSize::DynamicFontAtSize() { } DynamicFontAtSize::~DynamicFontAtSize() { - if (valid) { FT_Done_FreeType(library); } @@ -660,7 +691,6 @@ DynamicFontAtSize::~DynamicFontAtSize() { ///////////////////////// void DynamicFont::_reload_cache() { - ERR_FAIL_COND(cache_id.size < 1); if (!data.is_valid()) { data_at_size.unref(); @@ -682,8 +712,9 @@ void DynamicFont::_reload_cache() { for (int i = 0; i < fallbacks.size(); i++) { fallback_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(cache_id); - if (outline_cache_id.outline_size > 0) + if (outline_cache_id.outline_size > 0) { fallback_outline_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(outline_cache_id); + } } emit_changed(); @@ -691,7 +722,6 @@ void DynamicFont::_reload_cache() { } void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) { - data = p_data; _reload_cache(); @@ -700,27 +730,26 @@ void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) { } Ref<DynamicFontData> DynamicFont::get_font_data() const { - return data; } void DynamicFont::set_size(int p_size) { - - if (cache_id.size == p_size) + if (cache_id.size == p_size) { return; + } cache_id.size = p_size; outline_cache_id.size = p_size; _reload_cache(); } int DynamicFont::get_size() const { - return cache_id.size; } void DynamicFont::set_outline_size(int p_size) { - if (outline_cache_id.outline_size == p_size) + if (outline_cache_id.outline_size == p_size) { return; + } ERR_FAIL_COND(p_size < 0 || p_size > UINT8_MAX); outline_cache_id.outline_size = p_size; _reload_cache(); @@ -743,31 +772,28 @@ Color DynamicFont::get_outline_color() const { } bool DynamicFontData::is_antialiased() const { - return antialiased; } void DynamicFontData::set_antialiased(bool p_antialiased) { - - if (antialiased == p_antialiased) + if (antialiased == p_antialiased) { return; + } antialiased = p_antialiased; } DynamicFontData::Hinting DynamicFontData::get_hinting() const { - return hinting; } void DynamicFontData::set_hinting(Hinting p_hinting) { - - if (hinting == p_hinting) + if (hinting == p_hinting) { return; + } hinting = p_hinting; } int DynamicFont::get_spacing(int p_type) const { - if (p_type == SPACING_TOP) { return spacing_top; } else if (p_type == SPACING_BOTTOM) { @@ -782,7 +808,6 @@ int DynamicFont::get_spacing(int p_type) const { } void DynamicFont::set_spacing(int p_type, int p_value) { - if (p_type == SPACING_TOP) { spacing_top = p_value; } else if (p_type == SPACING_BOTTOM) { @@ -798,45 +823,80 @@ void DynamicFont::set_spacing(int p_type, int p_value) { } float DynamicFont::get_height() const { - - if (!data_at_size.is_valid()) + if (!data_at_size.is_valid()) { return 1; + } return data_at_size->get_height() + spacing_top + spacing_bottom; } float DynamicFont::get_ascent() const { - - if (!data_at_size.is_valid()) + if (!data_at_size.is_valid()) { return 1; + } return data_at_size->get_ascent() + spacing_top; } float DynamicFont::get_descent() const { - - if (!data_at_size.is_valid()) + if (!data_at_size.is_valid()) { return 1; + } return data_at_size->get_descent() + spacing_bottom; } -Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const { +float DynamicFont::get_underline_position() const { + if (!data_at_size.is_valid()) { + return 2; + } + + return data_at_size->get_underline_position(); +} + +float DynamicFont::get_underline_thickness() const { + if (!data_at_size.is_valid()) { + return 1; + } + + return data_at_size->get_underline_thickness(); +} - if (!data_at_size.is_valid()) +Size2 DynamicFont::get_char_size(char32_t p_char, char32_t p_next) const { + if (!data_at_size.is_valid()) { return Size2(1, 1); + } Size2 ret = data_at_size->get_char_size(p_char, p_next, fallback_data_at_size); - if (p_char == ' ') + if (p_char == ' ') { ret.width += spacing_space + spacing_char; - else if (p_next) + } else if (p_next) { ret.width += spacing_char; + } return ret; } -bool DynamicFont::is_distance_field_hint() const { +String DynamicFont::get_available_chars() const { + if (!data_at_size.is_valid()) { + return ""; + } + + String chars = data_at_size->get_available_chars(); + for (int i = 0; i < fallback_data_at_size.size(); i++) { + String fallback_chars = fallback_data_at_size[i]->get_available_chars(); + for (int j = 0; j < fallback_chars.length(); j++) { + if (chars.find_char(fallback_chars[j]) == -1) { + chars += fallback_chars[j]; + } + } + } + + return chars; +} + +bool DynamicFont::is_distance_field_hint() const { return false; } @@ -844,11 +904,12 @@ bool DynamicFont::has_outline() const { return outline_cache_id.outline_size > 0; } -float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const { +float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const { const Ref<DynamicFontAtSize> &font_at_size = p_outline && outline_cache_id.outline_size > 0 ? outline_data_at_size : data_at_size; - if (!font_at_size.is_valid()) + if (!font_at_size.is_valid()) { return 0; + } const Vector<Ref<DynamicFontAtSize>> &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size; Color color = p_outline && outline_cache_id.outline_size > 0 ? p_modulate * outline_color : p_modulate; @@ -859,7 +920,6 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_ } void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) { - ERR_FAIL_COND(p_data.is_null()); ERR_FAIL_INDEX(p_idx, fallbacks.size()); fallbacks.write[p_idx] = p_data; @@ -867,12 +927,12 @@ void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) { } void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) { - ERR_FAIL_COND(p_data.is_null()); fallbacks.push_back(p_data); fallback_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(cache_id)); //const.. - if (outline_cache_id.outline_size > 0) + if (outline_cache_id.outline_size > 0) { fallback_outline_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(outline_cache_id)); + } _change_notify(); emit_changed(); @@ -882,14 +942,14 @@ void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) { int DynamicFont::get_fallback_count() const { return fallbacks.size(); } -Ref<DynamicFontData> DynamicFont::get_fallback(int p_idx) const { +Ref<DynamicFontData> DynamicFont::get_fallback(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, fallbacks.size(), Ref<DynamicFontData>()); return fallbacks[p_idx]; } -void DynamicFont::remove_fallback(int p_idx) { +void DynamicFont::remove_fallback(int p_idx) { ERR_FAIL_INDEX(p_idx, fallbacks.size()); fallbacks.remove(p_idx); fallback_data_at_size.remove(p_idx); @@ -898,7 +958,6 @@ void DynamicFont::remove_fallback(int p_idx) { } bool DynamicFont::_set(const StringName &p_name, const Variant &p_value) { - String str = p_name; if (str.begins_with("fallback/")) { int idx = str.get_slicec('/', 1).to_int(); @@ -924,7 +983,6 @@ bool DynamicFont::_set(const StringName &p_name, const Variant &p_value) { } bool DynamicFont::_get(const StringName &p_name, Variant &r_ret) const { - String str = p_name; if (str.begins_with("fallback/")) { int idx = str.get_slicec('/', 1).to_int(); @@ -940,8 +998,8 @@ bool DynamicFont::_get(const StringName &p_name, Variant &r_ret) const { return false; } -void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const { +void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < fallbacks.size(); i++) { p_list->push_back(PropertyInfo(Variant::OBJECT, "fallback/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "DynamicFontData")); } @@ -950,10 +1008,11 @@ void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const { } void DynamicFont::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_font_data", "data"), &DynamicFont::set_font_data); ClassDB::bind_method(D_METHOD("get_font_data"), &DynamicFont::get_font_data); + ClassDB::bind_method(D_METHOD("get_available_chars"), &DynamicFont::get_available_chars); + ClassDB::bind_method(D_METHOD("set_size", "data"), &DynamicFont::set_size); ClassDB::bind_method(D_METHOD("get_size"), &DynamicFont::get_size); @@ -996,7 +1055,6 @@ SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = nullptr; DynamicFont::DynamicFont() : font_list(this) { - valid = false; cache_id.size = 16; outline_cache_id.size = 16; @@ -1025,14 +1083,12 @@ void DynamicFont::finish_dynamic_fonts() { } void DynamicFont::update_oversampling() { - Vector<Ref<DynamicFont>> changed; { MutexLock lock(dynamic_font_mutex); SelfList<DynamicFont> *E = dynamic_fonts->first(); while (E) { - if (E->self()->data_at_size.is_valid()) { E->self()->data_at_size->update_oversampling(); @@ -1065,36 +1121,35 @@ void DynamicFont::update_oversampling() { ///////////////////////// RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { - - if (r_error) + if (r_error) { *r_error = ERR_FILE_CANT_OPEN; + } Ref<DynamicFontData> dfont; dfont.instance(); dfont->set_font_path(p_path); - if (r_error) + if (r_error) { *r_error = OK; + } return dfont; } void ResourceFormatLoaderDynamicFont::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("ttf"); p_extensions->push_back("otf"); } bool ResourceFormatLoaderDynamicFont::handles_type(const String &p_type) const { - return (p_type == "DynamicFontData"); } String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const { - String el = p_path.get_extension().to_lower(); - if (el == "ttf" || el == "otf") + if (el == "ttf" || el == "otf") { return "DynamicFontData"; + } return ""; } |