core: Matrix translation is in twips
This commit is contained in:
parent
c4c02260fb
commit
223edb9bc1
|
@ -85,7 +85,7 @@ pub fn text_width<'gc>(
|
|||
{
|
||||
let metrics = etext.measure_text(context);
|
||||
|
||||
return Ok(metrics.0.into());
|
||||
return Ok(metrics.0.to_pixels().into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined.into())
|
||||
|
@ -103,7 +103,7 @@ pub fn text_height<'gc>(
|
|||
{
|
||||
let metrics = etext.measure_text(context);
|
||||
|
||||
return Ok(metrics.1.into());
|
||||
return Ok(metrics.1.to_pixels().into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined.into())
|
||||
|
|
|
@ -142,18 +142,18 @@ impl<'gc> DisplayObjectBase<'gc> {
|
|||
self.transform.color_transform = *color_transform;
|
||||
}
|
||||
fn x(&self) -> f64 {
|
||||
f64::from(self.transform.matrix.tx) / Twips::TWIPS_PER_PIXEL
|
||||
self.transform.matrix.tx.to_pixels()
|
||||
}
|
||||
fn set_x(&mut self, value: f64) {
|
||||
self.set_transformed_by_script(true);
|
||||
self.transform.matrix.tx = (value * Twips::TWIPS_PER_PIXEL) as f32
|
||||
self.transform.matrix.tx = Twips::from_pixels(value)
|
||||
}
|
||||
fn y(&self) -> f64 {
|
||||
f64::from(self.transform.matrix.ty) / Twips::TWIPS_PER_PIXEL
|
||||
self.transform.matrix.ty.to_pixels()
|
||||
}
|
||||
fn set_y(&mut self, value: f64) {
|
||||
self.set_transformed_by_script(true);
|
||||
self.transform.matrix.ty = (value * Twips::TWIPS_PER_PIXEL) as f32
|
||||
self.transform.matrix.ty = Twips::from_pixels(value)
|
||||
}
|
||||
|
||||
/// Caches the scale and rotation factors for this display object, if necessary.
|
||||
|
|
|
@ -226,9 +226,9 @@ impl<'gc> EditText<'gc> {
|
|||
transform.color_transform.a_mult = f32::from(color.a) / 255.0;
|
||||
|
||||
if let Some(layout) = &static_data.text.layout {
|
||||
transform.matrix.tx += layout.left_margin.get() as f32;
|
||||
transform.matrix.tx += layout.indent.get() as f32;
|
||||
transform.matrix.ty -= layout.leading.get() as f32;
|
||||
transform.matrix.tx += layout.left_margin;
|
||||
transform.matrix.tx += layout.indent;
|
||||
transform.matrix.ty -= layout.leading;
|
||||
}
|
||||
|
||||
transform
|
||||
|
@ -239,31 +239,31 @@ impl<'gc> EditText<'gc> {
|
|||
///
|
||||
/// This function takes the current font size and the transform to adjust,
|
||||
/// and returns the adjusted transform.
|
||||
pub fn newline(self, height: f32, mut transform: Transform) -> Transform {
|
||||
pub fn newline(self, height: Twips, mut transform: Transform) -> Transform {
|
||||
let edit_text = self.0.read();
|
||||
let static_data = &edit_text.static_data;
|
||||
|
||||
transform.matrix.tx = 0.0;
|
||||
transform.matrix.ty += height * Twips::TWIPS_PER_PIXEL as f32;
|
||||
transform.matrix.tx = Twips::new(0);
|
||||
transform.matrix.ty += height;
|
||||
if let Some(layout) = &static_data.text.layout {
|
||||
transform.matrix.tx += layout.left_margin.get() as f32;
|
||||
transform.matrix.tx += layout.indent.get() as f32;
|
||||
transform.matrix.ty += layout.leading.get() as f32;
|
||||
transform.matrix.tx += layout.left_margin;
|
||||
transform.matrix.tx += layout.indent;
|
||||
transform.matrix.ty += layout.leading;
|
||||
}
|
||||
|
||||
transform
|
||||
}
|
||||
|
||||
pub fn line_width(self) -> f32 {
|
||||
pub fn line_width(self) -> Twips {
|
||||
let edit_text = self.0.read();
|
||||
let static_data = &edit_text.static_data;
|
||||
|
||||
let mut base_width = self.width() as f32;
|
||||
let mut base_width = Twips::from_pixels(self.width());
|
||||
|
||||
if let Some(layout) = &static_data.text.layout {
|
||||
base_width -= layout.left_margin.to_pixels() as f32;
|
||||
base_width -= layout.indent.to_pixels() as f32;
|
||||
base_width -= layout.right_margin.to_pixels() as f32;
|
||||
base_width -= layout.left_margin;
|
||||
base_width -= layout.indent;
|
||||
base_width -= layout.right_margin;
|
||||
}
|
||||
|
||||
base_width
|
||||
|
@ -311,8 +311,7 @@ impl<'gc> EditText<'gc> {
|
|||
let height = static_data
|
||||
.text
|
||||
.height
|
||||
.map(|v| v.to_pixels() as f32)
|
||||
.unwrap_or_else(|| font.scale());
|
||||
.unwrap_or_else(|| Twips::from_pixels(font.scale().into()));
|
||||
|
||||
for natural_line in edit_text.text.split('\n') {
|
||||
if break_base != 0 {
|
||||
|
@ -364,14 +363,14 @@ impl<'gc> EditText<'gc> {
|
|||
/// Measure the width and height of the `EditText`'s current text load.
|
||||
///
|
||||
/// The returned tuple should be interpreted as width, then height.
|
||||
pub fn measure_text(self, context: &mut UpdateContext<'_, 'gc, '_>) -> (f32, f32) {
|
||||
pub fn measure_text(self, context: &mut UpdateContext<'_, 'gc, '_>) -> (Twips, Twips) {
|
||||
let breakpoints = self.line_breaks_cached(context.gc_context, context.library);
|
||||
|
||||
let edit_text = self.0.read();
|
||||
let static_data = &edit_text.static_data;
|
||||
let font_id = static_data.text.font_id.unwrap_or(0);
|
||||
|
||||
let mut size: (f32, f32) = (0.0, 0.0);
|
||||
let mut size: (Twips, Twips) = Default::default();
|
||||
|
||||
if let Some(font) = context
|
||||
.library
|
||||
|
@ -399,15 +398,14 @@ impl<'gc> EditText<'gc> {
|
|||
let height = static_data
|
||||
.text
|
||||
.height
|
||||
.map(|v| v.to_pixels() as f32)
|
||||
.unwrap_or_else(|| font.scale());
|
||||
.unwrap_or_else(|| Twips::from_pixels(font.scale().into()));
|
||||
|
||||
for chunk in chunks {
|
||||
let chunk_size = font.measure(chunk, height);
|
||||
|
||||
size.0 = size.0.max(chunk_size.0);
|
||||
if let Some(layout) = &static_data.text.layout {
|
||||
size.1 += layout.leading.to_pixels() as f32;
|
||||
size.1 += layout.leading;
|
||||
}
|
||||
size.1 += chunk_size.1;
|
||||
}
|
||||
|
@ -490,8 +488,7 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
|||
let height = static_data
|
||||
.text
|
||||
.height
|
||||
.map(|v| v.to_pixels() as f32)
|
||||
.unwrap_or_else(|| font.scale());
|
||||
.unwrap_or_else(|| Twips::from_pixels(font.scale().into()));
|
||||
|
||||
let breakpoints = edit_text
|
||||
.cached_break_points
|
||||
|
|
|
@ -71,25 +71,25 @@ impl<'gc> TDisplayObject<'gc> for Text<'gc> {
|
|||
a: 0,
|
||||
};
|
||||
let mut font_id = 0;
|
||||
let mut height = 0.0;
|
||||
let mut height = Twips::new(0);
|
||||
let mut transform: Transform = Default::default();
|
||||
for block in &tf.static_data.text_blocks {
|
||||
if let Some(x) = block.x_offset {
|
||||
transform.matrix.tx = x.get() as f32;
|
||||
transform.matrix.tx = x;
|
||||
}
|
||||
if let Some(y) = block.y_offset {
|
||||
transform.matrix.ty = y.get() as f32;
|
||||
transform.matrix.ty = y;
|
||||
}
|
||||
color = block.color.as_ref().unwrap_or(&color).clone();
|
||||
font_id = block.font_id.unwrap_or(font_id);
|
||||
height = block.height.map(|h| h.get() as f32).unwrap_or(height);
|
||||
height = block.height.unwrap_or(height);
|
||||
if let Some(font) = context
|
||||
.library
|
||||
.library_for_movie(self.movie().unwrap())
|
||||
.unwrap()
|
||||
.get_font(font_id)
|
||||
{
|
||||
let scale = height / font.scale();
|
||||
let scale = (height.get() as f32) / font.scale();
|
||||
transform.matrix.a = scale;
|
||||
transform.matrix.d = scale;
|
||||
transform.color_transform.r_mult = f32::from(color.r) / 255.0;
|
||||
|
@ -103,7 +103,7 @@ impl<'gc> TDisplayObject<'gc> for Text<'gc> {
|
|||
.renderer
|
||||
.render_shape(glyph.shape, context.transform_stack.transform());
|
||||
context.transform_stack.pop();
|
||||
transform.matrix.tx += c.advance as f32;
|
||||
transform.matrix.tx += Twips::new(c.advance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,13 +132,13 @@ impl<'gc> Font<'gc> {
|
|||
self,
|
||||
text: &str,
|
||||
mut transform: Transform,
|
||||
height: f32,
|
||||
height: Twips,
|
||||
mut glyph_func: FGlyph,
|
||||
) where
|
||||
FGlyph: FnMut(&Transform, &Glyph),
|
||||
{
|
||||
transform.matrix.ty += height * Twips::TWIPS_PER_PIXEL as f32;
|
||||
let scale = (height * Twips::TWIPS_PER_PIXEL as f32) / self.scale();
|
||||
transform.matrix.ty += height;
|
||||
let scale = height.get() as f32 / self.scale();
|
||||
|
||||
transform.matrix.a = scale;
|
||||
transform.matrix.d = scale;
|
||||
|
@ -148,26 +148,24 @@ impl<'gc> Font<'gc> {
|
|||
if let Some(glyph) = self.get_glyph_for_char(c) {
|
||||
glyph_func(&transform, &glyph);
|
||||
// Step horizontally.
|
||||
let mut advance = f32::from(glyph.advance);
|
||||
let mut advance = Twips::new(glyph.advance);
|
||||
if has_kerning_info {
|
||||
advance += self
|
||||
.get_kerning_offset(c, chars.peek().cloned().unwrap_or('\0'))
|
||||
.get() as f32;
|
||||
advance += self.get_kerning_offset(c, chars.peek().cloned().unwrap_or('\0'));
|
||||
}
|
||||
transform.matrix.tx += advance * scale;
|
||||
transform.matrix.tx += Twips::new((advance.get() as f32 * scale) as i32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Measure a particular string's metrics (width and height).
|
||||
pub fn measure(self, text: &str, height: f32) -> (f32, f32) {
|
||||
let mut size = (0.0, 0.0);
|
||||
pub fn measure(self, text: &str, height: Twips) -> (Twips, Twips) {
|
||||
let mut size = (Twips::new(0), Twips::new(0));
|
||||
|
||||
self.evaluate(text, Default::default(), height, |transform, _glyph| {
|
||||
let tx = transform.matrix.tx / Twips::TWIPS_PER_PIXEL as f32;
|
||||
let ty = transform.matrix.ty / Twips::TWIPS_PER_PIXEL as f32;
|
||||
size.0 = f32::max(size.0, tx);
|
||||
size.1 = f32::max(size.1, ty);
|
||||
let tx = transform.matrix.tx;
|
||||
let ty = transform.matrix.ty;
|
||||
size.0 = std::cmp::max(size.0, tx);
|
||||
size.1 = std::cmp::max(size.1, ty);
|
||||
});
|
||||
|
||||
size
|
||||
|
@ -178,7 +176,7 @@ impl<'gc> Font<'gc> {
|
|||
///
|
||||
/// This function assumes only `" "` is valid whitespace to split words on,
|
||||
/// and will not attempt to break words that are longer than `width`.
|
||||
pub fn split_wrapped_lines(self, text: &str, height: f32, width: f32) -> Vec<usize> {
|
||||
pub fn split_wrapped_lines(self, text: &str, height: Twips, width: Twips) -> Vec<usize> {
|
||||
let mut result = vec![];
|
||||
let mut current_width = width;
|
||||
let mut current_word = &text[0..0];
|
||||
|
|
|
@ -6,20 +6,30 @@ pub struct Matrix {
|
|||
pub b: f32,
|
||||
pub c: f32,
|
||||
pub d: f32,
|
||||
pub tx: f32,
|
||||
pub ty: f32,
|
||||
pub tx: Twips,
|
||||
pub ty: Twips,
|
||||
}
|
||||
|
||||
impl Matrix {
|
||||
pub fn invert(&mut self) {
|
||||
let (tx, ty) = (self.tx.get() as f32, self.ty.get() as f32);
|
||||
let det = self.a * self.d - self.b * self.c;
|
||||
let a = self.d / det;
|
||||
let b = self.b / -det;
|
||||
let c = self.c / -det;
|
||||
let d = self.a / det;
|
||||
let tx = (self.d * self.tx - self.c * self.ty) / -det;
|
||||
let ty = (self.b * self.tx - self.a * self.ty) / det;
|
||||
*self = Matrix { a, b, c, d, tx, ty };
|
||||
let (out_tx, out_ty) = (
|
||||
round_to_i32((self.d * tx - self.c * ty) / -det),
|
||||
round_to_i32((self.b * tx - self.a * ty) / det),
|
||||
);
|
||||
*self = Matrix {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
tx: Twips::new(out_tx),
|
||||
ty: Twips::new(out_ty),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,8 +40,8 @@ impl From<swf::Matrix> for Matrix {
|
|||
b: matrix.rotate_skew_0,
|
||||
c: matrix.rotate_skew_1,
|
||||
d: matrix.scale_y,
|
||||
tx: matrix.translate_x.get() as f32,
|
||||
ty: matrix.translate_y.get() as f32,
|
||||
tx: matrix.translate_x,
|
||||
ty: matrix.translate_y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,13 +49,18 @@ impl From<swf::Matrix> for Matrix {
|
|||
impl std::ops::Mul for Matrix {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: Self) -> Self {
|
||||
let (rhs_tx, rhs_ty) = (rhs.tx.get() as f32, rhs.ty.get() as f32);
|
||||
let (out_tx, out_ty) = (
|
||||
round_to_i32(self.a * rhs_tx + self.c * rhs_ty).wrapping_add(self.tx.get()),
|
||||
round_to_i32(self.b * rhs_tx + self.d * rhs_ty).wrapping_add(self.ty.get()),
|
||||
);
|
||||
Matrix {
|
||||
a: self.a * rhs.a + self.c * rhs.b,
|
||||
b: self.b * rhs.a + self.d * rhs.b,
|
||||
c: self.a * rhs.c + self.c * rhs.d,
|
||||
d: self.b * rhs.c + self.d * rhs.d,
|
||||
tx: self.a * rhs.tx + self.c * rhs.ty + self.tx,
|
||||
ty: self.b * rhs.tx + self.d * rhs.ty + self.ty,
|
||||
tx: Twips::new(out_tx),
|
||||
ty: Twips::new(out_ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,9 +69,9 @@ impl std::ops::Mul<(Twips, Twips)> for Matrix {
|
|||
type Output = (Twips, Twips);
|
||||
fn mul(self, (x, y): (Twips, Twips)) -> (Twips, Twips) {
|
||||
let (x, y) = (x.get() as f32, y.get() as f32);
|
||||
let out_x = self.a * x + self.c * y + self.tx;
|
||||
let out_y = self.b * x + self.d * y + self.ty;
|
||||
(Twips::new(out_x as i32), Twips::new(out_y as i32))
|
||||
let out_x = round_to_i32(self.a * x + self.c * y).wrapping_add(self.tx.get());
|
||||
let out_y = round_to_i32(self.b * x + self.d * y).wrapping_add(self.ty.get());
|
||||
(Twips::new(out_x), Twips::new(out_y))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,23 +80,28 @@ impl std::default::Default for Matrix {
|
|||
Matrix {
|
||||
a: 1.0,
|
||||
c: 0.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 0.0,
|
||||
d: 1.0,
|
||||
ty: 0.0,
|
||||
ty: Twips::new(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::MulAssign for Matrix {
|
||||
fn mul_assign(&mut self, rhs: Self) {
|
||||
let (rhs_tx, rhs_ty) = (rhs.tx.get() as f32, rhs.ty.get() as f32);
|
||||
let (out_tx, out_ty) = (
|
||||
round_to_i32(self.a * rhs_tx + self.c * rhs_ty) + self.tx.get(),
|
||||
round_to_i32(self.b * rhs_tx + self.d * rhs_ty) + self.ty.get(),
|
||||
);
|
||||
*self = Matrix {
|
||||
a: self.a * rhs.a + self.c * rhs.b,
|
||||
b: self.b * rhs.a + self.d * rhs.b,
|
||||
c: self.a * rhs.c + self.c * rhs.d,
|
||||
d: self.b * rhs.c + self.d * rhs.d,
|
||||
tx: self.a * rhs.tx + self.c * rhs.ty + self.tx,
|
||||
ty: self.b * rhs.tx + self.d * rhs.ty + self.ty,
|
||||
tx: Twips::new(out_tx),
|
||||
ty: Twips::new(out_ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,18 +149,18 @@ mod tests {
|
|||
}
|
||||
|
||||
impl AbsDiffEq for Matrix {
|
||||
type Epsilon = <f32 as AbsDiffEq>::Epsilon;
|
||||
type Epsilon = (<f32 as AbsDiffEq>::Epsilon, <i32 as AbsDiffEq>::Epsilon);
|
||||
fn default_epsilon() -> Self::Epsilon {
|
||||
f32::default_epsilon()
|
||||
(f32::default_epsilon(), i32::default_epsilon())
|
||||
}
|
||||
|
||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||
self.a.abs_diff_eq(&other.a, epsilon)
|
||||
&& self.b.abs_diff_eq(&other.b, epsilon)
|
||||
&& self.c.abs_diff_eq(&other.c, epsilon)
|
||||
&& self.d.abs_diff_eq(&other.d, epsilon)
|
||||
&& self.tx.abs_diff_eq(&other.tx, epsilon)
|
||||
&& self.ty.abs_diff_eq(&other.ty, epsilon)
|
||||
self.a.abs_diff_eq(&other.a, epsilon.0)
|
||||
&& self.b.abs_diff_eq(&other.b, epsilon.0)
|
||||
&& self.c.abs_diff_eq(&other.c, epsilon.0)
|
||||
&& self.d.abs_diff_eq(&other.d, epsilon.0)
|
||||
&& self.tx.get().abs_diff_eq(&other.tx.get(), epsilon.1)
|
||||
&& self.ty.get().abs_diff_eq(&other.ty.get(), epsilon.1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,12 +170,12 @@ mod tests {
|
|||
}
|
||||
|
||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||
self.a.ulps_eq(&other.a, epsilon, max_ulps)
|
||||
&& self.b.ulps_eq(&other.b, epsilon, max_ulps)
|
||||
&& self.c.ulps_eq(&other.c, epsilon, max_ulps)
|
||||
&& self.d.ulps_eq(&other.d, epsilon, max_ulps)
|
||||
&& self.tx.ulps_eq(&other.tx, epsilon, max_ulps)
|
||||
&& self.ty.ulps_eq(&other.ty, epsilon, max_ulps)
|
||||
self.a.ulps_eq(&other.a, epsilon.0, max_ulps)
|
||||
&& self.b.ulps_eq(&other.b, epsilon.0, max_ulps)
|
||||
&& self.c.ulps_eq(&other.c, epsilon.0, max_ulps)
|
||||
&& self.d.ulps_eq(&other.d, epsilon.0, max_ulps)
|
||||
&& self.tx == other.tx
|
||||
&& self.ty == other.ty
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,72 +192,72 @@ mod tests {
|
|||
Matrix {
|
||||
a: 1.0,
|
||||
c: 4.0,
|
||||
tx: 7.0,
|
||||
tx: Twips::from_pixels(7.0),
|
||||
b: 2.0,
|
||||
d: 5.0,
|
||||
ty: 2.0
|
||||
ty: Twips::from_pixels(2.0)
|
||||
},
|
||||
Matrix {
|
||||
a: -1.666_666_6,
|
||||
c: 1.333_333_3,
|
||||
tx: 9.0,
|
||||
tx: Twips::from_pixels(9.0),
|
||||
b: 0.666_666_6,
|
||||
d: -0.333_333_3,
|
||||
ty: -4.0
|
||||
ty: Twips::from_pixels(-4.0)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: -1.0,
|
||||
c: -4.0,
|
||||
tx: -7.0,
|
||||
tx: Twips::from_pixels(-7.0),
|
||||
b: -2.0,
|
||||
d: -5.0,
|
||||
ty: -2.0
|
||||
ty: Twips::from_pixels(-2.0)
|
||||
},
|
||||
Matrix {
|
||||
a: 1.666_666_6,
|
||||
c: -1.333_333_3,
|
||||
tx: 9.0,
|
||||
tx: Twips::from_pixels(9.0),
|
||||
b: -0.666_666_6,
|
||||
d: 0.333_333_3,
|
||||
ty: -4.0
|
||||
ty: Twips::from_pixels(-4.0)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 1.5,
|
||||
c: 1.2,
|
||||
tx: 1.0,
|
||||
tx: Twips::from_pixels(1.0),
|
||||
b: -2.7,
|
||||
d: 3.4,
|
||||
ty: -2.4
|
||||
ty: Twips::from_pixels(-2.4)
|
||||
},
|
||||
Matrix {
|
||||
a: 0.407_673_9,
|
||||
c: -0.143_884_9,
|
||||
tx: -0.752_997_6,
|
||||
tx: Twips::from_pixels(-0.752_997_6),
|
||||
b: 0.323_741,
|
||||
d: 0.179_856_1,
|
||||
ty: 0.107_913_67
|
||||
ty: Twips::from_pixels(0.107_913_67)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: -2.0,
|
||||
c: 0.0,
|
||||
tx: 10.0,
|
||||
tx: Twips::from_pixels(10.0),
|
||||
b: 0.0,
|
||||
d: -1.0,
|
||||
ty: 5.0
|
||||
ty: Twips::from_pixels(5.0)
|
||||
},
|
||||
Matrix {
|
||||
a: -0.5,
|
||||
c: 0.0,
|
||||
tx: 5.0,
|
||||
tx: Twips::from_pixels(5.0),
|
||||
b: 0.0,
|
||||
d: -1.0,
|
||||
ty: 5.0
|
||||
ty: Twips::from_pixels(5.0)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -251,37 +271,37 @@ mod tests {
|
|||
Matrix {
|
||||
a: 1.0,
|
||||
c: 4.0,
|
||||
tx: 7.0,
|
||||
tx: Twips::from_pixels(7.0),
|
||||
b: 2.0,
|
||||
d: 5.0,
|
||||
ty: 2.0
|
||||
ty: Twips::from_pixels(2.0)
|
||||
},
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 4.0,
|
||||
tx: 7.0,
|
||||
tx: Twips::from_pixels(7.0),
|
||||
b: 2.0,
|
||||
d: 5.0,
|
||||
ty: 2.0
|
||||
ty: Twips::from_pixels(2.0)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 4.0,
|
||||
tx: 7.0,
|
||||
tx: Twips::from_pixels(7.0),
|
||||
b: 2.0,
|
||||
d: 5.0,
|
||||
ty: 2.0
|
||||
ty: Twips::from_pixels(2.0)
|
||||
},
|
||||
Matrix::default(),
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 4.0,
|
||||
tx: 7.0,
|
||||
tx: Twips::from_pixels(7.0),
|
||||
b: 2.0,
|
||||
d: 5.0,
|
||||
ty: 2.0
|
||||
ty: Twips::from_pixels(2.0)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -293,130 +313,130 @@ mod tests {
|
|||
Matrix {
|
||||
a: 6.0,
|
||||
c: 4.0,
|
||||
tx: 2.0,
|
||||
tx: Twips::new(2),
|
||||
b: 5.0,
|
||||
d: 3.0,
|
||||
ty: 1.0
|
||||
ty: Twips::new(1)
|
||||
},
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 3.0,
|
||||
tx: 5.0,
|
||||
tx: Twips::new(5),
|
||||
b: 2.0,
|
||||
d: 4.0,
|
||||
ty: 6.0
|
||||
ty: Twips::new(6)
|
||||
},
|
||||
Matrix {
|
||||
a: 14.0,
|
||||
c: 34.0,
|
||||
tx: 56.0,
|
||||
tx: Twips::new(56),
|
||||
b: 11.0,
|
||||
d: 27.0,
|
||||
ty: 44.0
|
||||
ty: Twips::new(44)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 3.0,
|
||||
tx: 5.0,
|
||||
tx: Twips::new(5),
|
||||
b: 2.0,
|
||||
d: 4.0,
|
||||
ty: 6.0
|
||||
ty: Twips::new(6)
|
||||
},
|
||||
Matrix {
|
||||
a: 6.0,
|
||||
c: 4.0,
|
||||
tx: 2.0,
|
||||
tx: Twips::new(2),
|
||||
b: 5.0,
|
||||
d: 3.0,
|
||||
ty: 1.0
|
||||
ty: Twips::new(1)
|
||||
},
|
||||
Matrix {
|
||||
a: 21.0,
|
||||
c: 13.0,
|
||||
tx: 10.0,
|
||||
tx: Twips::new(10),
|
||||
b: 32.0,
|
||||
d: 20.0,
|
||||
ty: 14.0
|
||||
ty: Twips::new(14)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 2.0,
|
||||
tx: 3.0,
|
||||
tx: Twips::new(3),
|
||||
b: 4.0,
|
||||
d: 5.0,
|
||||
ty: 6.0
|
||||
ty: Twips::new(6)
|
||||
},
|
||||
Matrix {
|
||||
a: 6.0,
|
||||
c: 5.0,
|
||||
tx: 4.0,
|
||||
tx: Twips::new(4),
|
||||
b: 3.0,
|
||||
d: 2.0,
|
||||
ty: 1.0
|
||||
ty: Twips::new(1)
|
||||
},
|
||||
Matrix {
|
||||
a: 12.0,
|
||||
c: 9.0,
|
||||
tx: 9.0,
|
||||
tx: Twips::new(9),
|
||||
b: 39.0,
|
||||
d: 30.0,
|
||||
ty: 27.0
|
||||
ty: Twips::new(27)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 6.0,
|
||||
c: 5.0,
|
||||
tx: 4.0,
|
||||
tx: Twips::new(4),
|
||||
b: 3.0,
|
||||
d: 2.0,
|
||||
ty: 1.0
|
||||
ty: Twips::new(1)
|
||||
},
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 2.0,
|
||||
tx: 3.0,
|
||||
tx: Twips::new(3),
|
||||
b: 4.0,
|
||||
d: 5.0,
|
||||
ty: 6.0
|
||||
ty: Twips::new(6)
|
||||
},
|
||||
Matrix {
|
||||
a: 26.0,
|
||||
c: 37.0,
|
||||
tx: 52.0,
|
||||
tx: Twips::new(52),
|
||||
b: 11.0,
|
||||
d: 16.0,
|
||||
ty: 22.0
|
||||
ty: Twips::new(22)
|
||||
}
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 2.0,
|
||||
tx: 3.0,
|
||||
tx: Twips::new(3),
|
||||
b: 4.0,
|
||||
d: 5.0,
|
||||
ty: 6.0
|
||||
ty: Twips::new(6)
|
||||
},
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 2.0,
|
||||
tx: 3.0,
|
||||
tx: Twips::new(3),
|
||||
b: 4.0,
|
||||
d: 5.0,
|
||||
ty: 6.0
|
||||
ty: Twips::new(6)
|
||||
},
|
||||
Matrix {
|
||||
a: 9.0,
|
||||
c: 12.0,
|
||||
tx: 18.0,
|
||||
tx: Twips::new(18),
|
||||
b: 24.0,
|
||||
d: 33.0,
|
||||
ty: 48.0
|
||||
ty: Twips::new(48)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -453,10 +473,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 1.0,
|
||||
c: 0.0,
|
||||
tx: 10.0,
|
||||
tx: Twips::new(10),
|
||||
b: 0.0,
|
||||
d: 1.0,
|
||||
ty: 5.0
|
||||
ty: Twips::new(5)
|
||||
},
|
||||
(Twips::new(0), Twips::new(0)),
|
||||
(Twips::new(10), Twips::new(5))
|
||||
|
@ -465,25 +485,13 @@ mod tests {
|
|||
Matrix {
|
||||
a: 1.0,
|
||||
c: 0.0,
|
||||
tx: -200.0,
|
||||
tx: Twips::new(-200),
|
||||
b: 0.0,
|
||||
d: 1.0,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(50), Twips::new(20)),
|
||||
(Twips::new(-150), Twips::new(20))
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: 1.0,
|
||||
c: 0.0,
|
||||
tx: 1.125,
|
||||
b: 0.0,
|
||||
d: 1.0,
|
||||
ty: 1.925
|
||||
},
|
||||
(Twips::new(0), Twips::new(0)),
|
||||
(Twips::new(1), Twips::new(1))
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -494,10 +502,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 3.0,
|
||||
c: 0.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 0.0,
|
||||
d: 3.0,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(0), Twips::new(0)),
|
||||
(Twips::new(0), Twips::new(0))
|
||||
|
@ -506,10 +514,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 3.0,
|
||||
c: 0.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 0.0,
|
||||
d: 3.0,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(10), Twips::new(10)),
|
||||
(Twips::new(30), Twips::new(30))
|
||||
|
@ -518,10 +526,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 0.6,
|
||||
c: 0.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 0.0,
|
||||
d: 0.2,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(5), Twips::new(10)),
|
||||
(Twips::new(3), Twips::new(2))
|
||||
|
@ -530,10 +538,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 0.5,
|
||||
c: 0.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 0.0,
|
||||
d: 0.5,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(5), Twips::new(5)),
|
||||
(Twips::new(2), Twips::new(2))
|
||||
|
@ -547,10 +555,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 0.0,
|
||||
c: -1.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 1.0,
|
||||
d: 0.0,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(10), Twips::new(0)),
|
||||
(Twips::new(0), Twips::new(10))
|
||||
|
@ -559,10 +567,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 0.0,
|
||||
c: -1.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 1.0,
|
||||
d: 0.0,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(0), Twips::new(10)),
|
||||
(Twips::new(-10), Twips::new(0))
|
||||
|
@ -571,10 +579,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 0.0,
|
||||
c: 1.0,
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: -1.0,
|
||||
d: 0.0,
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(10), Twips::new(10)),
|
||||
(Twips::new(10), Twips::new(-10))
|
||||
|
@ -583,22 +591,22 @@ mod tests {
|
|||
Matrix {
|
||||
a: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
c: f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: -f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
d: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(100), Twips::new(0)),
|
||||
(Twips::new(70), Twips::new(-70))
|
||||
(Twips::new(71), Twips::new(-71))
|
||||
),
|
||||
(
|
||||
Matrix {
|
||||
a: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
c: f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: -f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
d: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(100), Twips::new(100)),
|
||||
(Twips::new(141), Twips::new(0))
|
||||
|
@ -613,10 +621,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 3.0 * f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
c: 3.0 * f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: 3.0 * -f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
d: 3.0 * f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
ty: 0.0
|
||||
ty: Twips::new(0)
|
||||
},
|
||||
(Twips::new(100), Twips::new(100)),
|
||||
(Twips::new(424), Twips::new(0))
|
||||
|
@ -626,10 +634,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: 3.0 * f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
c: 3.0 * f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
tx: -5.0,
|
||||
tx: Twips::new(-5),
|
||||
b: 3.0 * -f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
d: 3.0 * f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
ty: 5.0
|
||||
ty: Twips::new(5)
|
||||
},
|
||||
(Twips::new(100), Twips::new(100)),
|
||||
(Twips::new(419), Twips::new(5))
|
||||
|
@ -639,10 +647,10 @@ mod tests {
|
|||
Matrix {
|
||||
a: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
c: f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
tx: -5.0,
|
||||
tx: Twips::new(-5),
|
||||
b: -f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
d: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
ty: 5.0
|
||||
ty: Twips::new(5)
|
||||
},
|
||||
(Twips::new(100), Twips::new(100)),
|
||||
(Twips::new(136), Twips::new(5))
|
||||
|
@ -652,13 +660,38 @@ mod tests {
|
|||
Matrix {
|
||||
a: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
c: f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
tx: 0.0,
|
||||
tx: Twips::new(0),
|
||||
b: -f32::sin(std::f32::consts::FRAC_PI_4),
|
||||
d: f32::cos(std::f32::consts::FRAC_PI_4),
|
||||
ty: 10.0 * f32::sin(std::f32::consts::FRAC_PI_4)
|
||||
ty: Twips::new((10.0 * f32::sin(std::f32::consts::FRAC_PI_4)) as i32)
|
||||
},
|
||||
(Twips::new(105), Twips::new(95)),
|
||||
(Twips::new(141), Twips::new(0))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule.
|
||||
/// (e.g., both 1.5 and 2.5 will round to 2).
|
||||
/// This is the rounding method used by Flash for the above transforms.
|
||||
/// Although this is easy to do on most architectures, Rust provides no standard
|
||||
/// way to round in this manner (`f32::round` always rounds away from zero).
|
||||
/// For more info and the below code snippet, see: https://github.com/rust-lang/rust/issues/55107
|
||||
/// This also clamps out-of-range values and NaN to `i32::MIN`.
|
||||
/// TODO: Investigate using SSE/wasm intrinsics for this.
|
||||
fn round_to_i32(f: f32) -> i32 {
|
||||
if f.is_finite() {
|
||||
let a = f.abs();
|
||||
if f < 2_147_483_648.0_f32 {
|
||||
let k = 1.0 / std::f32::EPSILON;
|
||||
let out = if a < k { ((a + k) - k).copysign(f) } else { f };
|
||||
out as i32
|
||||
} else {
|
||||
// Out-of-range clamps to MIN.
|
||||
std::i32::MIN
|
||||
}
|
||||
} else {
|
||||
// NAN/Infinity goes to 0.
|
||||
0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -728,8 +728,8 @@ impl Player {
|
|||
b: 0.0,
|
||||
c: 0.0,
|
||||
d: scale,
|
||||
tx: margin_width * 20.0,
|
||||
ty: margin_height * 20.0,
|
||||
tx: Twips::from_pixels(margin_width.into()),
|
||||
ty: Twips::from_pixels(margin_height.into()),
|
||||
};
|
||||
self.inverse_view_matrix = self.view_matrix;
|
||||
self.inverse_view_matrix.invert();
|
||||
|
|
|
@ -181,10 +181,10 @@ swf_tests! {
|
|||
// Eventually we can hopefully make some of these match exactly (see #193).
|
||||
// Some will probably always need to be approx. (if they rely on trig functions, etc.)
|
||||
swf_tests_approx! {
|
||||
(local_to_global, "avm1/local_to_global", 1, 0.4),
|
||||
(local_to_global, "avm1/local_to_global", 1, 0.051),
|
||||
(stage_object_properties, "avm1/stage_object_properties", 4, 0.051),
|
||||
(stage_object_properties_swf6, "avm1/stage_object_properties_swf6", 4, 0.051),
|
||||
(movieclip_getbounds, "avm1/movieclip_getbounds", 1, 0.1),
|
||||
(movieclip_getbounds, "avm1/movieclip_getbounds", 1, 0.051),
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -710,8 +710,8 @@ impl RenderBackend for GliumRenderBackend {
|
|||
[transform.matrix.c, transform.matrix.d, 0.0, 0.0],
|
||||
[0.0, 0.0, 1.0, 0.0],
|
||||
[
|
||||
transform.matrix.tx / 20.0,
|
||||
transform.matrix.ty / 20.0,
|
||||
transform.matrix.tx.to_pixels() as f32,
|
||||
transform.matrix.ty.to_pixels() as f32,
|
||||
0.0,
|
||||
1.0,
|
||||
],
|
||||
|
|
|
@ -305,8 +305,8 @@ impl WebCanvasRenderBackend {
|
|||
matrix.b.into(),
|
||||
matrix.c.into(),
|
||||
matrix.d.into(),
|
||||
f64::from(matrix.tx) / 20.0,
|
||||
f64::from(matrix.ty) / 20.0,
|
||||
matrix.tx.to_pixels(),
|
||||
matrix.ty.to_pixels(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -774,8 +774,8 @@ fn swf_shape_to_svg(
|
|||
let shift = Matrix {
|
||||
a: 32768.0 / width,
|
||||
d: 32768.0 / height,
|
||||
tx: -16384.0,
|
||||
ty: -16384.0,
|
||||
tx: swf::Twips::new(-16384),
|
||||
ty: swf::Twips::new(-16384),
|
||||
..Default::default()
|
||||
};
|
||||
let gradient_matrix = matrix * shift;
|
||||
|
@ -821,8 +821,6 @@ fn swf_shape_to_svg(
|
|||
let shift = Matrix {
|
||||
a: 32768.0,
|
||||
d: 32768.0,
|
||||
tx: 0.0,
|
||||
ty: 0.0,
|
||||
..Default::default()
|
||||
};
|
||||
let gradient_matrix = matrix * shift;
|
||||
|
@ -874,8 +872,6 @@ fn swf_shape_to_svg(
|
|||
let shift = Matrix {
|
||||
a: 32768.0,
|
||||
d: 32768.0,
|
||||
tx: 0.0,
|
||||
ty: 0.0,
|
||||
..Default::default()
|
||||
};
|
||||
let gradient_matrix = matrix * shift;
|
||||
|
@ -1219,8 +1215,8 @@ fn swf_shape_to_canvas_commands(
|
|||
matrix.set_b(a.b);
|
||||
matrix.set_c(a.c);
|
||||
matrix.set_d(a.d);
|
||||
matrix.set_e(a.tx);
|
||||
matrix.set_f(a.ty);
|
||||
matrix.set_e(a.tx.get() as f32);
|
||||
matrix.set_f(a.ty.get() as f32);
|
||||
|
||||
bitmap_pattern.set_transform(&matrix);
|
||||
|
||||
|
|
Loading…
Reference in New Issue