Przeglądaj źródła

Add LabelSettings resource for quick Label theme property override.

bruvzg 3 lat temu
rodzic
commit
f63d54126d

+ 3 - 0
doc/classes/Label.xml

@@ -49,6 +49,9 @@
 		<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
 			Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
 		</member>
+		<member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings">
+			Resource to override [Theme] font, outline and shadow properties.
+		</member>
 		<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
 			Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
 		</member>

+ 39 - 0
doc/classes/LabelSettings.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="LabelSettings" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+	<brief_description>
+		Resource to override [Theme] font, outline and shadow properties of the [Label].
+	</brief_description>
+	<description>
+	</description>
+	<tutorials>
+	</tutorials>
+	<members>
+		<member name="font" type="Font" setter="set_font" getter="get_font">
+			[Font] of the [Label]'s text.
+		</member>
+		<member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(0.875, 0.875, 0.875, 1)">
+			Default text [Color] of the [Label].
+		</member>
+		<member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16">
+			Font size of the [Label]'s text.
+		</member>
+		<member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0">
+			Vertical space between lines in multiline text.
+		</member>
+		<member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)">
+			The tint of text outline.
+		</member>
+		<member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0">
+			Text outline size.
+		</member>
+		<member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(1, 1, 1, 1)">
+			The tint of text shadow.
+		</member>
+		<member name="shadow_offset" type="Vector2" setter="set_shadow_offset" getter="get_shadow_offset" default="Vector2(1, 1)">
+			The offset of the text's shadow.
+		</member>
+		<member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0">
+			The size of the text's shadow.
+		</member>
+	</members>
+</class>

+ 1 - 0
editor/icons/LabelSettings.svg

@@ -0,0 +1 @@
+<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M6 3a1 1 0 0 0-.707.293l-4 4a1 1 0 0 0 0 1.414l4 4A1 1 0 0 0 6 13h2.076a3.766 3.766 0 0 1-.058-.496c-.003-.058-.006-.115-.006-.174a2.606 2.606 0 0 1 .05-.508 3.212 3.212 0 0 1 .133-.496 5.104 5.104 0 0 1 .451-.982 8.303 8.303 0 0 1 .422-.656 14.41 14.41 0 0 1 .489-.667c.172-.223.351-.45.535-.68.163-.203.327-.408.492-.618a27.639 27.639 0 0 0 .732-.977 16.04 16.04 0 0 0 .465-.697c.075-.12.147-.242.219-.365a12.399 12.399 0 0 0 .684 1.062 27.555 27.555 0 0 0 .73.977c.165.21.331.415.494.619a43.298 43.298 0 0 1 .787 1.013c.082.111.16.222.237.332L15 9.79V4a1 1 0 0 0-1-1H6zM5 7a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" style="fill:#8eef97;fill-opacity:1"/><path d="M9.184 13A2.99 2.99 0 0 0 12 15a2.99 2.99 0 0 0 2.816-2z" fill="#ff4596"/><path d="M9.23 11c-.136.326-.23.656-.23 1 0 .352.072.686.184 1h5.632c.112-.314.184-.648.184-1 0-.344-.094-.674-.23-1H9.23z" fill="#8045ff"/><path d="M10.564 9c-.552.69-1.058 1.342-1.334 2h5.54c-.276-.658-.782-1.31-1.335-2Z" fill="#45d7ff"/><path d="M12 7c-.43.746-.945 1.387-1.435 2h2.87c-.49-.613-1.005-1.254-1.435-2Z" fill="#45ffa2"/></svg>

+ 47 - 18
scene/gui/label.cpp

@@ -31,6 +31,7 @@
 #include "label.h"
 
 #include "core/config/project_settings.h"
+#include "core/core_string_names.h"
 #include "core/string/print_string.h"
 #include "core/string/translation.h"
 
@@ -64,7 +65,7 @@ bool Label::is_uppercase() const {
 }
 
 int Label::get_line_height(int p_line) const {
-	Ref<Font> font = get_theme_font(SNAME("font"));
+	Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
 	if (p_line >= 0 && p_line < lines_rid.size()) {
 		return TS->shaped_text_get_size(lines_rid[p_line]).y;
 	} else if (lines_rid.size() > 0) {
@@ -74,7 +75,8 @@ int Label::get_line_height(int p_line) const {
 		}
 		return h;
 	} else {
-		return font->get_height(get_theme_font_size(SNAME("font_size")));
+		int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
+		return font->get_height(font_size);
 	}
 }
 
@@ -91,8 +93,8 @@ void Label::_shape() {
 		} else {
 			TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction);
 		}
-		const Ref<Font> &font = get_theme_font(SNAME("font"));
-		int font_size = get_theme_font_size(SNAME("font_size"));
+		const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+		int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
 		ERR_FAIL_COND(font.is_null());
 		String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
 		if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
@@ -223,9 +225,8 @@ void Label::_shape() {
 }
 
 void Label::_update_visible() {
-	int line_spacing = get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
+	int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
 	Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label"));
-	Ref<Font> font = get_theme_font(SNAME("font"));
 	int lines_visible = lines_rid.size();
 
 	if (max_lines_visible >= 0 && lines_visible > max_lines_visible) {
@@ -295,17 +296,19 @@ void Label::_notification(int p_what) {
 
 			RID ci = get_canvas_item();
 
+			bool has_settings = settings.is_valid();
+
 			Size2 string_size;
 			Size2 size = get_size();
 			Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
-			Ref<Font> font = get_theme_font(SNAME("font"));
-			Color font_color = get_theme_color(SNAME("font_color"));
-			Color font_shadow_color = get_theme_color(SNAME("font_shadow_color"));
-			Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
-			int line_spacing = get_theme_constant(SNAME("line_spacing"));
-			Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
-			int outline_size = get_theme_constant(SNAME("outline_size"));
-			int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size"));
+			Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+			Color font_color = has_settings ? settings->get_font_color() : get_theme_color(SNAME("font_color"));
+			Color font_shadow_color = has_settings ? settings->get_shadow_color() : get_theme_color(SNAME("font_shadow_color"));
+			Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
+			int line_spacing = has_settings ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
+			Color font_outline_color = has_settings ? settings->get_outline_color() : get_theme_color(SNAME("font_outline_color"));
+			int outline_size = has_settings ? settings->get_outline_size() : get_theme_constant(SNAME("outline_size"));
+			int shadow_outline_size = has_settings ? settings->get_shadow_size() : get_theme_constant(SNAME("shadow_outline_size"));
 			bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL);
 			bool rtl_layout = is_layout_rtl();
 
@@ -552,8 +555,10 @@ Size2 Label::get_minimum_size() const {
 
 	Size2 min_size = minsize;
 
-	Ref<Font> font = get_theme_font(SNAME("font"));
-	min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size"))));
+	const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+	int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
+
+	min_size.height = MAX(min_size.height, font->get_height(font_size) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM));
 
 	Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size();
 	if (autowrap_mode != TextServer::AUTOWRAP_OFF) {
@@ -578,9 +583,8 @@ int Label::get_line_count() const {
 }
 
 int Label::get_visible_line_count() const {
-	Ref<Font> font = get_theme_font(SNAME("font"));
 	Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
-	int line_spacing = get_theme_constant(SNAME("line_spacing"));
+	int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
 	int lines_visible = 0;
 	float total_h = 0.0;
 	for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
@@ -641,6 +645,28 @@ void Label::set_text(const String &p_string) {
 	update_minimum_size();
 }
 
+void Label::_invalidate() {
+	font_dirty = true;
+	update();
+}
+
+void Label::set_label_settings(const Ref<LabelSettings> &p_settings) {
+	if (settings != p_settings) {
+		if (settings.is_valid()) {
+			settings->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate));
+		}
+		settings = p_settings;
+		if (settings.is_valid()) {
+			settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), varray(), CONNECT_REFERENCE_COUNTED);
+		}
+		_invalidate();
+	}
+}
+
+Ref<LabelSettings> Label::get_label_settings() const {
+	return settings;
+}
+
 void Label::set_text_direction(Control::TextDirection p_text_direction) {
 	ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
 	if (text_direction != p_text_direction) {
@@ -804,6 +830,8 @@ void Label::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment);
 	ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text);
 	ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text);
+	ClassDB::bind_method(D_METHOD("set_label_settings", "settings"), &Label::set_label_settings);
+	ClassDB::bind_method(D_METHOD("get_label_settings"), &Label::get_label_settings);
 	ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction);
 	ClassDB::bind_method(D_METHOD("get_text_direction"), &Label::get_text_direction);
 	ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language);
@@ -836,6 +864,7 @@ void Label::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options);
 
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "label_settings", PROPERTY_HINT_RESOURCE_TYPE, "LabelSettings"), "set_label_settings", "get_label_settings");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");

+ 7 - 0
scene/gui/label.h

@@ -32,6 +32,7 @@
 #define LABEL_H
 
 #include "scene/gui/control.h"
+#include "scene/resources/label_settings.h"
 
 class Label : public Control {
 	GDCLASS(Label, Control);
@@ -65,8 +66,11 @@ private:
 	int lines_skipped = 0;
 	int max_lines_visible = -1;
 
+	Ref<LabelSettings> settings;
+
 	void _update_visible();
 	void _shape();
+	void _invalidate();
 
 protected:
 	void _notification(int p_what);
@@ -85,6 +89,9 @@ public:
 	void set_text(const String &p_string);
 	String get_text() const;
 
+	void set_label_settings(const Ref<LabelSettings> &p_settings);
+	Ref<LabelSettings> get_label_settings() const;
+
 	void set_text_direction(TextDirection p_text_direction);
 	TextDirection get_text_direction() const;
 

+ 3 - 0
scene/register_scene_types.cpp

@@ -159,6 +159,7 @@
 #include "scene/resources/gradient.h"
 #include "scene/resources/height_map_shape_3d.h"
 #include "scene/resources/immediate_mesh.h"
+#include "scene/resources/label_settings.h"
 #include "scene/resources/material.h"
 #include "scene/resources/mesh.h"
 #include "scene/resources/mesh_data_tool.h"
@@ -860,6 +861,8 @@ void register_scene_types() {
 
 	GDREGISTER_CLASS(Curve);
 
+	GDREGISTER_CLASS(LabelSettings);
+
 	GDREGISTER_CLASS(SceneReplicationConfig);
 
 	GDREGISTER_CLASS(TextLine);

+ 187 - 0
scene/resources/label_settings.cpp

@@ -0,0 +1,187 @@
+/*************************************************************************/
+/*  label_settings.cpp                                                   */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "label_settings.h"
+
+#include "core/core_string_names.h"
+
+void LabelSettings::_font_changed() {
+	emit_changed();
+}
+
+void LabelSettings::_bind_methods() {
+	ClassDB::bind_method(D_METHOD("set_line_spacing", "spacing"), &LabelSettings::set_line_spacing);
+	ClassDB::bind_method(D_METHOD("get_line_spacing"), &LabelSettings::get_line_spacing);
+
+	ClassDB::bind_method(D_METHOD("set_font", "font"), &LabelSettings::set_font);
+	ClassDB::bind_method(D_METHOD("get_font"), &LabelSettings::get_font);
+
+	ClassDB::bind_method(D_METHOD("set_font_size", "size"), &LabelSettings::set_font_size);
+	ClassDB::bind_method(D_METHOD("get_font_size"), &LabelSettings::get_font_size);
+
+	ClassDB::bind_method(D_METHOD("set_font_color", "color"), &LabelSettings::set_font_color);
+	ClassDB::bind_method(D_METHOD("get_font_color"), &LabelSettings::get_font_color);
+
+	ClassDB::bind_method(D_METHOD("set_outline_size", "size"), &LabelSettings::set_outline_size);
+	ClassDB::bind_method(D_METHOD("get_outline_size"), &LabelSettings::get_outline_size);
+
+	ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &LabelSettings::set_outline_color);
+	ClassDB::bind_method(D_METHOD("get_outline_color"), &LabelSettings::get_outline_color);
+
+	ClassDB::bind_method(D_METHOD("set_shadow_size", "size"), &LabelSettings::set_shadow_size);
+	ClassDB::bind_method(D_METHOD("get_shadow_size"), &LabelSettings::get_shadow_size);
+
+	ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &LabelSettings::set_shadow_color);
+	ClassDB::bind_method(D_METHOD("get_shadow_color"), &LabelSettings::get_shadow_color);
+
+	ClassDB::bind_method(D_METHOD("set_shadow_offset", "offset"), &LabelSettings::set_shadow_offset);
+	ClassDB::bind_method(D_METHOD("get_shadow_offset"), &LabelSettings::get_shadow_offset);
+
+	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing");
+
+	ADD_GROUP("Font", "font");
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,1024,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
+	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "font_color"), "set_font_color", "get_font_color");
+
+	ADD_GROUP("Outline", "outline");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1,or_greater,suffix:px"), "set_outline_size", "get_outline_size");
+	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
+
+	ADD_GROUP("Shadow", "shadow");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size", PROPERTY_HINT_RANGE, "0,127,1,or_greater,suffix:px"), "set_shadow_size", "get_shadow_size");
+	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shadow_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_shadow_offset", "get_shadow_offset");
+}
+
+void LabelSettings::set_line_spacing(real_t p_spacing) {
+	if (line_spacing != p_spacing) {
+		line_spacing = p_spacing;
+		emit_changed();
+	}
+}
+
+real_t LabelSettings::get_line_spacing() const {
+	return line_spacing;
+}
+
+void LabelSettings::set_font(const Ref<Font> &p_font) {
+	if (font != p_font) {
+		if (font.is_valid()) {
+			font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed));
+		}
+		font = p_font;
+		if (font.is_valid()) {
+			font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), varray(), CONNECT_REFERENCE_COUNTED);
+		}
+		emit_changed();
+	}
+}
+
+Ref<Font> LabelSettings::get_font() const {
+	return font;
+}
+
+void LabelSettings::set_font_size(int p_size) {
+	if (font_size != p_size) {
+		font_size = p_size;
+		emit_changed();
+	}
+}
+
+int LabelSettings::get_font_size() const {
+	return font_size;
+}
+
+void LabelSettings::set_font_color(const Color &p_color) {
+	if (font_color != p_color) {
+		font_color = p_color;
+		emit_changed();
+	}
+}
+
+Color LabelSettings::get_font_color() const {
+	return font_color;
+}
+
+void LabelSettings::set_outline_size(int p_size) {
+	if (outline_size != p_size) {
+		outline_size = p_size;
+		emit_changed();
+	}
+}
+
+int LabelSettings::get_outline_size() const {
+	return outline_size;
+}
+
+void LabelSettings::set_outline_color(const Color &p_color) {
+	if (outline_color != p_color) {
+		outline_color = p_color;
+		emit_changed();
+	}
+}
+
+Color LabelSettings::get_outline_color() const {
+	return outline_color;
+}
+
+void LabelSettings::set_shadow_size(int p_size) {
+	if (shadow_size != p_size) {
+		shadow_size = p_size;
+		emit_changed();
+	}
+}
+
+int LabelSettings::get_shadow_size() const {
+	return shadow_size;
+}
+
+void LabelSettings::set_shadow_color(const Color &p_color) {
+	if (shadow_color != p_color) {
+		shadow_color = p_color;
+		emit_changed();
+	}
+}
+
+Color LabelSettings::get_shadow_color() const {
+	return shadow_color;
+}
+
+void LabelSettings::set_shadow_offset(const Vector2 &p_offset) {
+	if (shadow_offset != p_offset) {
+		shadow_offset = p_offset;
+		emit_changed();
+	}
+}
+
+Vector2 LabelSettings::get_shadow_offset() const {
+	return shadow_offset;
+}

+ 89 - 0
scene/resources/label_settings.h

@@ -0,0 +1,89 @@
+/*************************************************************************/
+/*  label_settings.h                                                     */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef LABEL_SETTINGS_H
+#define LABEL_SETTINGS_H
+
+#include "core/io/resource.h"
+#include "font.h"
+
+/*************************************************************************/
+
+class LabelSettings : public Resource {
+	GDCLASS(LabelSettings, Resource);
+
+	real_t line_spacing = 0;
+
+	Ref<Font> font;
+	int font_size = Font::DEFAULT_FONT_SIZE;
+	Color font_color = Color(0.875, 0.875, 0.875);
+
+	int outline_size = 0;
+	Color outline_color = Color(1, 1, 1);
+
+	int shadow_size = 0;
+	Color shadow_color = Color(1, 1, 1);
+	Vector2 shadow_offset = Vector2(1, 1);
+
+	void _font_changed();
+
+protected:
+	static void _bind_methods();
+
+public:
+	void set_line_spacing(real_t p_spacing);
+	real_t get_line_spacing() const;
+
+	void set_font(const Ref<Font> &p_font);
+	Ref<Font> get_font() const;
+
+	void set_font_size(int p_size);
+	int get_font_size() const;
+
+	void set_font_color(const Color &p_color);
+	Color get_font_color() const;
+
+	void set_outline_size(int p_size);
+	int get_outline_size() const;
+
+	void set_outline_color(const Color &p_color);
+	Color get_outline_color() const;
+
+	void set_shadow_size(int p_size);
+	int get_shadow_size() const;
+
+	void set_shadow_color(const Color &p_color);
+	Color get_shadow_color() const;
+
+	void set_shadow_offset(const Vector2 &p_offset);
+	Vector2 get_shadow_offset() const;
+};
+
+#endif // LABEL_SETTINGS_H