Skip to content

avm2: Fix return font subclass in Font.enumerateFonts#23248

Open
besuper wants to merge 6 commits intoruffle-rs:masterfrom
besuper:fix-enumerate_fonts
Open

avm2: Fix return font subclass in Font.enumerateFonts#23248
besuper wants to merge 6 commits intoruffle-rs:masterfrom
besuper:fix-enumerate_fonts

Conversation

@besuper
Copy link
Copy Markdown

@besuper besuper commented Mar 15, 2026

This fix makes Font.enumerateFonts() return the correct font subclass instead of always using the base flash.text.Font class.

The ClassObject in Font.registerFont() was not preserved, so enumerateFonts() created all instances with the base Font class. This broke SWFs that rely on getQualifiedClassName() to recover the original font class from enumerated fonts.

Fixes #22979
I've tested CityVille with this fix, and the game now loads correctly

@danielhjacobs danielhjacobs added A-avm2 Area: AVM2 (ActionScript 3) T-fix Type: Bug fix (in something that's supposed to work already) labels Mar 16, 2026
@kjarosh
Copy link
Copy Markdown
Member

kjarosh commented Mar 21, 2026

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).

@besuper
Copy link
Copy Markdown
Author

besuper commented Mar 21, 2026

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() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks O(n^2), can we make it O(n)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@besuper besuper requested a review from kjarosh March 27, 2026 07:44
Comment thread core/src/library.rs
#[derive(Collect, Default)]
#[collect(no_drop)]
struct FontMap<'gc>(FnvHashMap<FontQuery, Font<'gc>>);
struct FontMap<'gc>(FnvHashMap<FontQuery, (Font<'gc>, Option<ClassObject<'gc>>)>);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we store the Option<ClassObject> directly on the Font?

@kjarosh kjarosh added waiting-on-author Waiting on the PR author to make the requested changes labels Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-avm2 Area: AVM2 (ActionScript 3) T-fix Type: Bug fix (in something that's supposed to work already) waiting-on-author Waiting on the PR author to make the requested changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Font] flash.text.Font::enumerateFonts(); returns "flash.text::Font" instead of the actual font asset

4 participants