From 34775965ea8dd5e7e07697635352e42a573720a6 Mon Sep 17 00:00:00 2001 From: Udeshya Date: Mon, 3 Apr 2023 00:25:10 +0100 Subject: [PATCH] avm2: Implement `Transform.pixelBounds` --- core/src/avm2/globals/flash/geom/Transform.as | 1 + core/src/avm2/globals/flash/geom/transform.rs | 28 ++++- .../swfs/avm2/displayobject_transform/Test.as | 109 ++++++++++++++++++ .../avm2/displayobject_transform/test.fla | Bin 4023 -> 0 bytes .../avm2/displayobject_transform/test.swf | Bin 2042 -> 2165 bytes 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 tests/tests/swfs/avm2/displayobject_transform/Test.as delete mode 100644 tests/tests/swfs/avm2/displayobject_transform/test.fla diff --git a/core/src/avm2/globals/flash/geom/Transform.as b/core/src/avm2/globals/flash/geom/Transform.as index 749939b9a..6f8c8b171 100644 --- a/core/src/avm2/globals/flash/geom/Transform.as +++ b/core/src/avm2/globals/flash/geom/Transform.as @@ -15,5 +15,6 @@ package flash.geom { public native function get concatenatedColorTransform():ColorTransform; public native function get concatenatedMatrix():Matrix; + public native function get pixelBounds():Rectangle; } } diff --git a/core/src/avm2/globals/flash/geom/transform.rs b/core/src/avm2/globals/flash/geom/transform.rs index a8c035d45..dcb0b2214 100644 --- a/core/src/avm2/globals/flash/geom/transform.rs +++ b/core/src/avm2/globals/flash/geom/transform.rs @@ -5,7 +5,7 @@ use crate::avm2_stub_getter; use crate::display_object::TDisplayObject; use crate::prelude::{DisplayObject, Matrix, Twips}; use ruffle_render::quality::StageQuality; -use swf::{ColorTransform, Fixed8}; +use swf::{ColorTransform, Fixed8, Rectangle}; fn get_display_object<'gc>( this: Object<'gc>, @@ -246,3 +246,29 @@ pub fn object_to_matrix<'gc>( Ok(Matrix { a, b, c, d, tx, ty }) } + +pub fn get_pixel_bounds<'gc>( + activation: &mut Activation<'_, 'gc>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let this = this.unwrap(); + let display_object = get_display_object(this, activation)?; + rectangle_to_object(display_object.world_bounds(), activation) +} + +fn rectangle_to_object<'gc>( + rectangle: Rectangle, + activation: &mut Activation<'_, 'gc>, +) -> Result, Error<'gc>> { + let object = activation.avm2().classes().rectangle.construct( + activation, + &[ + rectangle.x_min.to_pixels().into(), + rectangle.y_min.to_pixels().into(), + rectangle.width().to_pixels().into(), + rectangle.height().to_pixels().into(), + ], + )?; + Ok(object.into()) +} diff --git a/tests/tests/swfs/avm2/displayobject_transform/Test.as b/tests/tests/swfs/avm2/displayobject_transform/Test.as new file mode 100644 index 000000000..09e781523 --- /dev/null +++ b/tests/tests/swfs/avm2/displayobject_transform/Test.as @@ -0,0 +1,109 @@ +package +{ + import flash.display.*; + import flash.geom.Transform; + import flash.text.*; + + public dynamic class Test extends MovieClip + { + + public function Test() + { + super(); + addFrameScript(0,this.frame1); + } + + public function run(stage:Stage) + { + var firstTransform; + var secondTransform; + var tempMat; + var tempColor; + var otherMat; + var otherColor; + var printTransform = function(trans:Transform) + { + trace("colorTransform=" + trans.colorTransform); + trace("matrix=" + trans.matrix); + trace("concatenatedMatrix=" + trans.concatenatedMatrix); + }; + var checkQuals = function(stage:Stage, child:DisplayObject) + { + var i = undefined; + var qual = undefined; + var quals = ["best","high","16x16","16x16linear","8x8","8x8linear","low","medium"]; + for(i in quals) + { + qual = quals[i]; + stage.quality = qual; + trace(qual + " TextField " + child.transform.concatenatedMatrix); + trace(qual + " stage" + stage.transform.concatenatedMatrix); + } + }; + var firstParent:Sprite = new Sprite(); + var secondParent:Sprite = new Sprite(); + var child:TextField = new TextField(); + firstParent.addChild(child); + trace("Checking stage qualities with non-stage child"); + checkQuals(stage,child); + stage.addChild(firstParent); + trace(""); + trace("Checking stage qualities with child on stage"); + checkQuals(stage,child); + trace("// child.transform == child.transform"); + trace(child.transform == child.transform); + firstTransform = child.transform; + secondTransform = child.transform; + trace("// firstTransform"); + printTransform(firstTransform); + trace("// secondTransform"); + printTransform(secondTransform); + firstTransform.matrix.a = 99; + firstTransform.colorTransform.redOffset = 249; + trace("// firstTransform after no-op modifications"); + printTransform(firstTransform); + tempMat = firstTransform.matrix; + tempMat.a = 42; + firstTransform.matrix = tempMat; + trace("// firstTransform after matrix modification"); + printTransform(firstTransform); + trace("// secondTransform"); + printTransform(secondTransform); + tempColor = child.transform.colorTransform; + tempColor.redOffset = 12; + child.transform.colorTransform = tempColor; + trace("// firstTransform after color modification"); + printTransform(firstTransform); + trace("// secondTransform"); + printTransform(secondTransform); + otherMat = secondParent.transform.matrix; + otherColor = secondParent.transform.colorTransform; + otherMat.a = otherMat.b = otherMat.c = otherMat.d = 42; + otherColor.redMultiplier = otherColor.greenMultiplier = otherColor.blueMultiplier = 3; + secondParent.transform.matrix = otherMat; + secondParent.transform.colorTransform = otherColor; + secondParent.addChild(child); + trace("// firstTransform after setting parent"); + printTransform(firstTransform); + trace("// secondTransform after setting parent"); + printTransform(secondTransform); + firstParent.addChild(secondParent); + stage.addChild(firstParent); + trace("// firstTransform after indirectly added to stage"); + printTransform(firstTransform); + trace("// secondTransform after indirectly added to stage"); + printTransform(secondTransform); + stage.removeChild(firstParent); + trace("// firstTransform after indirectly removed from stage"); + printTransform(firstTransform); + trace("// secondTransform after indirectly removed forrm stage"); + printTransform(secondTransform); + } + + internal function frame1() : * + { + this.run(stage); + } + } + +} \ No newline at end of file diff --git a/tests/tests/swfs/avm2/displayobject_transform/test.fla b/tests/tests/swfs/avm2/displayobject_transform/test.fla deleted file mode 100644 index 19c29e130c6454acbb6923125d7d1868a13018a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4023 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 RcF1r~Dn0<9gWCfD{s&UHU2^~c diff --git a/tests/tests/swfs/avm2/displayobject_transform/test.swf b/tests/tests/swfs/avm2/displayobject_transform/test.swf index a1ffe2d33afc7d2342874e21048265077de4b4ca..f4b88d7bee0cf30e175e9d4e4daa049001be390d 100644 GIT binary patch literal 2165 zcmV-*2#WVZS5qb^4*&po0gYG7Qya+{@1BQRBMAv%FE-%EV9Uk^y|FQ1gUy2R+PfIr z__bcN>}aM3&3dF!W=4QdadFAN;aqabKai>%a!OTlgKSmyo=b9La?Hv3x#w`N{-(5tq<>Yo^)JFa2QKU-N<_v&`Tn+IuOqUQU} z`9fiLcQ?N~op;>rLTPSpu23u&%H*x&1&df(q_xGIi;Z&s7>p%;d_Nrz63;uK5sg1UGo>UX4AHGjnNhMa$e2R-|lKV zG-ukHSG!Z_IWmlI`8Hi#YHE6os;f5LQDAYQFP-K^->+v9-o_OWUT4w6XPKgL8IO zd?n`mp`au-o@ur=~{J@;g3W8>BOvlVoZf(+>U ztqlH4yn~j7j~_q2iHTr}K$8aF{&gC%1fjpoIO=a;_UG7h>iOtTr~jBhh*`Kei1N(I zkhrw9JiqzEqpr8vf`hDWt~h#&U-ae^*ZGm^zPIVNOgQ*WAGo}B@9mo2rnXZrZyJ`@ zw6%9mmHBS@uGa8aV%)yX*z=l~)C^1=h(N!g`&ibjNnw=N*oP zWWP)x-CS#LArg+Kbf*D%M;p+Lwa_$lTo>bsnBS&OUFlNGo)7mX>ovn%A9rVQFK!P%ai{3e}cn`&MHhjI4cv?Kpk9=bz~_%&$2+7G1Wj=IMU@M$@%? zn(0@rg!i$|?_=44w+|7!7yF$aHhc;P?pr%FbR6rq_mP|nZFGk{|M~lDV0O)iH|!F2 zYL@>lu0DsrS1oEAs=}|7WkEy@&v}EL_CO!2?6w-2VkF!Hq(d7Vg>+eFw~||~QT?se z*bXVwa2<aOM2)P~c@ac-60VfKG}a~~Dz9fw>g6hc(K8>qUl@VP1tUZ&-Gem7}` zK;u!!Fr%x&n&MJp-84PwPaOlOnhEC&vF4nnT6YY~Y!^!JMBgyA`ZZ0`N*g_S03z;5S5IPx9YKz6t4*k!4S(YJ-rKwD_bZ)5XEhAV zg%V-EQ{jrKq54jE8|4$3PlUu>T6cCR&y$4)6$LNY+316kVyF4Q=h%!#HUX@ zeXKeR_r2V1Q90LHTZixFu>eXlb7HA9J0#;_;fyexk}pQp;ql>1XYnW=y*!#3y)t@r zbYk?{@b^Lr3!)q$Q6&~n3?x&7MIuNK?F?5cSP7E=?WoRg#17d65w+gfe$DV-V*^O288$NA&e5w_tOZy z1e<`QSNQd}(B5eHbrnV(PfkS@goW!%NWw^1LNbOAFpl8K6%YlHAPfPE2gL`V6>%&+ z_HQwW9TbDa!9x@bRB#3zn8GR$1W9laL?Ir(afAsP0l(3Tm{kr<>BFjsuLolw#Scw6 zl+J-PaA-zC={#V?Xfz)GEk43&bnyreVdzc?>JdIIjvwJKq)R}kR-$Hf|L0(wkGhmS zlRcXq$&O~nvgfkrvloI(FQfaq99+&IJyMnTbuxGtA*D*HkqZF3Qk8!)m3>_bt{zq; zEf!2v#Hy5?{O~t3-ihQIS7kpO_EeY4B$EEa$B$7GjRcbrsT7go13?4=8aybzn*4k5 z2p8}m#pC;Rf%hWsCEm-tkMN#Qd|2l@91PA<3ECNj^%V z_sM!J$o7PIkOLw0D23jq>WLsvu^oe!SRI7ZEx>tB^K&kOPBEav%(w(MQ)&w_?pX#; zfqPEF>;|9RIEJ|iwwv5GQ-ST+2{Rt{zvs$Zl(U<0*m5x26U1N+fHT}@9sp4mh_D0! z-Uj_GuD{dKi%h@39L#h^*M@>cK0kHkKUg~*+y%fq2i)rbIMEVc4IukvHfAjB+LcF+74$f_3&h(o7aBQ|1)!UZeBjuQmxd8EBMK-9In)pxpi!>q?6|sN^%m literal 2042 zcmV;S5qrD4*&pooRwEuSKCMyuF_U2d0{aKa6)1dLjo8tWG9`@LY7WCG)Y62 zPD2OTE@35>+e=RHEh7~Snt5km9Ar%#{m3?X#7cVi@5$~K(r_UxrckApXN){WxRTJgE} zw)o6^UPQkS#y}sVr3!Ocri9S%1OH5N0)Bc?o_D_>&8!=KEx*oOn=X5Xo6;Ew@MU*2y>}zt@vRry5MeFY`$(a2EXV< zi6)i;T))nP$QwSluQ08JvKOw7)qjWp|C+cR$Vkrp9RxL3^IlpFb`s#aT^)ity-o9dtkYaf2?k_gI&r~$LTf? zL6<77;tDP&%k>SmumK0BQMZ`av+gnG9N+{*e1Im7^A0NtctRV7$DH8Y(Y1e3uXLO{ z%c)u(T!{L12DX@0Gl3iJ#_X}4k2Q&T%yu_f^PF7z3lm1_)r{%6cI4s8UzxOH=6YVs zF4Mb)9su1(qj@RpM8Lrna%_A3!I9>@18jT$mBs!yf)w5epo4JFd(t$4ch4UCe->@5p z5Oe&4*!*oD(vv(W6M4u$-yz7Hb;ySrF&kDZsAe`=L2cRfp{^IyT&LO(bn{Vl%65}o z@3DE;31AzTce-2Yp#xbmDuK1hBE=Jb;^gGvw9nn+9hVycoGC8}2mU_a+og(UHG;Fp zZ2w`@^O=jjBhlzzUPS5teUq)^bU~MOJe<&bhf_nnazY*+!s=n$qSFdfD8G=_c#(*mZm0=*#8OPF5A^eaqnVR{?WJDAR6dKc4s zm_EWp%MfjWXx|ZSk!VkdHb%6kMEjm-OGH~H+B2d(rwNHBWtvcEMxi|l4HP<{kbzAi zyd%OE5oR_1fd#+PuSh_GsQ${aKzHC{OGDAe7k~JdSv(pGl1wEeVFe?RsH%cgOfez| zDM*m9Bq2mGkucT}h8&5z#Rp&}3bI_<$Ac*LQ4iy*S}wh3#@;V#I7|XKxo5_kpa;OI zJu}e+DKLb5%ktka7!8i?R3v!heVjpq`*;jPb4Jkj@mX;=m(7jmCUWO;=W~;}soZp^ zKUa7D2#2$%qI}q?kluNSs!YntDR8onbJ9pS@}Vr5N$?k@_sX)-6P{Sr%5pCM{$FNq zD}a+trucrZ!wk<7rSBh~KB+`i!c!2Rs7NyTy8`iPyTun%|1R$164n^rvoViT3u6r5 z!aKIWR{%p{#};9jVR*IgQ6Ji|rEsh>mcz3!?tjz|VV69H)?<5T#4Zb?bsxoJpgKW z5zMY}l}o@0+#|V-C&SA?&vE)nn^rk}jmyn=wqgu~bIoyV{6E+j46lR!4X*!Hmz%Gf zQ-Q^fO~acoq}eGjy~Rn6jCgnlEWhTK^IevA+X39`3gAIIb~CnPYvDHlv}_y#c-UF9 zX2im8!TKh*e%$4Bq3!g$E~ihLPGxWkamK=@9SC#8!|wsa4nNtcsXq+;gDOHd6m`SU z!Mc_}9B)5aE*OdAX)ZqzE=PX36Il7P4vIs_FF0x+j2|G-`#jKBUGe`2^aD<>bjANu z>rBbq^!4F`V}QXo+@Rd$rvmgtPFK79m>tuTIIMxrw_L~SGJON|V@|*AGOa&A@lk{Y zbP5U%I*mkxG6;&s7?Ke>14RU#<;5h6;Gf5FL=l?ch3FiwK<9Z0g32PvaM^YrBDhE{ z+(B7@LNl~m1V~pW*W}{b)Jrs4lK>MCD;QHPDnmrTS}X;cFG6v3`q4C6%Pr2}Py&%E zf=F+=UCn>o2yqtenuW!@5DFlrFa@37Ei%O27mI6RajjHbn=P(gD6XmS_Y#jrKQ;1k YI~)d+o2hiGc7E|qiEe@9zb2iBh1Qep4FCWD