Explorar o código

[TextServer] Store font extra spacing variations without making a full copy of font.

bruvzg %!s(int64=2) %!d(string=hai) anos
pai
achega
4a167fc740

+ 7 - 0
doc/classes/TextServer.xml

@@ -15,6 +15,13 @@
 				Creates a new, empty font cache entry resource. To free the resulting resource, use the [method free_rid] method.
 			</description>
 		</method>
+		<method name="create_font_linked_variation">
+			<return type="RID" />
+			<param index="0" name="font_rid" type="RID" />
+			<description>
+				Creates a new variation existing font which is reusing the same glyph cache and font data. To free the resulting resource, use the [method free_rid] method.
+			</description>
+		</method>
 		<method name="create_shaped_text">
 			<return type="RID" />
 			<param index="0" name="direction" type="int" enum="TextServer.Direction" default="0" />

+ 6 - 0
doc/classes/TextServerExtension.xml

@@ -19,6 +19,12 @@
 			<description>
 			</description>
 		</method>
+		<method name="_create_font_linked_variation" qualifiers="virtual">
+			<return type="RID" />
+			<param index="0" name="font_rid" type="RID" />
+			<description>
+			</description>
+		</method>
 		<method name="_create_shaped_text" qualifiers="virtual">
 			<return type="RID" />
 			<param index="0" name="direction" type="int" enum="TextServer.Direction" />

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 148 - 115
modules/text_server_adv/text_server_adv.cpp


+ 16 - 0
modules/text_server_adv/text_server_adv.h

@@ -293,6 +293,11 @@ class TextServerAdvanced : public TextServerExtension {
 		}
 	};
 
+	struct FontAdvancedLinkedVariation {
+		RID base_font;
+		int extra_spacing[4] = { 0, 0, 0, 0 };
+	};
+
 	struct FontAdvanced {
 		Mutex mutex;
 
@@ -534,9 +539,19 @@ class TextServerAdvanced : public TextServerExtension {
 	// Common data.
 
 	double oversampling = 1.0;
+	mutable RID_PtrOwner<FontAdvancedLinkedVariation> font_var_owner;
 	mutable RID_PtrOwner<FontAdvanced> font_owner;
 	mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner;
 
+	_FORCE_INLINE_ FontAdvanced *_get_font_data(const RID &p_font_rid) const {
+		RID rid = p_font_rid;
+		FontAdvancedLinkedVariation *fdv = font_var_owner.get_or_null(rid);
+		if (unlikely(fdv)) {
+			rid = fdv->base_font;
+		}
+		return font_owner.get_or_null(rid);
+	}
+
 	struct SystemFontKey {
 		String font_name;
 		TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
@@ -704,6 +719,7 @@ public:
 	/* Font interface */
 
 	MODBIND0R(RID, create_font);
+	MODBIND1R(RID, create_font_linked_variation, const RID &);
 
 	MODBIND2(font_set_data, const RID &, const PackedByteArray &);
 	MODBIND3(font_set_data_ptr, const RID &, const uint8_t *, int64_t);

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 149 - 114
modules/text_server_fb/text_server_fb.cpp


+ 16 - 0
modules/text_server_fb/text_server_fb.h

@@ -245,6 +245,11 @@ class TextServerFallback : public TextServerExtension {
 		}
 	};
 
+	struct FontFallbackLinkedVariation {
+		RID base_font;
+		int extra_spacing[4] = { 0, 0, 0, 0 };
+	};
+
 	struct FontFallback {
 		Mutex mutex;
 
@@ -451,9 +456,19 @@ class TextServerFallback : public TextServerExtension {
 	// Common data.
 
 	double oversampling = 1.0;
+	mutable RID_PtrOwner<FontFallbackLinkedVariation> font_var_owner;
 	mutable RID_PtrOwner<FontFallback> font_owner;
 	mutable RID_PtrOwner<ShapedTextDataFallback> shaped_owner;
 
+	_FORCE_INLINE_ FontFallback *_get_font_data(const RID &p_font_rid) const {
+		RID rid = p_font_rid;
+		FontFallbackLinkedVariation *fdv = font_var_owner.get_or_null(rid);
+		if (unlikely(fdv)) {
+			rid = fdv->base_font;
+		}
+		return font_owner.get_or_null(rid);
+	}
+
 	struct SystemFontKey {
 		String font_name;
 		TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
@@ -569,6 +584,7 @@ public:
 	/* Font interface */
 
 	MODBIND0R(RID, create_font);
+	MODBIND1R(RID, create_font_linked_variation, const RID &);
 
 	MODBIND2(font_set_data, const RID &, const PackedByteArray &);
 	MODBIND3(font_set_data_ptr, const RID &, const uint8_t *, int64_t);

+ 46 - 28
scene/resources/font.cpp

@@ -558,24 +558,28 @@ _FORCE_INLINE_ void FontFile::_clear_cache() {
 	}
 }
 
-_FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index) const {
+_FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index, int p_make_linked_from) const {
 	if (unlikely(p_cache_index >= cache.size())) {
 		cache.resize(p_cache_index + 1);
 	}
 	if (unlikely(!cache[p_cache_index].is_valid())) {
-		cache.write[p_cache_index] = TS->create_font();
-		TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size);
-		TS->font_set_antialiasing(cache[p_cache_index], antialiasing);
-		TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps);
-		TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf);
-		TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range);
-		TS->font_set_msdf_size(cache[p_cache_index], msdf_size);
-		TS->font_set_fixed_size(cache[p_cache_index], fixed_size);
-		TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter);
-		TS->font_set_allow_system_fallback(cache[p_cache_index], allow_system_fallback);
-		TS->font_set_hinting(cache[p_cache_index], hinting);
-		TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
-		TS->font_set_oversampling(cache[p_cache_index], oversampling);
+		if (p_make_linked_from >= 0 && p_make_linked_from != p_cache_index && p_make_linked_from < cache.size()) {
+			cache.write[p_cache_index] = TS->create_font_linked_variation(cache[p_make_linked_from]);
+		} else {
+			cache.write[p_cache_index] = TS->create_font();
+			TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size);
+			TS->font_set_antialiasing(cache[p_cache_index], antialiasing);
+			TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps);
+			TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf);
+			TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range);
+			TS->font_set_msdf_size(cache[p_cache_index], msdf_size);
+			TS->font_set_fixed_size(cache[p_cache_index], fixed_size);
+			TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter);
+			TS->font_set_allow_system_fallback(cache[p_cache_index], allow_system_fallback);
+			TS->font_set_hinting(cache[p_cache_index], hinting);
+			TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
+			TS->font_set_oversampling(cache[p_cache_index], oversampling);
+		}
 	}
 }
 
@@ -2218,17 +2222,19 @@ real_t FontFile::get_oversampling() const {
 RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph) const {
 	// Find existing variation cache.
 	const Dictionary &supported_coords = get_supported_variation_list();
+	int make_linked_from = -1;
 	for (int i = 0; i < cache.size(); i++) {
 		if (cache[i].is_valid()) {
 			const Dictionary &cache_var = TS->font_get_variation_coordinates(cache[i]);
 			bool match = true;
+			bool match_linked = true;
 			match = match && (TS->font_get_face_index(cache[i]) == p_face_index);
 			match = match && (TS->font_get_embolden(cache[i]) == p_strength);
 			match = match && (TS->font_get_transform(cache[i]) == p_transform);
-			match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_TOP) == p_spacing_top);
-			match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_BOTTOM) == p_spacing_bottom);
-			match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_SPACE) == p_spacing_space);
-			match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_GLYPH) == p_spacing_glyph);
+			match_linked = match_linked && (TS->font_get_spacing(cache[i], TextServer::SPACING_TOP) == p_spacing_top);
+			match_linked = match_linked && (TS->font_get_spacing(cache[i], TextServer::SPACING_BOTTOM) == p_spacing_bottom);
+			match_linked = match_linked && (TS->font_get_spacing(cache[i], TextServer::SPACING_SPACE) == p_spacing_space);
+			match_linked = match_linked && (TS->font_get_spacing(cache[i], TextServer::SPACING_GLYPH) == p_spacing_glyph);
 			for (const Variant *V = supported_coords.next(nullptr); V && match; V = supported_coords.next(V)) {
 				const Vector3 &def = supported_coords[*V];
 
@@ -2255,22 +2261,34 @@ RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_fa
 				match = match && (c_v == s_v);
 			}
 			if (match) {
-				return cache[i];
+				if (match_linked) {
+					return cache[i];
+				} else {
+					make_linked_from = i;
+				}
 			}
 		}
 	}
 
 	// Create new variation cache.
 	int idx = cache.size();
-	_ensure_rid(idx);
-	TS->font_set_variation_coordinates(cache[idx], p_variation_coordinates);
-	TS->font_set_face_index(cache[idx], p_face_index);
-	TS->font_set_embolden(cache[idx], p_strength);
-	TS->font_set_transform(cache[idx], p_transform);
-	TS->font_set_spacing(cache[idx], TextServer::SPACING_TOP, p_spacing_top);
-	TS->font_set_spacing(cache[idx], TextServer::SPACING_BOTTOM, p_spacing_bottom);
-	TS->font_set_spacing(cache[idx], TextServer::SPACING_SPACE, p_spacing_space);
-	TS->font_set_spacing(cache[idx], TextServer::SPACING_GLYPH, p_spacing_glyph);
+	if (make_linked_from >= 0) {
+		_ensure_rid(idx, make_linked_from);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_TOP, p_spacing_top);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_BOTTOM, p_spacing_bottom);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_SPACE, p_spacing_space);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_GLYPH, p_spacing_glyph);
+	} else {
+		_ensure_rid(idx);
+		TS->font_set_variation_coordinates(cache[idx], p_variation_coordinates);
+		TS->font_set_face_index(cache[idx], p_face_index);
+		TS->font_set_embolden(cache[idx], p_strength);
+		TS->font_set_transform(cache[idx], p_transform);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_TOP, p_spacing_top);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_BOTTOM, p_spacing_bottom);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_SPACE, p_spacing_space);
+		TS->font_set_spacing(cache[idx], TextServer::SPACING_GLYPH, p_spacing_glyph);
+	}
 	return cache[idx];
 }
 

+ 1 - 1
scene/resources/font.h

@@ -205,7 +205,7 @@ class FontFile : public Font {
 	mutable Vector<RID> cache;
 
 	_FORCE_INLINE_ void _clear_cache();
-	_FORCE_INLINE_ void _ensure_rid(int p_cache_index) const;
+	_FORCE_INLINE_ void _ensure_rid(int p_cache_index, int p_make_linked_from = -1) const;
 
 	void _convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz);
 	void _convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz);

+ 7 - 0
servers/text/text_server_extension.cpp

@@ -51,6 +51,7 @@ void TextServerExtension::_bind_methods() {
 	/* Font interface */
 
 	GDVIRTUAL_BIND(_create_font);
+	GDVIRTUAL_BIND(_create_font_linked_variation, "font_rid");
 
 	GDVIRTUAL_BIND(_font_set_data, "font_rid", "data");
 	GDVIRTUAL_BIND(_font_set_data_ptr, "font_rid", "data_ptr", "data_size");
@@ -412,6 +413,12 @@ RID TextServerExtension::create_font() {
 	return ret;
 }
 
+RID TextServerExtension::create_font_linked_variation(const RID &p_font_rid) {
+	RID ret;
+	GDVIRTUAL_CALL(_create_font_linked_variation, p_font_rid, ret);
+	return ret;
+}
+
 void TextServerExtension::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
 	GDVIRTUAL_CALL(_font_set_data, p_font_rid, p_data);
 }

+ 3 - 0
servers/text/text_server_extension.h

@@ -80,6 +80,9 @@ public:
 	virtual RID create_font() override;
 	GDVIRTUAL0R(RID, _create_font);
 
+	virtual RID create_font_linked_variation(const RID &p_font_rid) override;
+	GDVIRTUAL1R(RID, _create_font_linked_variation, RID);
+
 	virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override;
 	virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override;
 	GDVIRTUAL2(_font_set_data, RID, const PackedByteArray &);

+ 1 - 0
servers/text_server.cpp

@@ -206,6 +206,7 @@ void TextServer::_bind_methods() {
 	/* Font Interface */
 
 	ClassDB::bind_method(D_METHOD("create_font"), &TextServer::create_font);
+	ClassDB::bind_method(D_METHOD("create_font_linked_variation", "font_rid"), &TextServer::create_font_linked_variation);
 
 	ClassDB::bind_method(D_METHOD("font_set_data", "font_rid", "data"), &TextServer::font_set_data);
 

+ 1 - 0
servers/text_server.h

@@ -237,6 +237,7 @@ public:
 	/* Font interface */
 
 	virtual RID create_font() = 0;
+	virtual RID create_font_linked_variation(const RID &p_font_rid) = 0;
 
 	virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) = 0;
 	virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) = 0;

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio