From df6064b2e967be7370814affe0449e7c30c2d3e2 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Fri, 30 Jun 2023 20:12:09 +0200 Subject: [PATCH] avm1: Implement color matrix filter conversions --- core/src/avm1/globals/bitmap_filter.rs | 9 ++++++ core/src/avm1/globals/color_matrix_filter.rs | 28 ++++++++++++++++++ .../swfs/avm1/color_matrix_filter/output.txt | 7 +++++ .../swfs/avm1/color_matrix_filter/test.fla | Bin 5126 -> 6060 bytes .../swfs/avm1/color_matrix_filter/test.swf | Bin 1075 -> 1288 bytes 5 files changed, 44 insertions(+) diff --git a/core/src/avm1/globals/bitmap_filter.rs b/core/src/avm1/globals/bitmap_filter.rs index e59107d8a..d714c34fd 100644 --- a/core/src/avm1/globals/bitmap_filter.rs +++ b/core/src/avm1/globals/bitmap_filter.rs @@ -4,6 +4,7 @@ use crate::avm1::activation::Activation; use crate::avm1::error::Error; use crate::avm1::globals::bevel_filter::BevelFilter; use crate::avm1::globals::blur_filter::BlurFilter; +use crate::avm1::globals::color_matrix_filter::ColorMatrixFilter; use crate::avm1::object::NativeObject; use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{Attribute, Object, ScriptObject, TObject, Value}; @@ -70,6 +71,7 @@ pub fn avm1_to_filter(object: Object) -> Option { match native { NativeObject::BevelFilter(filter) => Some(Filter::BevelFilter(filter.filter())), NativeObject::BlurFilter(filter) => Some(Filter::BlurFilter(filter.filter())), + NativeObject::ColorMatrixFilter(filter) => Some(Filter::ColorMatrixFilter(filter.filter())), // Invalid filters are silently dropped/ignored, no errors are thrown. _ => None, @@ -92,6 +94,13 @@ pub fn filter_to_avm1<'gc>(activation: &mut Activation<'_, 'gc>, filter: Filter) )), activation.context.avm1.prototypes().blur_filter, ), + Filter::ColorMatrixFilter(filter) => ( + NativeObject::ColorMatrixFilter(ColorMatrixFilter::from_filter( + activation.context.gc_context, + filter, + )), + activation.context.avm1.prototypes().color_matrix_filter, + ), _ => { // Unrepresentable filters (eg Shader) will just return as Null. // Not sure there's a way to even get to that state though, they can only be added in avm2. diff --git a/core/src/avm1/globals/color_matrix_filter.rs b/core/src/avm1/globals/color_matrix_filter.rs index b92e46d7d..a37b99bdb 100644 --- a/core/src/avm1/globals/color_matrix_filter.rs +++ b/core/src/avm1/globals/color_matrix_filter.rs @@ -6,6 +6,7 @@ use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{Activation, ArrayObject, Error, Object, ScriptObject, TObject, Value}; use crate::context::GcContext; use gc_arena::{Collect, GcCell, MutationContext}; +use std::ops::Deref; #[derive(Clone, Debug, Collect)] #[collect(require_static)] @@ -13,6 +14,22 @@ struct ColorMatrixFilterData { matrix: [f32; 4 * 5], } +impl From<&ColorMatrixFilterData> for swf::ColorMatrixFilter { + fn from(filter: &ColorMatrixFilterData) -> swf::ColorMatrixFilter { + swf::ColorMatrixFilter { + matrix: filter.matrix, + } + } +} + +impl From for ColorMatrixFilterData { + fn from(filter: swf::ColorMatrixFilter) -> ColorMatrixFilterData { + Self { + matrix: filter.matrix, + } + } +} + impl Default for ColorMatrixFilterData { fn default() -> Self { Self { @@ -42,6 +59,13 @@ impl<'gc> ColorMatrixFilter<'gc> { Ok(color_matrix_filter) } + pub fn from_filter( + gc_context: MutationContext<'gc, '_>, + filter: swf::ColorMatrixFilter, + ) -> Self { + Self(GcCell::allocate(gc_context, filter.into())) + } + pub(crate) fn duplicate(&self, gc_context: MutationContext<'gc, '_>) -> Self { Self(GcCell::allocate(gc_context, self.0.read().clone())) } @@ -75,6 +99,10 @@ impl<'gc> ColorMatrixFilter<'gc> { } Ok(()) } + + pub fn filter(&self) -> swf::ColorMatrixFilter { + self.0.read().deref().into() + } } macro_rules! color_matrix_filter_method { diff --git a/tests/tests/swfs/avm1/color_matrix_filter/output.txt b/tests/tests/swfs/avm1/color_matrix_filter/output.txt index c3e586096..efe487e11 100644 --- a/tests/tests/swfs/avm1/color_matrix_filter/output.txt +++ b/tests/tests/swfs/avm1/color_matrix_filter/output.txt @@ -1,3 +1,6 @@ +// test.filters[0].matrix +1.10561990737915,0.896963536739349,-1.15258347988129,0,28.2250022888184,-0.257689893245697,0.772316873073578,0.335373044013977,0,28.2250003814697,0.8850017786026,-0.860078454017639,0.825076699256897,0,28.2250003814697,0,0,0,1,0 + // new ColorMatrixFilter [object Object] // x.clone() @@ -6,6 +9,10 @@ false // x.matrix 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0 +// test.filters = [x] +// test.filters[0].matrix +1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0 + // x.matrix after set to [0] 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // x.matrix after set to [1] diff --git a/tests/tests/swfs/avm1/color_matrix_filter/test.fla b/tests/tests/swfs/avm1/color_matrix_filter/test.fla index 5d9183919fdeefcd1ceae1c3b91cf1bf0caaf6bc..5bc33f5b2bea2247d791a9447ee00707f9ad57a9 100644 GIT binary patch delta 3087 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 R69w6yWL5ys`%{g8e*l7Cki`H1 delta 2107 zcmV-B2*mfSFNP?PTYthtc2NQZ006)d000jF002Z!O+;^Fb!}yCbS`*pY`s`rZ|X)6 zeUFs?Fx@_cTsgMafU$3JBou@iDd|Px>b6qEgE4Dx>kniv!SvU6)&^o~JAAk*L5R$p zIdgV)c0Ead`0aHVIqQIh9MZrKldoywS!Bui>Z_t`HXC`BD`e6 zeCBXA-&tz-^CYfVW1WO!Fkczd^FNWsD$*nlfKNp?M-V>RU`QJzl3E{cYPao`cWsnaa_ z;I)LQhVCR8EtAo!$yA9-vMg)r6k5I=FVMx8b_ks>-TSg;38(~`1Z@dA5_BcdCFn_D zNMNE%xY17$KoLO^LJ>m|L=i<1MiHl7z4QkPt$$4%g$v-@75o47-QHZ%)#2Lr&*GPnf73V9nUQ78<&H2!XRP3_^;j9-XCwuXU^vafMUl78Ho=Go&Je$q?U@!H^v1n4Od0?ht)flV>`8 z>?@bd4t?eFd83chlbF2|<@8jf?8l-{XDsE@AuA)vhP#RhQK=Xavw;1Od6-9)(m>iD z$6ko_oiNV5aPhI8{%Sq*y=3{Tm*8l>J%1)2=e}po0@&du-rwS{1GUp3dy`0yCS5hD zMh*SLF=Vs#VmEjyXEN)wS3}%2n-Qx<4RNR4h?uIHT4pwkw%IoHhRju(1+&&rv)MB% ziH(lYkhtBgCq7?YbwQ1Gf&D6Vx?WAJna!HZtZ4y5(|e7G4Wp)>TD#ds89l9rm_=&M zh`TkdMSIOogKkzI21BLIYOI^pUC}d*6Q$@YrQ0*RkoW(xdHe@ZO9KQH00IaI07#pd zQAlpmfgu9`00|TT02Kg}4;B}H?O5Gz+AtWs?^9Um?ZB}Kfmo1=@}u^Gt!j}r?asso zq9$<`hrhnsF7`-!g*kyxAffbcQ#BC*BF=Zt!Qc7(*`jf=2&r?=V=&}nH)v|VfBw>d z%bMEPYG3b%Z9Z|Y9wL7C@Oj`o+&dQ2F6^_$f-L;d=P?Bf-wPyJG&Rb9#E=v9JsE}? zNJHZLrq)UxfN%X9&=wH~)pDie=m-JREF+_8n&=b2I>Jy_FSCRUQZ)&#f%T=?XX>*N zu@SlL^wx6fuBlDpI3y6x=kxNsQWnt|BFnN88jMRSq9m6=Oc$jsT)#T*AfxSp-)JHokA+S3!I5 zzH)@onC=qP2RbIGMlfCz?1b%82jiVjNJKu3Z5oE2>(E36&H}bJapchkd<=T;->cHm?>}8Sz7LC#GVader;&27 z3^}~zQcNR7(fvNT4rELNhhKMWHBfe4Ms#e|Th$J_#74b) ziO{9luGD+DXBt+2x2;>tBu7Ns+nb2COTkEuNT{lg= zYE|@%b_<%L{SvvVlTojTzVbZ!0*ai>l`GY1UD`W&Ps`+v|JWVP9(ZnAHX)59Px9W> zvczjSK!Qn2flwzcL?>O|tO0jM55wHNX~(CZgC6FePk3;Dpc`!k9L7sAisv-qt+7h* z3tD9nI+ty@O7~x|LDJb9O*mTOZ#2Oq73(9I@TlTUXfWo?h8Zv$_=mo|!}2-a^Zx7Q zvl`uPZdt?3H^Z#Q^T<^TrWXnSndUXpUF)^&YY$q)%wDrEUl%JP lmJt8|ZE0;~ba`-PP)h{{000002>=NIQ33z})e!&y004}*%`pG~ diff --git a/tests/tests/swfs/avm1/color_matrix_filter/test.swf b/tests/tests/swfs/avm1/color_matrix_filter/test.swf index ea842aa9df46883018f1937826bc684a97ef809c..32ace006d603b901160487ce101474d91e746f99 100644 GIT binary patch literal 1288 zcmV+j1^41+g(cOvO@~}fci6OnpkZ@H%_G< z+C^)ZqoV1SfbUik z`?g&b7^YsY)Ab~6n0pMD&1M;vXLz2%1Z5rQw$z|>YdVpGj)I7+vZ+>W)zBfimr6#> zUP&Ze*+!+>lGQC*l8q9g%SMH1NL7ZTS%&CfNGO;{vJG>`Ftpq%q2QV(S^Mw}(@>CQ zVR=b|h3zz?V5z2RGE8N-W#)Wln-&uBUyf&amg0DdPwjA7fnOB()SGQ-r_gEE2C^kt zvL!DsNwH}v$?ov1z_9|GdX41;mOV}GVBK^>R+WP*C7+RSnK{?QtF=`wx4K%bnVK^y zxy&F9Rgi95xU-zoS-C7IhFOv9oK&r9YFQ$JOoOuajq2unVc4n(VWn#mg3SA=Ohe{!5#>O2F1&&idrPr5X4AmxG`XZZ@0w$S*Mf zKAw&w0K-5VSvIYxnvG2B9=l89lVPe2K-|D}1J?%{z&S*qU}%Q9;W*bEgb3-V4t)a+ zx~v&GnwtmCwZjEhR$$}Q<38kENpJ<;YwWfYP*QLJTF8dB0ddIzK`tu;^17}H1s`a(w=Q>HA z-vuSGx-H`G_No|w&bFXga1;h{Fhgu;irDbxQ6K09?q`#@BAZUUXXa=K#G|cPyw^*> zHnzP?E^&v9PC1vpnWKR-DeNWA{w*gq;2%59UU!f|SF5drA+OLL{9F=>f>;RW-?{rt z%fR-UCq9A$Ev`+hyyx#Du*X&T7BmU(x9QtD=5<6LvVi{d0ZhA|2^UkDa6ObfRt3 zIf{X{`tYD`Mobt{-=)~osf0? y@ZHnZUw?c5tB1$Me9!ThIpX^s``&w4%1_d7od}ujyypWQpF_t_p7jq9XkB?-{)qGd literal 1075 zcmV-31kC$GS5psw3;+OloXwWcPvb@u$A^S$5`HYO>~86nwxg^Bp~XLwKw?3*Ax2qR zx zjjnxMeq&?D{zr0i7f%-m|x9XQU8cvpWsHE>OA*)BF8 zN7-&Bp;=p&<;0cX{P8)gxx;=)r!Syo8foCB6$<1wEr$8?Co@@H_fIsH9xPr~# zk=eRloWMbVKRXH5vhi!T*~bBr3%$7J-v=)XQD~Kg#@X39CPyD0(2Ehh#6kfyi(HCG z%E_0UT<7wF%NiH{|4?>?%X2QvT$Z>ja#`S#=aS=+<-*I$X1L6ANpnd>HQd$yD!!uS z|5rr|>?IX&aZ`W3^^i`_q*w0IY&u|KI@eh+Gj;Xhkyx7=^6%-{Lw+$uZv1s~GmBi0 z$UFB=2@88Y{Z(IWg^QujJjiY4zK$~3TRykB8Ia#hli&yD@i+7B4G~JG8Fc^v