Просмотр исходного кода

Added font oversampling support

Juan Linietsky 7 лет назад
Родитель
Сommit
fc103566e6

+ 4 - 0
main/main.cpp

@@ -1448,6 +1448,9 @@ bool Main::start() {
 			bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
 			sml->get_root()->set_snap_controls_to_pixels(snap_controls);
 
+			bool font_oversampling = GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", false);
+			sml->set_use_font_oversampling(font_oversampling);
+
 		} else {
 			GLOBAL_DEF("display/window/stretch/mode", "disabled");
 			ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
@@ -1458,6 +1461,7 @@ bool Main::start() {
 			sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
 			sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
 			GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
+			GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", false);
 		}
 
 		String local_game_path;

+ 1 - 1
scene/gui/label.cpp

@@ -207,7 +207,7 @@ void Label::_notification(int p_what) {
 				} break;
 			}
 
-			int y_ofs = style->get_offset().y;
+			float y_ofs = style->get_offset().y;
 			y_ofs += (line - lines_skipped) * font_h + font->get_ascent();
 			y_ofs += vbegin + line * vsep;
 

+ 24 - 0
scene/main/scene_tree.cpp

@@ -38,6 +38,7 @@
 #include "os/os.h"
 #include "print_string.h"
 #include "project_settings.h"
+#include "scene/resources/dynamic_font.h"
 #include "scene/resources/material.h"
 #include "scene/resources/mesh.h"
 #include "scene/resources/packed_scene.h"
@@ -495,6 +496,10 @@ bool SceneTree::idle(float p_time) {
 	Size2 win_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height);
 	if (win_size != last_screen_size) {
 
+		if (use_font_oversampling) {
+			DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width;
+		}
+
 		last_screen_size = win_size;
 		_update_root_rect();
 
@@ -2195,6 +2200,9 @@ void SceneTree::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_connection_failed"), &SceneTree::_connection_failed);
 	ClassDB::bind_method(D_METHOD("_server_disconnected"), &SceneTree::_server_disconnected);
 
+	ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &SceneTree::set_use_font_oversampling);
+	ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &SceneTree::is_using_font_oversampling);
+
 	ADD_SIGNAL(MethodInfo("tree_changed"));
 	ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node")));
 	ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node")));
@@ -2244,6 +2252,20 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) {
 	idle_callbacks[idle_callback_count++] = p_callback;
 }
 
+void SceneTree::set_use_font_oversampling(bool p_oversampling) {
+
+	use_font_oversampling = p_oversampling;
+	if (use_font_oversampling) {
+		DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width;
+	} else {
+		DynamicFontAtSize::font_oversampling = 1.0;
+	}
+}
+
+bool SceneTree::is_using_font_oversampling() const {
+	return use_font_oversampling;
+}
+
 SceneTree::SceneTree() {
 
 	singleton = this;
@@ -2380,6 +2402,8 @@ SceneTree::SceneTree() {
 	last_send_cache_id = 1;
 
 #endif
+
+	use_font_oversampling = false;
 }
 
 SceneTree::~SceneTree() {

+ 5 - 0
scene/main/scene_tree.h

@@ -122,11 +122,13 @@ private:
 	bool _quit;
 	bool initialized;
 	bool input_handled;
+
 	Size2 last_screen_size;
 	StringName tree_changed_name;
 	StringName node_added_name;
 	StringName node_removed_name;
 
+	bool use_font_oversampling;
 	int64_t current_frame;
 	int node_count;
 
@@ -420,6 +422,9 @@ public:
 
 	void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink = 1);
 
+	void set_use_font_oversampling(bool p_oversampling);
+	bool is_using_font_oversampling() const;
+
 	//void change_scene(const String& p_path);
 	//Node *get_loaded_scene();
 

+ 19 - 13
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,13 +604,16 @@ 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));
 
@@ -623,6 +628,7 @@ DynamicFontAtSize::DynamicFontAtSize() {
 	descent = 1;
 	linegap = 1;
 	texture_flags = 0;
+	oversampling = font_oversampling;
 }
 
 DynamicFontAtSize::~DynamicFontAtSize() {

+ 8 - 5
scene/resources/dynamic_font.h

@@ -97,10 +97,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 +122,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 +147,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;