Merge pull request #95083 from bruvzg/base_font_loops

[Font] Add check for cyclic base font dependencies.
This commit is contained in:
Rémi Verschelde 2024-08-06 12:31:42 +02:00
commit 20eee3edd3
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 26 additions and 6 deletions

View file

@ -149,6 +149,25 @@ bool Font::_is_cyclic(const Ref<Font> &p_f, int p_depth) const {
return false; 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() { void Font::reset_state() {
_invalidate_rids(); _invalidate_rids();
} }
@ -2910,7 +2929,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
} }
Ref<Font> f = theme->get_font(theme_name, E); Ref<Font> f = theme->get_font(theme_name, E);
if (f == this) { if (_is_base_cyclic(f, 0)) {
continue; continue;
} }
if (f.is_valid()) { 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()); 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()) { if (f.is_valid()) {
theme_font = f; theme_font = f;
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); 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); Ref<Font> f = theme->get_font(theme_name, E);
if (f == this) { if (_is_base_cyclic(f, 0)) {
continue; continue;
} }
if (f.is_valid()) { 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()); 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()) { if (f.is_valid()) {
theme_font = f; theme_font = f;
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);

View file

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