diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/dynamic_font.cpp | 86 | ||||
-rw-r--r-- | scene/resources/dynamic_font.h | 24 | ||||
-rw-r--r-- | scene/resources/font.cpp | 4 |
3 files changed, 93 insertions, 21 deletions
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index a40417f24d..66b1e49d13 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -191,10 +191,10 @@ Error DynamicFontAtSize::_load() { ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER ); }*/ - error = FT_Set_Pixel_Sizes(face, 0, id.size); + error = FT_Set_Pixel_Sizes(face, 0, id.size * oversampling); - ascent = face->size->metrics.ascender >> 6; - descent = -face->size->metrics.descender >> 6; + ascent = (face->size->metrics.ascender >> 6) / oversampling; + descent = (-face->size->metrics.descender >> 6) / oversampling; linegap = 0; texture_flags = 0; if (id.mipmaps) @@ -208,6 +208,8 @@ Error DynamicFontAtSize::_load() { return OK; } +float DynamicFontAtSize::font_oversampling = 1.0; + float DynamicFontAtSize::get_height() const { return ascent + descent; @@ -282,11 +284,11 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V if (delta.x == 0) continue; - ret.x += delta.x >> 6; + ret.x += (delta.x >> 6) / oversampling; break; } } else { - ret.x += delta.x >> 6; + ret.x += (delta.x >> 6) / oversampling; } } @@ -338,7 +340,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT cpos.y += ch->v_align; ERR_FAIL_COND_V(ch->texture_idx < -1 || ch->texture_idx >= fb->textures.size(), 0); if (ch->texture_idx != -1) - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), fb->textures[ch->texture_idx].texture->get_rid(), ch->rect, p_modulate, false, RID(), false); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), fb->textures[ch->texture_idx].texture->get_rid(), ch->rect_uv, p_modulate, false, RID(), false); advance = ch->advance; used_fallback = true; break; @@ -360,7 +362,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT cpos.y += c->v_align; ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), 0); if (c->texture_idx != -1) - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx].texture->get_rid(), c->rect, p_modulate, false, RID(), false); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx].texture->get_rid(), c->rect_uv, p_modulate, false, RID(), false); advance = c->advance; //textures[c->texture_idx].texture->draw(p_canvas_item,Vector2()); } @@ -382,11 +384,11 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT if (delta.x == 0) continue; - advance += delta.x >> 6; + advance += (delta.x >> 6) / oversampling; break; } } else { - advance += delta.x >> 6; + advance += (delta.x >> 6) / oversampling; } } @@ -602,19 +604,37 @@ void DynamicFontAtSize::_update_char(CharType p_char) { } Character chr; - chr.h_align = xofs; - chr.v_align = ascent - yofs; // + ascent - descent; - chr.advance = advance; + chr.h_align = xofs / oversampling; + chr.v_align = ascent - (yofs / oversampling); // + ascent - descent; + chr.advance = advance / oversampling; chr.texture_idx = tex_index; chr.found = true; - chr.rect = Rect2(tex_x + rect_margin, tex_y + rect_margin, w, h); + chr.rect_uv = Rect2(tex_x + rect_margin, tex_y + rect_margin, w, h); + chr.rect = chr.rect_uv; + chr.rect.position /= oversampling; + chr.rect.size /= oversampling; //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" RECT: "+chr.rect+" X OFS: "+itos(xofs)+" Y OFS: "+itos(yofs)); char_map[p_char] = chr; } +bool DynamicFontAtSize::update_oversampling() { + if (oversampling == font_oversampling) + return false; + if (!valid) + return false; + + FT_Done_FreeType(library); + textures.clear(); + char_map.clear(); + oversampling = font_oversampling; + _load(); + + return true; +} + DynamicFontAtSize::DynamicFontAtSize() { valid = false; @@ -623,6 +643,7 @@ DynamicFontAtSize::DynamicFontAtSize() { descent = 1; linegap = 1; texture_flags = 0; + oversampling = font_oversampling; } DynamicFontAtSize::~DynamicFontAtSize() { @@ -913,15 +934,52 @@ void DynamicFont::_bind_methods() { BIND_ENUM_CONSTANT(SPACING_SPACE); } -DynamicFont::DynamicFont() { +Mutex *DynamicFont::dynamic_font_mutex = NULL; + +SelfList<DynamicFont>::List DynamicFont::dynamic_fonts; + +DynamicFont::DynamicFont() : + font_list(this) { spacing_top = 0; spacing_bottom = 0; spacing_char = 0; spacing_space = 0; + if (dynamic_font_mutex) + dynamic_font_mutex->lock(); + dynamic_fonts.add(&font_list); + if (dynamic_font_mutex) + dynamic_font_mutex->unlock(); } DynamicFont::~DynamicFont() { + + if (dynamic_font_mutex) + dynamic_font_mutex->lock(); + dynamic_fonts.remove(&font_list); + if (dynamic_font_mutex) + dynamic_font_mutex->unlock(); +} + +void DynamicFont::initialize_dynamic_fonts() { + dynamic_font_mutex = Mutex::create(); +} + +void DynamicFont::finish_dynamic_fonts() { + memdelete(dynamic_font_mutex); + dynamic_font_mutex = NULL; +} + +void DynamicFont::update_oversampling() { + + SelfList<DynamicFont> *E = dynamic_fonts.first(); + while (E) { + + if (E->self()->data_at_size.is_valid() && E->self()->data_at_size->update_oversampling()) { + E->self()->emit_changed(); + } + E = E->next(); + } } ///////////////////////// diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 52c3f30590..b2452a6a0a 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -32,6 +32,7 @@ #ifdef FREETYPE_ENABLED #include "io/resource_loader.h" +#include "os/mutex.h" #include "os/thread_safe.h" #include "scene/resources/font.h" @@ -97,10 +98,11 @@ class DynamicFontAtSize : public Reference { FT_Face face; /* handle to face object */ FT_StreamRec stream; - int ascent; - int descent; - int linegap; - int rect_margin; + float ascent; + float descent; + float linegap; + float rect_margin; + float oversampling; uint32_t texture_flags; @@ -121,6 +123,7 @@ class DynamicFontAtSize : public Reference { bool found; int texture_idx; Rect2 rect; + Rect2 rect_uv; float v_align; float h_align; float advance; @@ -145,8 +148,9 @@ class DynamicFontAtSize : public Reference { static HashMap<String, Vector<uint8_t> > _fontdata; Error _load(); -protected: public: + static float font_oversampling; + float get_height() const; float get_ascent() const; @@ -157,6 +161,7 @@ public: float 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) const; void set_texture_flags(uint32_t p_flags); + bool update_oversampling(); DynamicFontAtSize(); ~DynamicFontAtSize(); @@ -232,6 +237,15 @@ public: virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1)) const; + SelfList<DynamicFont> font_list; + + static Mutex *dynamic_font_mutex; + static SelfList<DynamicFont>::List dynamic_fonts; + + static void initialize_dynamic_fonts(); + static void finish_dynamic_fonts(); + static void update_oversampling(); + DynamicFont(); ~DynamicFont(); }; diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 2b44ea4554..8510669d6c 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -257,8 +257,8 @@ Error BitmapFont::create_from_fnt(const String &p_file) { if (keys.has("file")) { - String file = keys["file"]; - file = p_file.get_base_dir() + "/" + file; + String base_dir = p_file.get_base_dir(); + String file = base_dir.plus_file(keys["file"]); Ref<Texture> tex = ResourceLoader::load(file); if (tex.is_null()) { ERR_PRINT("Can't load font texture!"); |