Ver código fonte

[Font] Add check for cyclic base font dependencies.

bruvzg 1 ano atrás
pai
commit
5c8a8c57be
2 arquivos alterados com 26 adições e 6 exclusões
  1. 23 4
      scene/resources/font.cpp
  2. 3 2
      scene/resources/font.h

+ 23 - 4
scene/resources/font.cpp

@@ -149,6 +149,25 @@ bool Font::_is_cyclic(const Ref<Font> &p_f, int p_depth) const {
 	return false;
 }
 
+bool Font::_is_base_cyclic(const Ref<Font> &p_f, int p_depth) const {
+	ERR_FAIL_COND_V(p_depth > MAX_FALLBACK_DEPTH, true);
+	if (p_f.is_null()) {
+		return false;
+	}
+	if (p_f == this) {
+		return true;
+	}
+	Ref<FontVariation> fv = p_f;
+	if (fv.is_valid()) {
+		return _is_base_cyclic(fv->get_base_font(), p_depth + 1);
+	}
+	Ref<SystemFont> fs = p_f;
+	if (fs.is_valid()) {
+		return _is_base_cyclic(fs->get_base_font(), p_depth + 1);
+	}
+	return false;
+}
+
 void Font::reset_state() {
 	_invalidate_rids();
 }
@@ -2910,7 +2929,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
 			}
 
 			Ref<Font> f = theme->get_font(theme_name, E);
-			if (f == this) {
+			if (_is_base_cyclic(f, 0)) {
 				continue;
 			}
 			if (f.is_valid()) {
@@ -2922,7 +2941,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
 	}
 
 	Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
-	if (f != this) {
+	if (!_is_base_cyclic(f, 0)) {
 		if (f.is_valid()) {
 			theme_font = f;
 			theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -3273,7 +3292,7 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
 			}
 
 			Ref<Font> f = theme->get_font(theme_name, E);
-			if (f == this) {
+			if (_is_base_cyclic(f, 0)) {
 				continue;
 			}
 			if (f.is_valid()) {
@@ -3285,7 +3304,7 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
 	}
 
 	Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
-	if (f != this) {
+	if (!_is_base_cyclic(f, 0)) {
 		if (f.is_valid()) {
 			theme_font = f;
 			theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);

+ 3 - 2
scene/resources/font.h

@@ -99,8 +99,6 @@ protected:
 
 	virtual void _update_rids_fb(const Ref<Font> &p_f, int p_depth) const;
 	virtual void _update_rids() const;
-	virtual bool _is_cyclic(const Ref<Font> &p_f, int p_depth) const;
-
 	virtual void reset_state() override;
 
 #ifndef DISABLE_DEPRECATED
@@ -110,6 +108,8 @@ protected:
 #endif
 
 public:
+	virtual bool _is_cyclic(const Ref<Font> &p_f, int p_depth) const;
+	virtual bool _is_base_cyclic(const Ref<Font> &p_f, int p_depth) const;
 	virtual void _invalidate_rids();
 
 	static constexpr int DEFAULT_FONT_SIZE = 16;
@@ -494,6 +494,7 @@ protected:
 	virtual void reset_state() override;
 
 public:
+	virtual Ref<Font> get_base_font() const { return base_font; }
 	virtual Ref<Font> _get_base_font_or_default() const;
 
 	virtual void set_antialiasing(TextServer::FontAntialiasing p_antialiasing);