Repository: godot
Issue: [WIP] Multiple DynamicFont issues
Labels: bug,topic:rendering,topic:gui

*[WIP: Making this its own issue in order to refer to it from other issues.]*

**Godot version:** ~v3.1.2+ (I haven't double-checked with the most recent builds yet.)

**OS/device including version:** N/A


**Issue description:**

Copied from https://github.com/godotengine/godot/issues/32804#issuecomment-541489953:

----

Some `DynamicFont` font caching issues which I've noticed but haven't gotten to writing up yet. Here's a quick brain dump...

### Existing `DynamicFont` font cache issues

From memory, the issues are:

 1. It's possible for a (cached?) font size to be set before the data is loaded which means the following code won't "reload" the cache because it thinks the font size is already cached:

    https://github.com/godotengine/godot/blob/1fed266bf5452b30376db62495f4985f6975f2c1/scene/resources/dynamic_font.cpp#L698-L705

 2. I seem to recall that this "manual"/direct size-setting during initialization (via https://github.com/godotengine/godot/commit/c399c41dfb065efab8d3b168ef0a1c5a5cf609d5) is what causes the issue:
 https://github.com/godotengine/godot/blob/1fed266bf5452b30376db62495f4985f6975f2c1/scene/resources/dynamic_font.cpp#L1022-L1026

    There *was* an alternate patch which used the [`set_size()`](https://github.com/godotengine/godot/blob/1fed266bf5452b30376db62495f4985f6975f2c1/scene/resources/dynamic_font.cpp#L698-L705) method AFAICT correctly (and also handled https://github.com/godotengine/godot/commit/f41dddf069ab3747e38f2236db17a46ea55200b0 correctly): #21165

    From memory, the initialization issue fell out of the following change to calculation/handling of CacheID (which may be should have been setting size to `-1` or `0` anyway?): https://github.com/godotengine/godot/commit/8daf5491ab6bc60434e4d952830bdd258eaf0e53#diff-17a3b965179a9e0883c412a8af15cff3L59

    (Which--again from memory--worked because the previous comparison operator implementation didn't meet the [transitivity requirement of a comparison sort](https://en.wikipedia.org/wiki/Comparison_sort) i.e. it was (incorrectly) possible for items `a` & `b` to return true for both these tests:  `a < b` & `b < a`.)

 3. Inconsistent use of calls to: `emit_changed()`, `_change_notify()` & `_reload_cache()`.

### Possible solution

At a minimum it may be sufficient to replace these lines:

https://github.com/godotengine/godot/blob/1fed266bf5452b30376db62495f4985f6975f2c1/scene/resources/dynamic_font.cpp#L1025-L1026

with a call to `set_size(16)`--I seem to recall that because the `DynamicFont` isn't `valid` when first created without data the incorrect cache handling issue won't occur after this change. (Or maybe it needs to be `set_size(0)`.)

### Additional context

Hopefully this is a useful starting point for someone investigating this issue. Unfortunately my list of issues to write up "comprehensively" or "verbosely" :D (as I'm wont to do)--and ideally create a PR for--isn't getting shorter so I'm doing a brain-dump here in the hopes that imperfect & done is better than someone else having to repeat my troubleshooting efforts on the font caching side of things. :)

*Edit:* Possibly useful to keep in mind: https://github.com/godotengine/godot/commit/863dd9aa46aff502f7425ea6045de93bf09b76a3#diff-fce1ec7b33979481c1af96f2d6be6686

----

**Steps to reproduce:**


**Minimal reproduction project:**
<!-- A small Godot project which reproduces the issue. Drag and drop a zip archive to upload it. -->