33use crate :: avm2:: activation:: Activation ;
44use crate :: avm2:: class:: { Class , ClassAttributes } ;
55use crate :: avm2:: method:: { Method , NativeMethodImpl } ;
6- use crate :: avm2:: names:: { Namespace , QName } ;
6+ use crate :: avm2:: names:: { Multiname , Namespace , QName } ;
77use crate :: avm2:: object:: { bitmapdata_allocator, Object , TObject } ;
88use crate :: avm2:: value:: Value ;
99use crate :: avm2:: Error ;
@@ -159,6 +159,104 @@ pub fn transparent<'gc>(
159159 Ok ( Value :: Undefined )
160160}
161161
162+ /// Implements `BitmapData.scroll`.
163+ pub fn scroll < ' gc > (
164+ activation : & mut Activation < ' _ , ' gc , ' _ > ,
165+ this : Option < Object < ' gc > > ,
166+ args : & [ Value < ' gc > ] ,
167+ ) -> Result < Value < ' gc > , Error > {
168+ if let Some ( bitmap_data) = this. and_then ( |t| t. as_bitmap_data ( ) ) {
169+ let x = args
170+ . get ( 0 )
171+ . unwrap_or ( & Value :: Undefined )
172+ . coerce_to_i32 ( activation) ?;
173+ let y = args
174+ . get ( 1 )
175+ . unwrap_or ( & Value :: Undefined )
176+ . coerce_to_i32 ( activation) ?;
177+
178+ bitmap_data
179+ . write ( activation. context . gc_context )
180+ . scroll ( x, y) ;
181+ }
182+
183+ Ok ( Value :: Undefined )
184+ }
185+
186+ /// Implements `BitmapData.copyPixels`.
187+ pub fn copy_pixels < ' gc > (
188+ activation : & mut Activation < ' _ , ' gc , ' _ > ,
189+ this : Option < Object < ' gc > > ,
190+ args : & [ Value < ' gc > ] ,
191+ ) -> Result < Value < ' gc > , Error > {
192+ if let Some ( bitmap_data) = this. and_then ( |t| t. as_bitmap_data ( ) ) {
193+ let source_bitmap = args
194+ . get ( 0 )
195+ . unwrap_or ( & Value :: Undefined )
196+ . coerce_to_object ( activation) ?;
197+
198+ let source_rect = args
199+ . get ( 1 )
200+ . unwrap_or ( & Value :: Undefined )
201+ . coerce_to_object ( activation) ?;
202+
203+ let src_min_x = source_rect
204+ . get_property ( & Multiname :: public ( "x" ) , activation) ?
205+ . coerce_to_i32 ( activation) ?;
206+ let src_min_y = source_rect
207+ . get_property ( & Multiname :: public ( "y" ) , activation) ?
208+ . coerce_to_i32 ( activation) ?;
209+ let src_width = source_rect
210+ . get_property ( & Multiname :: public ( "width" ) , activation) ?
211+ . coerce_to_i32 ( activation) ?;
212+ let src_height = source_rect
213+ . get_property ( & Multiname :: public ( "height" ) , activation) ?
214+ . coerce_to_i32 ( activation) ?;
215+
216+ let dest_point = args
217+ . get ( 2 )
218+ . unwrap_or ( & Value :: Undefined )
219+ . coerce_to_object ( activation) ?;
220+
221+ let dest_x = dest_point
222+ . get_property ( & Multiname :: public ( "x" ) , activation) ?
223+ . coerce_to_i32 ( activation) ?;
224+ let dest_y = dest_point
225+ . get_property ( & Multiname :: public ( "y" ) , activation) ?
226+ . coerce_to_i32 ( activation) ?;
227+
228+ if let Some ( src_bitmap) = source_bitmap. as_bitmap_data ( ) {
229+ // dealing with object aliasing...
230+ let src_bitmap_clone: BitmapData ; // only initialized if source is the same object as self
231+ let src_bitmap_data_cell = src_bitmap;
232+ let src_bitmap_gc_ref; // only initialized if source is a different object than self
233+ let source_bitmap_ref = // holds the reference to either of the ones above
234+ if GcCell :: ptr_eq ( src_bitmap, bitmap_data) {
235+ src_bitmap_clone = src_bitmap_data_cell. read ( ) . clone ( ) ;
236+ & src_bitmap_clone
237+ } else {
238+ src_bitmap_gc_ref = src_bitmap_data_cell. read ( ) ;
239+ & src_bitmap_gc_ref
240+ } ;
241+
242+ if args. len ( ) >= 4 {
243+ log:: warn!( "BitmapData.copyPixels - alpha not implemented" ) ;
244+ }
245+
246+ bitmap_data
247+ . write ( activation. context . gc_context )
248+ . copy_pixels (
249+ source_bitmap_ref,
250+ ( src_min_x, src_min_y, src_width, src_height) ,
251+ ( dest_x, dest_y) ,
252+ None ,
253+ ) ;
254+ }
255+ }
256+
257+ Ok ( Value :: Undefined )
258+ }
259+
162260/// Implements `BitmapData.getPixel`.
163261pub fn get_pixel < ' gc > (
164262 activation : & mut Activation < ' _ , ' gc , ' _ > ,
@@ -180,6 +278,15 @@ pub fn get_pixel<'gc>(
180278 Ok ( Value :: Undefined )
181279}
182280
281+ pub fn lock < ' gc > (
282+ _activation : & mut Activation < ' _ , ' gc , ' _ > ,
283+ _this : Option < Object < ' gc > > ,
284+ _args : & [ Value < ' gc > ] ,
285+ ) -> Result < Value < ' gc > , Error > {
286+ log:: warn!( "BitmapData.lock - not yet implemented" ) ;
287+ Ok ( Value :: Undefined )
288+ }
289+
183290/// Construct `BitmapData`'s class.
184291pub fn create_class < ' gc > ( mc : MutationContext < ' gc , ' _ > ) -> GcCell < ' gc , Class < ' gc > > {
185292 let class = Class :: new (
@@ -208,7 +315,13 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
208315 ] ;
209316 write. define_public_builtin_instance_properties ( mc, PUBLIC_INSTANCE_PROPERTIES ) ;
210317
211- const PUBLIC_INSTANCE_METHODS : & [ ( & str , NativeMethodImpl ) ] = & [ ( "getPixel" , get_pixel) ] ;
318+ const PUBLIC_INSTANCE_METHODS : & [ ( & str , NativeMethodImpl ) ] = & [
319+ ( "getPixel" , get_pixel) ,
320+ ( "scroll" , scroll) ,
321+ ( "lock" , lock) ,
322+ ( "unlock" , lock) , // sic, it's a noop (TODO)
323+ ( "copyPixels" , copy_pixels) ,
324+ ] ;
212325 write. define_public_builtin_instance_methods ( mc, PUBLIC_INSTANCE_METHODS ) ;
213326
214327 class
0 commit comments