avm2: Fix return font subclass in Font.enumerateFonts#23248
avm2: Fix return font subclass in Font.enumerateFonts#23248besuper wants to merge 6 commits intoruffle-rs:masterfrom
Conversation
|
Does enumerate fonts return the same or new instances each time it's called? What's the relation between those objects and the ones injected through symbol classes? The behavior above should also be covered with a test(s). |
Enumerate fonts always returns new instances. While testing I figured out that embedded fonts appear as base Font instances. Only fonts explicitly registered with registerFont return instances of the subclass. I updated the fix to make embedded fonts always use the base Font class and only return the subclass for globally registered fonts. I also added a test covering both behaviors |
| } | ||
| } | ||
|
|
||
| for font in activation.context.library.global_fonts() { |
There was a problem hiding this comment.
This looks O(n^2), can we make it O(n)?
There was a problem hiding this comment.
I ended up storing an Option directly in FontMap struct instead of duplicating fonts in a separate vec. I think it's cleaner than maintaining a second vec alongside it
| #[derive(Collect, Default)] | ||
| #[collect(no_drop)] | ||
| struct FontMap<'gc>(FnvHashMap<FontQuery, Font<'gc>>); | ||
| struct FontMap<'gc>(FnvHashMap<FontQuery, (Font<'gc>, Option<ClassObject<'gc>>)>); |
There was a problem hiding this comment.
Could we store the Option<ClassObject> directly on the Font?
This fix makes
Font.enumerateFonts()return the correct font subclass instead of always using the baseflash.text.Fontclass.The
ClassObjectinFont.registerFont()was not preserved, soenumerateFonts()created all instances with the base Font class. This broke SWFs that rely ongetQualifiedClassName()to recover the original font class from enumerated fonts.Fixes #22979
I've tested CityVille with this fix, and the game now loads correctly