Skip to content

Implement BitmapData.scroll() #2190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions core/src/avm1/globals/bitmap_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,13 +656,26 @@ pub fn pixel_dissolve<'gc>(
}

pub fn scroll<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(bitmap_data) = this.as_bitmap_data_object() {
if !bitmap_data.disposed() {
log::warn!("BitmapData.scroll - not yet implemented");
let x = args
.get(0)
.unwrap_or(&Value::Undefined)
.coerce_to_i32(activation)?;
let y = args
.get(1)
.unwrap_or(&Value::Undefined)
.coerce_to_i32(activation)?;

bitmap_data
.bitmap_data()
.write(activation.context.gc_context)
.scroll(x, y);

return Ok(Value::Undefined);
}
}
Expand Down
42 changes: 42 additions & 0 deletions core/src/avm1/object/bitmap_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,48 @@ impl BitmapData {

(x, y, w, h)
}

pub fn scroll(&mut self, x: i32, y: i32) {
let width = self.width() as i32;
let height = self.height() as i32;

if (x == 0 && y == 0) || x.abs() >= width || y.abs() >= height {
return; // no-op
}

// since this is an "in-place copy", we have to iterate from bottom to top
// when scrolling downwards - so if y is positive
let reverse_y = y > 0;
// and if only scrolling horizontally, we have to iterate from right to left
// when scrolling right - so if x is positive
let reverse_x = y == 0 && x > 0;

// iteration ranges to use as source for the copy, from is inclusive, to is exclusive
let y_from = if reverse_y { height - y - 1 } else { -y };
let y_to = if reverse_y { -1 } else { height };
let dy = if reverse_y { -1 } else { 1 };

let x_from = if reverse_x {
// we know x > 0
width - x - 1
} else {
// x can be any sign
(-x).max(0)
};
let x_to = if reverse_x { -1 } else { width.min(width - x) };
let dx = if reverse_x { -1 } else { 1 };

let mut src_y = y_from;
while src_y != y_to {
let mut src_x = x_from;
while src_x != x_to {
let color = self.get_pixel_raw(src_x as u32, src_y as u32).unwrap();
self.set_pixel32_raw((src_x + x) as u32, (src_y + y) as u32, color);
src_x += dx;
}
src_y += dy;
}
}
}

/// A BitmapData
Expand Down