avm1: Implement gradient matrix types
This commit is contained in:
parent
5098eb079d
commit
31b0a5ae76
|
@ -16,6 +16,50 @@ pub fn value_to_matrix<'gc>(
|
||||||
object_to_matrix(value.as_object()?, avm, context)
|
object_to_matrix(value.as_object()?, avm, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gradient_object_to_matrix<'gc>(
|
||||||
|
object: Object<'gc>,
|
||||||
|
avm: &mut Avm1<'gc>,
|
||||||
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
|
) -> Result<Matrix, Error> {
|
||||||
|
if object
|
||||||
|
.get("matrixType", avm, context)?
|
||||||
|
.resolve(avm, context)?
|
||||||
|
.coerce_to_string(avm, context)?
|
||||||
|
== "box"
|
||||||
|
{
|
||||||
|
let width = object
|
||||||
|
.get("w", avm, context)?
|
||||||
|
.resolve(avm, context)?
|
||||||
|
.as_number(avm, context)?;
|
||||||
|
let height = object
|
||||||
|
.get("h", avm, context)?
|
||||||
|
.resolve(avm, context)?
|
||||||
|
.as_number(avm, context)?;
|
||||||
|
let rotation = object
|
||||||
|
.get("r", avm, context)?
|
||||||
|
.resolve(avm, context)?
|
||||||
|
.as_number(avm, context)?;
|
||||||
|
let tx = object
|
||||||
|
.get("x", avm, context)?
|
||||||
|
.resolve(avm, context)?
|
||||||
|
.as_number(avm, context)?;
|
||||||
|
let ty = object
|
||||||
|
.get("y", avm, context)?
|
||||||
|
.resolve(avm, context)?
|
||||||
|
.as_number(avm, context)?;
|
||||||
|
Ok(Matrix::create_gradient_box(
|
||||||
|
width as f32,
|
||||||
|
height as f32,
|
||||||
|
rotation as f32,
|
||||||
|
Twips::from_pixels(tx),
|
||||||
|
Twips::from_pixels(ty),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
// TODO: You can apparently pass a 3x3 matrix here. Did anybody actually? How does it work?
|
||||||
|
object_to_matrix(object, avm, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn object_to_matrix<'gc>(
|
pub fn object_to_matrix<'gc>(
|
||||||
object: Object<'gc>,
|
object: Object<'gc>,
|
||||||
avm: &mut Avm1<'gc>,
|
avm: &mut Avm1<'gc>,
|
||||||
|
@ -53,6 +97,8 @@ pub fn object_to_matrix<'gc>(
|
||||||
Ok(Matrix { a, b, c, d, tx, ty })
|
Ok(Matrix { a, b, c, d, tx, ty })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll need this soon!
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn matrix_to_object<'gc>(
|
pub fn matrix_to_object<'gc>(
|
||||||
matrix: Matrix,
|
matrix: Matrix,
|
||||||
avm: &mut Avm1<'gc>,
|
avm: &mut Avm1<'gc>,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! MovieClip prototype
|
//! MovieClip prototype
|
||||||
|
|
||||||
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
|
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
|
||||||
|
use crate::avm1::globals::matrix::gradient_object_to_matrix;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
|
@ -12,7 +13,7 @@ use crate::tag_utils::SwfSlice;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
use swf::{
|
use swf::{
|
||||||
FillStyle, Gradient, GradientInterpolation, GradientRecord, GradientSpread, LineCapStyle,
|
FillStyle, Gradient, GradientInterpolation, GradientRecord, GradientSpread, LineCapStyle,
|
||||||
LineJoinStyle, LineStyle, Matrix, Twips,
|
LineJoinStyle, LineStyle, Twips,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Implements `MovieClip`
|
/// Implements `MovieClip`
|
||||||
|
@ -279,46 +280,7 @@ fn begin_gradient_fill<'gc>(
|
||||||
color: Color::from_rgb(rgb, (alpha / 100.0 * 255.0) as u8),
|
color: Color::from_rgb(rgb, (alpha / 100.0 * 255.0) as u8),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let matrix = if matrix_object
|
let matrix = gradient_object_to_matrix(matrix_object, avm, context)?;
|
||||||
.get("matrixType", avm, context)?
|
|
||||||
.resolve(avm, context)?
|
|
||||||
.coerce_to_string(avm, context)?
|
|
||||||
== "box"
|
|
||||||
{
|
|
||||||
let width = matrix_object
|
|
||||||
.get("w", avm, context)?
|
|
||||||
.resolve(avm, context)?
|
|
||||||
.as_number(avm, context)?;
|
|
||||||
let height = matrix_object
|
|
||||||
.get("h", avm, context)?
|
|
||||||
.resolve(avm, context)?
|
|
||||||
.as_number(avm, context)?;
|
|
||||||
let tx = matrix_object
|
|
||||||
.get("x", avm, context)?
|
|
||||||
.resolve(avm, context)?
|
|
||||||
.as_number(avm, context)?
|
|
||||||
+ width / 2.0;
|
|
||||||
let ty = matrix_object
|
|
||||||
.get("y", avm, context)?
|
|
||||||
.resolve(avm, context)?
|
|
||||||
.as_number(avm, context)?
|
|
||||||
+ height / 2.0;
|
|
||||||
// TODO: This is wrong, doesn't account for rotations.
|
|
||||||
Matrix {
|
|
||||||
tx: Twips::from_pixels(tx),
|
|
||||||
ty: Twips::from_pixels(ty),
|
|
||||||
a: width as f32 / 1638.4,
|
|
||||||
d: height as f32 / 1638.4,
|
|
||||||
b: 0.0,
|
|
||||||
c: 0.0,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log::warn!(
|
|
||||||
"beginGradientFill() received unsupported matrix object {:?}",
|
|
||||||
matrix_object
|
|
||||||
);
|
|
||||||
return Ok(Value::Undefined.into());
|
|
||||||
};
|
|
||||||
let spread = match args
|
let spread = match args
|
||||||
.get(5)
|
.get(5)
|
||||||
.and_then(|v| v.clone().coerce_to_string(avm, context).ok())
|
.and_then(|v| v.clone().coerce_to_string(avm, context).ok())
|
||||||
|
|
Loading…
Reference in New Issue