summaryrefslogtreecommitdiff
path: root/scene/resources/dynamic_font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/dynamic_font.cpp')
-rw-r--r--scene/resources/dynamic_font.cpp263
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 "";
}