Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

text: Do not show text that's missing an embedded font #18856

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions core/src/html/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,10 +660,10 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
{
return font;
}
// TODO: If set to use embedded fonts and we couldn't find any matching font, show nothing
// However - at time of writing, we don't support DefineFont4. If we matched this behaviour,
// then a bunch of SWFs would just show no text suddenly.
Copy link
Collaborator

Choose a reason for hiding this comment

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

just to be sure, did you test some SWFs like this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Generally yes, I made sure that Flash behaves this way and most SWFs from my text collection work.

However, I've just remembered one SWF that used a wrong font: #14740, and unfortunately checking it now, it turns out the text disappears in it. Which makes sense, because now Ruffle somehow fails to load the embedded font and falls back to a device font :/

So I guess there are (and probably will be) cases when Ruffle fails to load an embedded font. Some probably are hard to spot.

// return new_empty_font(context, span, self.font_type);

// If set to use embedded fonts and we couldn't find any matching font, show nothing.
tracing::warn!("Embedded font not found: {font_name}, using an empty font");
return new_empty_font(context, span, self.font_type);
}

// Check if the font name is one of the known default fonts.
Expand Down Expand Up @@ -862,9 +862,9 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
fn left_alignment_offset(span: &TextSpan, is_first_line: bool) -> Twips {
if span.bullet {
if is_first_line {
Twips::from_pixels(35.0 + span.left_margin + span.block_indent + span.indent)
Twips::from_pixels(36.0 + span.left_margin + span.block_indent + span.indent)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this just to make the tests pass better? The change is kinda out of nowhere ;D

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I added a test that verifies how the bullet behaves when there's no font (to make sure I'm not breaking anything), and it turned out the bullet was misaligned by one pixel 😅

} else {
Twips::from_pixels(35.0 + span.left_margin + span.block_indent)
Twips::from_pixels(36.0 + span.left_margin + span.block_indent)
}
} else {
Self::left_alignment_offset_without_bullet(span, is_first_line)
Expand Down
47 changes: 47 additions & 0 deletions tests/tests/swfs/avm2/edittext_bullet_font/Test.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;

[SWF(width="200", height="200")]
public class Test extends Sprite {
[Embed(source="TestFontBulletA.ttf", fontName="TestFontNoBullet", embedAsCFF="false", unicodeRange="U+0061-U+0064")]
private var TestFontNoBullet:Class;

[Embed(source="TestFontBulletA.ttf", fontName="TestFontBulletA", embedAsCFF="false", unicodeRange="U+0061-U+0064,U+2022")]
private var TestFontBulletA:Class;

[Embed(source="TestFontBulletB.ttf", fontName="TestFontBulletB", embedAsCFF="false", unicodeRange="U+0061-U+0064,U+2022")]
private var TestFontBulletB:Class;

public function Test() {
stage.scaleMode = "noScale";

newTextField(5, 5, "TestFontBulletA", "<li>a</li>");
newTextField(5, 55, "TestFontBulletA", "<font face='TestFontBulletB'><li>a</li></font>");
newTextField(5, 105, "TestFontBulletA", "<li><font face='TestFontBulletB'>a</font></li>");
newTextField(5, 155, "TestFontBulletA", "<li><font face='TestFontBulletB'>a</font><font face='TestFontBulletA'>a</font></li>");
newTextField(105, 5, "TestFontBulletA", "<li><font face='TestFontBulletA'>a</font><font face='TestFontBulletB'>a</font></li>");
newTextField(105, 55, "TestFontBulletA", "<li><font face='TestFontBulletA'></font><font face='TestFontBulletB'>a</font></li>");
newTextField(105, 105, "TestFontBulletA", "<li><font face='TestFontNoBullet'>a</font><font face='TestFontBulletB'>a</font></li>");
newTextField(105, 155, "TestFontBulletA", "<li><font face='Unknown Font'>a</font><font face='TestFontBulletB'>a</font></li>");
}

private function newTextField(x: int, y: int, defaultFont: String, htmlText: String):void {
var text = new TextField();
text.border = true;
text.x = x;
text.y = y;
text.width = 90;
text.height = 40;
text.embedFonts = true;
var tf = new TextFormat();
tf.font = defaultFont;
tf.size = 20;
tf.leading = 5;
text.defaultTextFormat = tf;
text.htmlText = htmlText;
addChild(text);
}
}
}
134 changes: 134 additions & 0 deletions tests/tests/swfs/avm2/edittext_bullet_font/TestFontBulletA.sfd
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
SplineFontDB: 3.2
FontName: TestFontBulletA
FullName: TestFontBulletA
FamilyName: TestFontBulletA
Weight: Regular
Copyright: Copyright (c) 2024, Kamil Jarosz
UComments: "2024-7-24: Created with FontForge (http://fontforge.org)"
Version: 001.000
ItalicAngle: 0
UnderlinePosition: -76
UnderlineWidth: 38
Ascent: 800
Descent: 200
InvalidEm: 0
LayerCount: 2
Layer: 0 0 "Back" 1
Layer: 1 0 "Fore" 0
XUID: [1021 253 198287149 6396829]
StyleMap: 0x0000
FSType: 0
OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 1
CreationTime: 1721856925
ModificationTime: 1732996340
PfmFamily: 17
TTFWeight: 400
TTFWidth: 5
LineGap: 100
VLineGap: 0
OS2TypoAscent: 0
OS2TypoAOffset: 1
OS2TypoDescent: 0
OS2TypoDOffset: 1
OS2TypoLinegap: 100
OS2WinAscent: 0
OS2WinAOffset: 1
OS2WinDescent: 0
OS2WinDOffset: 1
HheadAscent: 0
HheadAOffset: 1
HheadDescent: 0
HheadDOffset: 1
OS2Vendor: 'PfEd'
MarkAttachClasses: 1
DEI: 91125
Encoding: UnicodeBmp
UnicodeInterp: none
NameList: AGL For New Fonts
DisplaySize: -48
AntiAlias: 1
FitToEm: 0
WinInfo: 8190 30 10
BeginPrivate: 0
EndPrivate
BeginChars: 65536 5

StartChar: a
Encoding: 97 97 0
Width: 800
Flags: HW
LayerCount: 2
Fore
SplineSet
0 800 m 5
800 800 l 5
800 0 l 1
0 0 l 1
0 800 l 5
EndSplineSet
EndChar

StartChar: b
Encoding: 98 98 1
Width: 108
VWidth: 1083
Flags: HW
LayerCount: 2
Fore
SplineSet
0 800 m 5
108 800 l 5
108 0 l 1
0 0 l 1
0 800 l 5
EndSplineSet
EndChar

StartChar: c
Encoding: 99 99 2
Width: 800
Flags: HW
LayerCount: 2
Fore
SplineSet
0 0 m 1
800 0 l 1
800 -200 l 5
0 -200 l 5
0 0 l 1
EndSplineSet
EndChar

StartChar: d
Encoding: 100 100 3
Width: 100
Flags: HW
LayerCount: 2
Fore
SplineSet
0 0 m 1
100 0 l 1
100 -200 l 5
0 -200 l 5
0 0 l 1
EndSplineSet
EndChar

StartChar: bullet
Encoding: 8226 8226 4
Width: 800
Flags: HW
LayerCount: 2
Fore
SplineSet
100 700 m 1
700 700 l 1
700 100 l 5
100 100 l 5
100 700 l 1
EndSplineSet
EndChar
EndChars
EndSplineFont
Binary file not shown.
139 changes: 139 additions & 0 deletions tests/tests/swfs/avm2/edittext_bullet_font/TestFontBulletB.sfd
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
SplineFontDB: 3.2
FontName: TestFontBulletB
FullName: TestFontBulletB
FamilyName: TestFontBulletB
Weight: Regular
Copyright: Copyright (c) 2024, Kamil Jarosz
UComments: "2024-7-24: Created with FontForge (http://fontforge.org)"
Version: 001.000
ItalicAngle: 0
UnderlinePosition: -76
UnderlineWidth: 38
Ascent: 800
Descent: 200
InvalidEm: 0
LayerCount: 2
Layer: 0 0 "Back" 1
Layer: 1 0 "Fore" 0
XUID: [1021 253 198287149 6396829]
StyleMap: 0x0000
FSType: 0
OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 1
CreationTime: 1721856925
ModificationTime: 1732996414
PfmFamily: 17
TTFWeight: 400
TTFWidth: 5
LineGap: 100
VLineGap: 0
OS2TypoAscent: 0
OS2TypoAOffset: 1
OS2TypoDescent: 0
OS2TypoDOffset: 1
OS2TypoLinegap: 100
OS2WinAscent: 0
OS2WinAOffset: 1
OS2WinDescent: 0
OS2WinDOffset: 1
HheadAscent: 0
HheadAOffset: 1
HheadDescent: 0
HheadDOffset: 1
OS2Vendor: 'PfEd'
MarkAttachClasses: 1
DEI: 91125
Encoding: UnicodeBmp
UnicodeInterp: none
NameList: AGL For New Fonts
DisplaySize: -48
AntiAlias: 1
FitToEm: 0
WinInfo: 8190 30 10
BeginPrivate: 0
EndPrivate
BeginChars: 65536 5

StartChar: a
Encoding: 97 97 0
Width: 800
Flags: HW
LayerCount: 2
Fore
SplineSet
0 800 m 5
800 800 l 5
800 0 l 1
0 0 l 1
0 800 l 5
EndSplineSet
Validated: 1
EndChar

StartChar: b
Encoding: 98 98 1
Width: 108
VWidth: 1083
Flags: HW
LayerCount: 2
Fore
SplineSet
0 800 m 5
108 800 l 5
108 0 l 1
0 0 l 1
0 800 l 5
EndSplineSet
Validated: 1
EndChar

StartChar: c
Encoding: 99 99 2
Width: 800
Flags: HW
LayerCount: 2
Fore
SplineSet
0 0 m 1
800 0 l 1
800 -200 l 5
0 -200 l 5
0 0 l 1
EndSplineSet
Validated: 1
EndChar

StartChar: d
Encoding: 100 100 3
Width: 100
Flags: HW
LayerCount: 2
Fore
SplineSet
0 0 m 1
100 0 l 1
100 -200 l 5
0 -200 l 5
0 0 l 1
EndSplineSet
Validated: 1
EndChar

StartChar: bullet
Encoding: 8226 8226 4
Width: 800
Flags: HW
LayerCount: 2
Fore
SplineSet
300 500 m 1
500 500 l 5
500 300 l 5
300 300 l 1
300 500 l 1
EndSplineSet
Validated: 1
EndChar
EndChars
EndSplineFont
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Binary file not shown.
7 changes: 7 additions & 0 deletions tests/tests/swfs/avm2/edittext_bullet_font/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
num_ticks = 1

[image_comparisons.output]
tolerance = 128

[player_options]
with_renderer = { optional = false, sample_count = 4 }
Loading