From f7cbe3b7cddf3351085e0f83852be28cf5696460 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 30 Jun 2023 15:32:42 -0400 Subject: [PATCH] avm2: Implement Graphics.copyFrom --- .../avm2/globals/flash/display/graphics.rs | 21 +++++++++++++++--- core/src/drawing.rs | 17 ++++++++++++++ .../avm2/graphics_direct_commands/Test.as | 12 ++++++++++ .../graphics_direct_commands/expected.png | Bin 6766 -> 6505 bytes .../avm2/graphics_direct_commands/test.swf | Bin 1263 -> 1232 bytes 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/core/src/avm2/globals/flash/display/graphics.rs b/core/src/avm2/globals/flash/display/graphics.rs index b3136de32..9842539db 100644 --- a/core/src/avm2/globals/flash/display/graphics.rs +++ b/core/src/avm2/globals/flash/display/graphics.rs @@ -819,10 +819,25 @@ pub fn cubic_curve_to<'gc>( /// Implements `Graphics.copyFrom` pub fn copy_from<'gc>( activation: &mut Activation<'_, 'gc>, - _this: Option>, - _args: &[Value<'gc>], + this: Option>, + args: &[Value<'gc>], ) -> Result, Error<'gc>> { - avm2_stub_method!(activation, "flash.display.Graphics", "copyFrom"); + if let Some(this) = this.and_then(|t| t.as_display_object()) { + let source = args + .get_object(activation, 0, "sourceGraphics")? + .as_display_object() + .expect("Bad sourceGraphics"); + + let source = source + .as_drawing(activation.context.gc_context) + .expect("Missing drawing for sourceGraphics"); + + let mut target_drawing = this + .as_drawing(activation.context.gc_context) + .expect("Missing drawing for target"); + + target_drawing.copy_from(&source); + } Ok(Value::Undefined) } diff --git a/core/src/drawing.rs b/core/src/drawing.rs index 01a02f712..76b508037 100644 --- a/core/src/drawing.rs +++ b/core/src/drawing.rs @@ -104,6 +104,23 @@ impl Drawing { this } + pub fn copy_from(&mut self, other: &Drawing) { + *self = Drawing { + render_handle: RefCell::new(None), + dirty: Cell::new(true), + shape_bounds: other.shape_bounds.clone(), + edge_bounds: other.edge_bounds.clone(), + paths: other.paths.clone(), + bitmaps: other.bitmaps.clone(), + current_fill: other.current_fill.clone(), + current_line: other.current_line.clone(), + pending_lines: other.pending_lines.clone(), + cursor: other.cursor, + fill_start: other.fill_start, + winding_rule: other.winding_rule, + } + } + pub fn set_winding_rule(&mut self, rule: FillRule) { self.winding_rule = rule; } diff --git a/tests/tests/swfs/avm2/graphics_direct_commands/Test.as b/tests/tests/swfs/avm2/graphics_direct_commands/Test.as index c9ca8aeba..b099e24de 100644 --- a/tests/tests/swfs/avm2/graphics_direct_commands/Test.as +++ b/tests/tests/swfs/avm2/graphics_direct_commands/Test.as @@ -48,8 +48,20 @@ shape.graphics.moveTo(90, 20); shape.graphics.lineTo(110, 20); shape.graphics.moveTo(120, 20); + + shape.graphics.beginFill(0xFF0000FF); + + var partial = new Shape(); + // These two commands should get overwritten by copyFrom + partial.graphics.drawCircle(0, 0, 30); + partial.graphics.beginFill(0xFFFF0000); + partial.graphics.copyFrom(shape.graphics); + partial.graphics.drawCircle(0, 0, 10); + partial.y = 100; + shape.graphics.lineTo(130, 20); this.addChild(shape); + this.addChild(partial); } function cubicCircle() { diff --git a/tests/tests/swfs/avm2/graphics_direct_commands/expected.png b/tests/tests/swfs/avm2/graphics_direct_commands/expected.png index 45cb1377a76447daa81eb35656e1ffa091c32e9d..b24320b6c8d586a36d1065dcdfbc6554ccb3dad4 100644 GIT binary patch literal 6505 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 literal 1263 zcmV<|ioTXLEZrer_ouMd>CEM})mBa~a%LtG{;zN!fg6&kMq{2xQ zrj}Y11=5NpM;2R(BuLtpyQ$Hxy6zA31A_iSwpq%H?z$<^ujr!g3`xm$?7C@6h}4}k z=bn4#3^nS21f{WA0Kj(>qe%cZJfm6IEminV+p_%v8Er1Kg1{{Z!qL%D z?kJygynR7hUtbqQS&-!{VPySdJJ32=+h1JR;zNZJ_I1y61Jkj2I@b1_gJ5%EA(rj5 z-M*~t=QP9F!#Uk)3mwfBq?{;F9YQK79@YZKt2>UhRirGwVrhPhf8jYz?E6Gsvv{Sp z!e{xt1Jg42Wgim2qvB}rPBij}fd zQcBzT;`VxFE%g3!YEP}?=m*rdSk3qkY8O&_YN}`Mo8*UdiGHuxGY_#*@tk(J3$Et*m^!t&(6fr#6#82*ud%88ZwtGU+EX*$ zXF*p|duq=AvFRTr`2NP6`*i&)EyRc577rBW?Ck9I)F3$^A*kut#=Hc;>&Y)!3Xp3Q z>>gFRDMOi#BkiM>M{#mQQW5C`@Ny=ChD@H5lKHC?kXIV|wNXXV}cj#7MMcHrx2V*a0bCy1m_UEjo=*w@1o>A#N0;=kC+b- zvw*-&7lceI0U(=zfMFp>Bq3lq2+02>LpeGm~+F$%nDhy*?z9 zD8e@S*o!{)MIW>KSf__AeGfyh*AYuQ`r&d%OJ`7>gf#dQW5M^{MhyN=LTbj-$dL#n;T)X-k!A?0)8I5?XfwTDl1b8wf2oyh;%X9qt}maD6Hue**|ky9a)PZHWK?