From ae8e75cd6431756bc971b561c128ced55325be4d Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 11 Nov 2025 14:27:10 +0100 Subject: [PATCH 1/7] text: Transform text size using layout_to_local_matrix This is needed as this transformation applies device-text specific scaling. --- core/src/display_object/edit_text.rs | 1 + core/src/html/dimensions.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index 602796e35b5a..e0655453e593 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -969,6 +969,7 @@ impl<'gc> EditText<'gc> { /// The returned tuple should be interpreted as width, then height. pub fn measure_text(self, _context: &mut UpdateContext<'gc>) -> (Twips, Twips) { let text_size = self.0.layout.borrow().text_size(); + let text_size = self.layout_to_local_matrix() * text_size; (text_size.width(), text_size.height()) } diff --git a/core/src/html/dimensions.rs b/core/src/html/dimensions.rs index 65dd737ca4c0..8986faafda55 100644 --- a/core/src/html/dimensions.rs +++ b/core/src/html/dimensions.rs @@ -152,6 +152,34 @@ impl From> for Size { } } +impl From> for Size { + fn from(size: swf::PointDelta) -> Self { + Self { + width: size.dx, + height: size.dy, + } + } +} + +impl From> for swf::PointDelta { + fn from(size: Size) -> Self { + Self { + dx: size.width, + dy: size.height, + } + } +} + +impl std::ops::Mul> for ruffle_render::matrix::Matrix { + type Output = Size; + + fn mul(self, size: Size) -> Size { + // Size has the same semantics as PointDelta when applying a matrix + let size: swf::PointDelta = size.into(); + (self * size).into() + } +} + /// A type which represents the offset and size of a text box. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct BoxBounds { From 35309304138da6ee6043c248988805f0bec24055 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 11 Nov 2025 15:03:50 +0100 Subject: [PATCH 2/7] text: Use layout_to_local_matrix when calculating line metrics This makes sure that the device-text specific transforms are applied. --- core/src/display_object/edit_text.rs | 4 +++- core/src/html/dimensions.rs | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index e0655453e593..43499f2f5a85 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -2262,13 +2262,15 @@ impl<'gc> EditText<'gc> { let line = layout.lines().get(line)?; let bounds = line.bounds(); + // TODO What about internal bounds? + let bounds = self.layout_to_local_matrix() * bounds; Some(LayoutMetrics { ascent: line.ascent(), descent: line.descent(), leading: line.leading(), width: bounds.width(), height: bounds.height() + line.leading(), - x: bounds.offset_x() + Self::GUTTER, + x: bounds.offset_x(), }) } diff --git a/core/src/html/dimensions.rs b/core/src/html/dimensions.rs index 8986faafda55..87c095e17e2d 100644 --- a/core/src/html/dimensions.rs +++ b/core/src/html/dimensions.rs @@ -231,6 +231,16 @@ where } } +impl std::ops::Mul> for ruffle_render::matrix::Matrix { + type Output = BoxBounds; + + fn mul(self, bounds: BoxBounds) -> BoxBounds { + // BoxBounds have the same semantics as Rectangle when applying a matrix + let bounds: Rectangle = bounds.into(); + (self * bounds).into() + } +} + impl BoxBounds where T: Add + Sub + Copy, From e7cff9aae0b47d01e42e5ae2a88e3ff2d4918761 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 11 Nov 2025 15:12:19 +0100 Subject: [PATCH 3/7] text: Implement proper layout_to_local_matrix inverse Device text requires non-translation-only transformations in the layout_to_local_matrix, which requires the generic inverse() function to be called when calculating its inverse. --- core/src/display_object/edit_text.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index 43499f2f5a85..e24027d29ecf 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -799,15 +799,12 @@ impl<'gc> EditText<'gc> { /// Returns the matrix for transforming from this object's /// local space into its layout coordinate space. - fn local_to_layout_matrix(self) -> Matrix { - // layout_to_local contains only a translation, - // no need to inverse the matrix generically. - let Matrix { tx, ty, .. } = self.layout_to_local_matrix(); - Matrix::translate(-tx, -ty) + fn local_to_layout_matrix(self) -> Option { + self.layout_to_local_matrix().inverse() } - fn local_to_layout(self, local: Point) -> Point { - self.local_to_layout_matrix() * local + fn local_to_layout(self, local: Point) -> Option> { + Some(self.local_to_layout_matrix()? * local) } pub fn replace_text( @@ -1593,7 +1590,7 @@ impl<'gc> EditText<'gc> { /// Characters are divided in half, the last line is extended, etc. pub fn screen_position_to_index(self, position: Point) -> Option { let position = self.global_to_local(position)?; - let position = self.local_to_layout(position); + let position = self.local_to_layout(position)?; // TODO We can use binary search for both y and x here @@ -2305,7 +2302,7 @@ impl<'gc> EditText<'gc> { return None; } - let position = self.local_to_layout(position); + let position = self.local_to_layout(position)?; Some( self.0 From 3072e5e78d3a96ac78ce7d157287cb1ccc81454f Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 11 Nov 2025 15:14:03 +0100 Subject: [PATCH 4/7] text: Fix x/y scaling of device text glyphs Device text in FP cannot be scaled independently in x/y. Only the y scale is applied, and the x scale is set so that the aspect ratio of characters is preserved. It's used only for calculating metrics and sizing bounds. --- core/src/display_object/edit_text.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index e24027d29ecf..4ee791b05791 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -791,10 +791,22 @@ impl<'gc> EditText<'gc> { /// coordinate space into this object's local space. fn layout_to_local_matrix(self) -> Matrix { let bounds = self.0.bounds.get(); - Matrix::translate( + let matrix = Matrix::translate( bounds.x_min + Self::GUTTER - Twips::from_pixels(self.0.hscroll.get()), bounds.y_min + Self::GUTTER - self.0.vertical_scroll_offset(), - ) + ); + + if self.font_type() == FontType::Device { + // Device text cannot be scaled independently in x/y. + // Here we have to make sure the independent x/y scale applied for + // the local coordinate space is reversed, leaving only y scale + // and keeping the original aspect ratio in x. + let m = self.local_to_global_matrix(); + let device_font_scale_x = m.d / m.a; + matrix * Matrix::scale(device_font_scale_x, 1.0f32) + } else { + matrix + } } /// Returns the matrix for transforming from this object's From 241570f319e71c492199df5f7dc94613361821fc Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 11 Nov 2025 15:16:29 +0100 Subject: [PATCH 5/7] tests: Add visual/edittext/edittext_device_transform_basic test Tests basic translations applied to device text. --- .../edittext_device_transform_basic/Test.as | 63 ++++++++++++++++++ .../TestFont.ttf | Bin 0 -> 1600 bytes .../output.expected.png | Bin 0 -> 820 bytes .../output.txt | 24 +++++++ .../edittext_device_transform_basic/test.swf | Bin 0 -> 2103 bytes .../edittext_device_transform_basic/test.toml | 18 +++++ 6 files changed, 105 insertions(+) create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_basic/Test.as create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_basic/TestFont.ttf create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.expected.png create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.txt create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_basic/test.swf create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_basic/test.toml diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/Test.as b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/Test.as new file mode 100644 index 000000000000..596c8fff102f --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/Test.as @@ -0,0 +1,63 @@ +package { +import flash.display.*; +import flash.text.*; +import flash.geom.*; + +[SWF(width="200", height="200")] +public class Test extends Sprite { + [Embed(source="TestFont.ttf", fontName="TestFont", embedAsCFF="false", unicodeRange="U+0061-U+0064")] + private var TestFont:Class; + + private var nextX:int = 0; + private var nextY:int = 0; + + public function Test() { + stage.scaleMode = "noScale"; + + test(false); + test(false, 2); + test(false, 1, 2); + test(false, 2, 2); + + nextX = 100; + nextY = 0; + + test(true); + test(true, 2); + test(true, 1, 2); + test(true, 2, 2); + } + + private function test(device: Boolean, scaleX: Number = 1, scaleY: Number = 1):TextField { + var text:TextField = new TextField(); + text.x = nextX; + text.y = nextY; + text.border = true; + text.width = 40; + text.height = 20; + text.embedFonts = !device; + var tf:TextFormat = new TextFormat(); + tf.font = "TestFont"; + tf.size = 10; + text.defaultTextFormat = tf; + + text.multiline = true; + text.text = "ab\n\n\n\n\n\n\n\n\n\n\nab"; + text.scaleX = scaleX; + text.scaleY = scaleY; + addChild(text); + + nextY += 50; + + trace("" + device + " = " + text.getCharBoundaries(0) + "," + text.getCharBoundaries(1)); + trace("" + device + " = " + metricsToString(text.getLineMetrics(0))); + trace("" + device + " = " + text.textWidth); + + return text; + } + + private function metricsToString(m:TextLineMetrics): String { + return "width=" + Math.round(m.width); + } +} +} diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/TestFont.ttf b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/TestFont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..761128c1eb3c323d499229f8c34f7523983545de GIT binary patch literal 1600 zcmcgsOK4L;6g~4kX-ma^u!vA)9v1tdO<$5?t7K8s#!nGNLlIHzYnmp3{CG*Fbs;WA zL|loe3lYJc*n%MFJ}zB|t1e1cF6>g=RN|SJX>Gd@x^W)EoO|xQGw03R83+LTaStY@ z6N%)-H_u=80-+wV-Dl5CB+!Kew40TE>FRKF>h#FD9KThYr+ zA+Zr(<`%9;V;xRMZ>-~}BU--KYR0qQbB=LMZ*x#}JS&DcrrcOnoxjUnRuxG^U&QGO ze5wF=Yu|1iki;pC1#56#V}lAGX>6hgs~THq76&!9(I&<<4w0Wx6=JDc9A|G}fp(-c zHn{FxjZK`x6OApj3tM9wM}*WkME){Pql7XR;Uk9(vZz9$k8}2OjKXCf;r*1DWStin zlPA7F>@%;TZt&?+dC|{hvQ^oa>X%VBIx;9Hy+ST8FL-{b!iXf&46P!;lp;qY)0JwX zR3y4WSBATi4`#%bbY?#9`Pd3oDLy08ftoP&NStKfJ!ON9A%Y={vTrJfS|(BQGiezO zyYi&mT$(Tz85$i@djF|#ifj9np9{oGDsZ`qQldUgrTt2-RFtk83A-+d-O9H8EKg0} v)cSiW)YZlDZ{sV(6E|4R6AJO}8@dAcs`9;8mr~6kbk}pNS$!mSzL$RhFdoS* literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.expected.png b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..17fb34882470bf19fd31144642bbee1dc7d580f2 GIT binary patch literal 820 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J2BoosZ$T+u%tWsIx;Y9 z?C1WI$O_~uBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk1_q{0 zo-U3d6}R5rbu4 z>)yTpq`5URLoQ5U#pb3T|9aOiPGE&85#Zop+4RuP<7x7gwv_O zOahrkNa%pK_oHW5SAIScSzfl@wEx}2LtpP*covv0_xEM}fr9ruAQ^SbvO+Q`;V;Qj76r+Hs~&qUF_k442|m;Hoy9ASd` z5#}l+$Kn*)vqk0d z#hqwIZ~9v~q5L`f9PyJu$Mfc@Z)^eucEDfbj_jcMi5tK?q`+c;$A$n$%FNFSQ{~@U zAM1E7{AqKfk9zh2RWX!sw(#>#T5M4IE-6EN?=_oUw?nQ~JI{8XTM6>-0q64a?PenC%!P<#kZ)l=28YRnx96K{s_G8>Y@K3Nmko?{knE~@w!+g=Slrj(zyJ@)C4VXf p&OZYOw4CnQvp@%CVL0%d{ezlSYkjT>WdV~lgQu&X%Q~loCIE6t7E}NL literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.txt b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.txt new file mode 100644 index 000000000000..cc88537d1095 --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/output.txt @@ -0,0 +1,24 @@ +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = width=16 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = width=16 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = width=16 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = width=16 +false = 16 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = width=16 +true = 16 +true = (x=2, y=2, w=4, h=10),(x=6, y=2, w=4, h=10) +true = width=8 +true = 8 +true = (x=2, y=2, w=16, h=10),(x=18, y=2, w=16, h=10) +true = width=32 +true = 32 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = width=16 +true = 16 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/test.swf b/tests/tests/swfs/visual/edittext/edittext_device_transform_basic/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..7d74601360e5bf3b72dce97746efa6675888f2ac GIT binary patch literal 2103 zcmV-72*~$CS5qk-4gdgn0j*YFZxhQEpP8NAv7JA5NN@rHVj#pxaO|}mOh`hS5aSE9 zK!v%5Tj55t_H4Yx_FB7}#N3x6wW|8m$3FBaFMaPfK&sSAy$_XXzd+Te`^Mf+K+ml0 z#3?FOrMuG3&YU^t%$eW$w{`m$h+{x&2co@KWZ zQXx0&1MhA!+1FaDo+xb}IE_GMt(p-H(G)Gu&1BPAP*kg~o3_*B-WG4S8&;J|b(zkJ zTeqvPkNBZjF&o^iZ)Q#zrHp5J4Y9S;=GD4Llp3Ow*f|vsn0p+Ow{~jhR{xeJNThin z9oQ8}4D(63_JPr`+`4cE=ag;JJK_!;Xdkp{fu(`qDWeptI)Z!l{}dXqNs$I`?H}-c zu_ao2UzP)%C#2v8+!I?*?88Jhn@Z&L+^wFylDe6Z&=0wyPXX_4q4C(kg(pu}e!NpI zzj*qrh`Lb-fiq7r_N}sscFD(&AAcHAU`vCS#$Nw54`G7PH-9L&zlYhMBhQ8Fp^xXD z01=~Kp|D(+?3RZJh+IU=C{chgL(y*#`x9b+L+mfWnOMF4ueWmjTQn!5k0S%2Z4}Eh z7`HHb*g9Ux5{+6Uh}E>D;|_kK8Madsj(TL(yt-Bw@?sIu zG(=4z=K`i67X&{wfk0jBYcWw1CO>F+r+eWhEUkvs5>akMP9JWBc&)Zuw;DCob9hxK ziMxr3ec|oaxpOawP{$H3PK^WYMI6-Hu=j588tB*Dm4My@k*gW&~6l8h`dvdqW|BWXr- zreqn(F;ZXzGrGyhU8Zd@y3ObgqxT?H2qecSQbL!nTv_}L!3tK!#-sS^wanX_ax;|2 ztGD324euJfci>&$CDSv-;(feYg4GxJ#zI&{SS8!&I%J-<;81 zh0LV*MiC=L)fmX&P*~~eUj*cE8+3k=kNP*@JH^NR1%tl-9Uu3TmFS}=dK;~({-U9#R37t}40S%jC;VlD z8Y(~Mr=*5Sf5o7wIX>m54f=O}-p?5HA3W~sm1%>PrU8mv7Y>}y9m6eGD>Etb{y25* z7*0c_3-~xSFQ-^eOEbWH>x82luw2BY+5T4HWXquDr5^j5K_4KbC?p)21vEA!8aL5K zD&=oh=FGYG=4dH_kAZ~}@Z_DY4opm-O43Z~l|^$=uPm8MdS%&M)+;y7n|fuzTnL7j z=yLGXZ-9gbkiVO{2t``f>1HQWwH=XpD0}vf>k2QZ;jj}%&x`A?WMkfQYp-9G?E|MO z+<>qm38urF;>dPhyRX`gEz=z~2eenNQ{8BGUP;{>r@EmBTyA#KlDd9M9Xg!#cO$2} zpQ}nVyS93p#3ddIWOi7^&@$zPYnX*FMiBXO4O~S@h7`n#f@SCdiNpX%;@_;0 z#7k7i{#1a^dC3Gq1AJtII0Mi5iNQrqw%AYZKPx|c`eb?N*NxX~L%@Zb8K_x>jD#}- zI-!yZr^Oqg)pWLy&Zc!#{+_@-u?Dc7{lvt~$#%aJd>&nWtuW+?fpfwqN{0F?mBfDC z|7>lh`L#lU=2vxDokL1ojgQ5nGvFK=VuUay6dr}jInLBrcpNij0$d4Y6ES#Iq=a!~ z@d18rf%0er5()6FvKngJ#cgWzMWV z#j}rJfaMUjqxU=2#z9R4UHY@&2CX{3y7ph)np?Z21x=AcOAG-{& Date: Tue, 11 Nov 2025 15:44:27 +0100 Subject: [PATCH 6/7] tests: Add visual/edittext/edittext_device_transform_metrics test --- .../edittext_device_transform_metrics/Test.as | 81 ++++++++++++++++++ .../TestFont.ttf | Bin 0 -> 1600 bytes .../output.txt | 40 +++++++++ .../test.swf | Bin 0 -> 2262 bytes .../test.toml | 8 ++ 5 files changed, 129 insertions(+) create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/Test.as create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/TestFont.ttf create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/output.txt create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/test.swf create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/test.toml diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/Test.as b/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/Test.as new file mode 100644 index 000000000000..b4b52e777f66 --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/Test.as @@ -0,0 +1,81 @@ +package { +import flash.display.*; +import flash.text.*; +import flash.geom.*; + +[SWF(width="200", height="200")] +public class Test extends Sprite { + [Embed(source="TestFont.ttf", fontName="TestFont", embedAsCFF="false", unicodeRange="U+0061-U+0064")] + private var TestFont:Class; + + private var nextX:int = 0; + private var nextY:int = 0; + + public function Test() { + stage.scaleMode = "noScale"; + + test(false); + test(false, 2); + test(false, 1, 2); + test(false, 2, 2); + + nextX = 100; + nextY = 0; + + test(true); + test(true, 2); + test(true, 1, 2); + test(true, 2, 2); + } + + private function test(device: Boolean, scaleX: Number = 1, scaleY: Number = 1):TextField { + var text:TextField = new TextField(); + text.x = nextX; + text.y = nextY; + text.border = true; + text.width = 40; + text.height = 20; + text.embedFonts = !device; + var tf:TextFormat = new TextFormat(); + tf.font = "TestFont"; + tf.size = 10; + text.defaultTextFormat = tf; + + text.multiline = true; + text.text = "ab\n\n\n\n\n\n\n\n\n\n\nab"; + text.scaleX = scaleX; + text.scaleY = scaleY; + addChild(text); + + nextY += 50; + + trace("" + device + " = " + text.getCharBoundaries(0) + "," + text.getCharBoundaries(1)); + trace("" + device + " = " + + text.getCharIndexAtPoint(1, 5) + "," + + text.getCharIndexAtPoint(2, 5) + "," + + text.getCharIndexAtPoint(5, 5) + "," + + text.getCharIndexAtPoint(8, 5) + "," + + text.getCharIndexAtPoint(10, 5) + "," + + text.getCharIndexAtPoint(12, 5) + "," + + text.getCharIndexAtPoint(15, 5) + "," + + text.getCharIndexAtPoint(8, 1) + "," + + text.getCharIndexAtPoint(12, 1) + "," + + text.getCharIndexAtPoint(8, 12) + "," + + text.getCharIndexAtPoint(12, 12) + "," + + ""); + trace("" + device + " = " + metricsToString(text.getLineMetrics(0))); + trace("" + device + " = " + text.textHeight); + trace("" + device + " = " + text.textWidth); + + return text; + } + + private function metricsToString(m:TextLineMetrics): String { + return "height=" + Math.round(m.height) + + ",width=" + Math.round(m.width) + + ",x=" + Math.round(m.x) + + ",ascent=" + Math.round(m.ascent) + + ",descent=" + Math.round(m.descent); + } +} +} diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/TestFont.ttf b/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/TestFont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..761128c1eb3c323d499229f8c34f7523983545de GIT binary patch literal 1600 zcmcgsOK4L;6g~4kX-ma^u!vA)9v1tdO<$5?t7K8s#!nGNLlIHzYnmp3{CG*Fbs;WA zL|loe3lYJc*n%MFJ}zB|t1e1cF6>g=RN|SJX>Gd@x^W)EoO|xQGw03R83+LTaStY@ z6N%)-H_u=80-+wV-Dl5CB+!Kew40TE>FRKF>h#FD9KThYr+ zA+Zr(<`%9;V;xRMZ>-~}BU--KYR0qQbB=LMZ*x#}JS&DcrrcOnoxjUnRuxG^U&QGO ze5wF=Yu|1iki;pC1#56#V}lAGX>6hgs~THq76&!9(I&<<4w0Wx6=JDc9A|G}fp(-c zHn{FxjZK`x6OApj3tM9wM}*WkME){Pql7XR;Uk9(vZz9$k8}2OjKXCf;r*1DWStin zlPA7F>@%;TZt&?+dC|{hvQ^oa>X%VBIx;9Hy+ST8FL-{b!iXf&46P!;lp;qY)0JwX zR3y4WSBATi4`#%bbY?#9`Pd3oDLy08ftoP&NStKfJ!ON9A%Y={vTrJfS|(BQGiezO zyYi&mT$(Tz85$i@djF|#ifj9np9{oGDsZ`qQldUgrTt2-RFtk83A-+d-O9H8EKg0} v)cSiW)YZlDZ{sV(6E|4R6AJO}8@dAcs`9;8mr~6kbk}pNS$!mSzL$RhFdoS* literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/output.txt b/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/output.txt new file mode 100644 index 000000000000..69da5c8b549c --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/output.txt @@ -0,0 +1,40 @@ +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = 0,0,0,0,1,1,1,-1,-1,-1,-1, +true = height=10,width=16,x=102,ascent=8,descent=2 +true = 120 +true = 16 +true = (x=2, y=2, w=4, h=10),(x=6, y=2, w=4, h=10) +true = 0,0,0,1,-1,-1,-1,-1,-1,-1,-1, +true = height=5,width=8,x=52,ascent=4,descent=1 +true = 60 +true = 8 +true = (x=2, y=2, w=16, h=10),(x=18, y=2, w=16, h=10) +true = 0,0,0,0,0,0,0,-1,-1,-1,-1, +true = height=20,width=32,x=102,ascent=16,descent=4 +true = 240 +true = 32 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = 0,0,0,0,1,1,1,-1,-1,-1,-1, +true = height=10,width=16,x=52,ascent=8,descent=2 +true = 120 +true = 16 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/test.swf b/tests/tests/swfs/visual/edittext/edittext_device_transform_metrics/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..79d58219adee99adaee099efe39c30028ce13320 GIT binary patch literal 2262 zcmV;{2r2hNS5qm44*&po0j*a{ZyU)G?(TUshk8)5WJZCsC6k;HDa(4VWXW91 z581H1u{SYS=plQ=iAfGIGm_}N#6WV$DaRag(myc}AOVs?Kxh9zkW2RF*8yXstfm%_ZuUa@AV}YGbzK z`?XbFKRrE7pJvmJd!#R{tgPrpM$cqYAd&LkRDD)YRlV!8o1uYS?iF0S=G#s+Aq+Cp zIrcYZXIoZ_g^tnMv0DyJ77IEr^9rx}p1zP?07J#Xs^z#9=5MlEt!x*VFsIj3UdbuE zK4m97WtEv%TGzXRLdUoLGT+>;u|kO_a%EmmYojJ z)QG_rIQQEf`axPpJLKcXk3Ww}Fr~sH554|N7PbjOxBm65_XimLDf*myKKgiJAD9^Z z25ExMIaMDKP`QleQDO?W2;PxLKGJkuD|^4_U=7Cmt}@@xDXvM#re|0EIee2&IuEsHbx1 z;D8RhXl+f5)65$X-@~@?NPD1oK449&&Ow2dx#o%YW2eYvAHS# z{KPJBHI#kX{CorQb)Wbah}Hd^&CA7TxL4DHkL&o2YC3L_yUM9u^h;`qi@>71V)CLu z&I3$AFWmgH1q|7@M4wb_qlTbboD4ILbx9~ ztcl?Z5y7xPLa({@32eMo0T#XMIAzYN>i#iA<>Cr$2Du?WW`0R=g%dOxhQA>t>l=|I z^9oS>8*1~bB}L5%25k){&#mzvUa3vzVgj2U=an5eA-u7}!z1U=cMbtSyK0ML<)7C&eco zXTjTrOqMD*PU0i+opBuh3K^8h6f2adltd`jD2`IxN2Lptj8bxuk~k$}l#EkyiAt9# znV@8nk}H&aLCFv$gOtQ5Nlz}1XFpJl6zFmQTaZV_o)0pK~VSz^&=@Vl}OD0mS71>1A{SqW9H7=l$eaH;q?u8 zzJzBBo^5#UJ|tt~j~+e7>-#`G!E^JPg0Moi&@9xnx`l2M31iy)5@j2K*~x9Fa2aY| z#&f$ENs3BA2S+riVSE*`wdk+$k5Vw$FaoWS#}+OTAofrY%S)D&q)ZNm8?!kD&jlA6 zv(qG}khx$4Mp%rcxnNXqTjO|Rx>!q zYAAOJpCzZo5Q|}M9E5LoB!VR|F|Fh-6CoAc0g`mdWgwL!lqp+Rn&P{? zyf2!(oGIT&NRo&a{RO0UPoy@5_LAw~LH??B^}RKay9S6Y1P{-ebbm-^f=4Y{3+Zg| zxJ6$N>D$46i=GxVEFlxv)+-GI7NH#FZ&|mDe9}r9`IMD1@@Xq=RX|2g!EuU{QF$8Ldp zAtNOimdh&q)Nx;XuWGI%&Ow-L^ImywVXabsC2X&CZ9}WQQmLl}ceTsyS)8_Jqutrh z9oO>0^5Pv57kEf;t*WPiTrhRlkN$syp14u|=YF5uL` zCbSstR#`c+m|j>)FQg50@DqXE@dmJ-_{2rMGu>*DpGVhNUh2t2J2_g%NY6D!7R**d z{A|;bv&&0Ma(2-WZ7U+hmH0qBHV(;=Ba{#-MYMisBZE{K(grb=h9Q;ELlA{WL6U}} zeHUT7~uYUmd4ML%4a&H|;05&`TXRE(rtWvdM0HQ5C6=-gGDKA@c3rk`V zBM-0eJPOnCZuB3pP;a4C>WA&(Xk)5={S(zjk8P+9)W*NBhyQ=nt`wId3L+Hl8%@k$ k`(gN3L?U8<35DI%JWei+5Qy Date: Tue, 11 Nov 2025 15:48:23 +0100 Subject: [PATCH 7/7] tests: Add visual/edittext/edittext_device_transform_negative test --- .../Test.as | 126 ++++++++++++++++++ .../TestFont.ttf | Bin 0 -> 1600 bytes .../output.expected.png | Bin 0 -> 1962 bytes .../output.txt | 120 +++++++++++++++++ .../test.swf | Bin 0 -> 2566 bytes .../test.toml | 19 +++ 6 files changed, 265 insertions(+) create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_negative/Test.as create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_negative/TestFont.ttf create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.expected.png create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.txt create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.swf create mode 100644 tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.toml diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/Test.as b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/Test.as new file mode 100644 index 000000000000..65cfb2458430 --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/Test.as @@ -0,0 +1,126 @@ +package { +import flash.display.*; +import flash.text.*; +import flash.geom.*; + +public class Test extends Sprite { + [Embed(source="TestFont.ttf", fontName="TestFont", embedAsCFF="false", unicodeRange="U+0061-U+0064")] + private var TestFont:Class; + + private var nextX = 0; + private var nextY = 0; + + public function Test() { + stage.scaleMode = "noScale"; + + test(false); + test(false, 2); + test(false, 1, 2); + test(false, 2, 2); + + nextX += 50; + test(false, 1, 1, 90); + test(false, 1, 2, 90); + nextX -= 50; + + nextX = 100; + nextY = 0; + + test(true); + test(true, 2); + test(true, 1, 2); + test(true, 2, 2); + + nextX += 50; + test(true, 1, 1, 90); + test(true, 1, 2, 90); + nextX -= 50; + + nextX = 200; + nextY = 0; + + test(false); + test(false, -2); + test(false, -1, -2); + test(false, -2, -2); + + nextY += 50; + test(false, -1, -1, 90); + test(false, -1, -2, 90); + nextY -= 50; + + nextX = 300; + nextY = 0; + + test(true); + test(true, -2); + test(true, -1, -2); + test(true, -2, -2); + + nextY += 50; + test(true, -1, -1, 90); + test(true, -1, -2, 90); + nextY -= 50; + + nextX = 400; + nextY = 0; + } + + private function test(device: Boolean, scaleX: Number = 1, scaleY: Number = 1, rotation: Number = 0):TextField { + var text = new TextField(); + text.x = nextX; + text.y = nextY; + if (rotation == 0 && scaleX < 0) { + text.x += 100; + } + if (rotation == 0 && scaleY < 0) { + text.y += 50; + } + text.border = true; + text.width = 40; + text.height = 20; + text.embedFonts = !device; + var tf = new TextFormat(); + tf.font = "TestFont"; + tf.size = 10; + text.defaultTextFormat = tf; + + text.multiline = true; + text.text = "ab\n\n\n\n\n\n\n\n\n\n\nab"; + text.scaleX = scaleX; + text.scaleY = scaleY; + text.rotation = rotation; + addChild(text); + + nextY += 50; + + trace("" + device + " = " + text.getCharBoundaries(0) + "," + text.getCharBoundaries(1)); + trace("" + device + " = " + + text.getCharIndexAtPoint(1, 5) + "," + + text.getCharIndexAtPoint(2, 5) + "," + + text.getCharIndexAtPoint(5, 5) + "," + + text.getCharIndexAtPoint(8, 5) + "," + + text.getCharIndexAtPoint(10, 5) + "," + + text.getCharIndexAtPoint(12, 5) + "," + + text.getCharIndexAtPoint(15, 5) + "," + + text.getCharIndexAtPoint(8, 1) + "," + + text.getCharIndexAtPoint(12, 1) + "," + + text.getCharIndexAtPoint(8, 12) + "," + + text.getCharIndexAtPoint(12, 12) + "," + + ""); + trace("" + device + " = " + metricsToString(text.getLineMetrics(0))); + trace("" + device + " = " + text.textHeight); + trace("" + device + " = " + text.textWidth); + + return text; + } + + private function metricsToString(m:TextLineMetrics): String { + return "height=" + Math.round(m.height) + + ",width=" + Math.round(m.width) + + ",x=" + Math.round(m.x) + + ",ascent=" + Math.round(m.ascent) + + ",descent=" + Math.round(m.descent); + } +} +} diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/TestFont.ttf b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/TestFont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..761128c1eb3c323d499229f8c34f7523983545de GIT binary patch literal 1600 zcmcgsOK4L;6g~4kX-ma^u!vA)9v1tdO<$5?t7K8s#!nGNLlIHzYnmp3{CG*Fbs;WA zL|loe3lYJc*n%MFJ}zB|t1e1cF6>g=RN|SJX>Gd@x^W)EoO|xQGw03R83+LTaStY@ z6N%)-H_u=80-+wV-Dl5CB+!Kew40TE>FRKF>h#FD9KThYr+ zA+Zr(<`%9;V;xRMZ>-~}BU--KYR0qQbB=LMZ*x#}JS&DcrrcOnoxjUnRuxG^U&QGO ze5wF=Yu|1iki;pC1#56#V}lAGX>6hgs~THq76&!9(I&<<4w0Wx6=JDc9A|G}fp(-c zHn{FxjZK`x6OApj3tM9wM}*WkME){Pql7XR;Uk9(vZz9$k8}2OjKXCf;r*1DWStin zlPA7F>@%;TZt&?+dC|{hvQ^oa>X%VBIx;9Hy+ST8FL-{b!iXf&46P!;lp;qY)0JwX zR3y4WSBATi4`#%bbY?#9`Pd3oDLy08ftoP&NStKfJ!ON9A%Y={vTrJfS|(BQGiezO zyYi&mT$(Tz85$i@djF|#ifj9np9{oGDsZ`qQldUgrTt2-RFtk83A-+d-O9H8EKg0} v)cSiW)YZlDZ{sV(6E|4R6AJO}8@dAcs`9;8mr~6kbk}pNS$!mSzL$RhFdoS* literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.expected.png b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..01840d1e14642fe68e387abb5d1dca732708f682 GIT binary patch literal 1962 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8aF1|{{Sh*;vjb?#+xT~>VX`VbVpxD z28NCO+ux;uunK>+RjZyvGU>trt&g{7(Jvf97;gNNDKYD}H~NpRZY9)VaTbJI~XtOM3C2 z`4uy-MfJ3QG>|*SJn!p@e~fb;a__m!d$2-+|8b&?hRm1wH3ENMttm|gDmV-j{PCjS zn}MN;kAcIALE!~M!vba?0`Z^xs(s=9+wARcpOuG=p$4A0z?g7Va@Xfh+4@eP4GC>9 zZ4jMMVR%x-0m7?QX}FHgeXV{u;;`94$|_Xk=taIw{K_P{QDFfsw(H9fVk5 ze5eqFk5B^S!L!*D5kCW*p7EX+pfi2aC%($Q~cZyJ==W+%iHxm_DXO07-2o* z*mZuTipUG={~X#8x%WHUv#QNS4Ym6e=PiVJ8xjmq|E%1=|M$&4|KEO}uQ_|X30D6$ zkvZ)J!-f|;cQ;Nux0P+azJW8$11JvO^w;jo=H-rW*LzqBfE*2-zydc_+gVG$3tDCO1vBKCqHMGh+gb^Hl-=`(SoNa46_kTXv_f`q;$F08BIt>-||by{o>qR-+MO z8^|3t&g@CoT^~tW&sYdfaM=AgLEpd2+G^=bzrEipj71q_Snf{jn)#~3hoM8Y94R3^ zs(s<`$5;bu6wqxS*0u+q40`o*{>KkCW`0^dla(J%|1a{KE#mdFbelg4pOQJC1}Jd9 zakk%`l6g{Z>9h&G>=?muh(c*xcvdS1C~P3v;E|-2z-|?x^A8RJ6#x?x zN_v84fQC6%n(y9Z`dPo;yZn~)I))ntFZ#mH1i9xj33$JQSqAj|k>3{>AI-Ocngz^R z3iB4;e z?>2c)wfxV`Z>-t#_;*PQ!hDTVZV0@0Zs)$aj}zpAv=UC?ya?M8%Y-90ApErBR($e`go8)EY*+=XOc^{~{an^LB{Ts5 Dr$&Z$ literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.txt b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.txt new file mode 100644 index 000000000000..8a8ce87fa140 --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/output.txt @@ -0,0 +1,120 @@ +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = 0,0,0,0,1,1,1,-1,-1,-1,-1, +true = height=10,width=16,x=102,ascent=8,descent=2 +true = 120 +true = 16 +true = (x=2, y=2, w=4, h=10),(x=6, y=2, w=4, h=10) +true = 0,0,0,1,-1,-1,-1,-1,-1,-1,-1, +true = height=5,width=8,x=52,ascent=4,descent=1 +true = 60 +true = 8 +true = (x=2, y=2, w=16, h=10),(x=18, y=2, w=16, h=10) +true = 0,0,0,0,0,0,0,-1,-1,-1,-1, +true = height=20,width=32,x=102,ascent=16,descent=4 +true = 240 +true = 32 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = 0,0,0,0,1,1,1,-1,-1,-1,-1, +true = height=10,width=16,x=52,ascent=8,descent=2 +true = 120 +true = 16 +true = (x=2, y=18, w=2, h=-2),(x=2, y=16, w=2, h=-2) +true = 0,0,0,0,0,0,0,0,0,0,0, +true = height=2,width=4,x=132,ascent=2,descent=0 +true = 24 +true = 4 +true = (x=2, y=18, w=2, h=-1),(x=2, y=17, w=2, h=-1) +true = 0,0,0,0,0,0,0,0,0,0,0, +true = height=1,width=2,x=57,ascent=1,descent=0 +true = 12 +true = 2 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +false = 0,0,0,0,1,1,1,-1,-1,-1,-1, +false = height=10,width=16,x=2,ascent=8,descent=2 +false = 120 +false = 16 +true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10) +true = 0,0,0,0,1,1,1,-1,-1,-1,-1, +true = height=10,width=16,x=302,ascent=8,descent=2 +true = 120 +true = 16 +true = (x=38, y=2, w=-4, h=10),(x=34, y=2, w=-4, h=10) +true = 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +true = height=5,width=8,x=162,ascent=4,descent=1 +true = 60 +true = 8 +true = (x=38, y=18, w=-16, h=-10),(x=22, y=18, w=-16, h=-10) +true = -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +true = height=20,width=32,x=362,ascent=16,descent=4 +true = 240 +true = 32 +true = (x=38, y=18, w=-8, h=-10),(x=30, y=18, w=-8, h=-10) +true = -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +true = height=10,width=16,x=162,ascent=8,descent=2 +true = 120 +true = 16 +true = (x=38, y=2, w=-2, h=2),(x=38, y=4, w=-2, h=2) +true = 0,0,0,0,0,0,0,0,0,0,0, +true = height=2,width=4,x=302,ascent=2,descent=0 +true = 24 +true = 4 +true = (x=38, y=2, w=-2, h=1),(x=38, y=3, w=-2, h=1) +true = 0,0,0,0,0,0,0,0,0,0,0, +true = height=1,width=2,x=152,ascent=1,descent=0 +true = 12 +true = 2 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.swf b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..82a672296604c0119962e0971f620d21098889e9 GIT binary patch literal 2566 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 literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.toml b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.toml new file mode 100644 index 000000000000..ca0673a36864 --- /dev/null +++ b/tests/tests/swfs/visual/edittext/edittext_device_transform_negative/test.toml @@ -0,0 +1,19 @@ +num_ticks = 1 +known_failure = true + +[[image_comparisons.output.checks]] +tolerance = 0 +max_outliers = 160 + +[[image_comparisons.output.checks]] +tolerance = 128 +max_outliers = 30 + +[player_options] +with_renderer = { optional = true, sample_count = 4 } + +[fonts.test_font] +family = "TestFont" +path = "TestFont.ttf" +bold = false +italic = false