mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Implement decompose_matrix function
This commit is contained in:
parent
1901a21a2c
commit
32810a9f9e
1 changed files with 87 additions and 0 deletions
|
@ -21,6 +21,7 @@ use properties::longhands::z_index::computed_value::T as ZIndex;
|
|||
use std::cmp;
|
||||
use std::fmt;
|
||||
use super::ComputedValues;
|
||||
use values::CSSFloat;
|
||||
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
||||
use values::computed::{BorderRadiusSize, LengthOrNone};
|
||||
use values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
|
||||
|
@ -757,6 +758,92 @@ impl Interpolate for LengthOrNone {
|
|||
TransformList(Some(result))
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct DecomposedMatrix {
|
||||
pub m11: CSSFloat, pub m12: CSSFloat,
|
||||
pub m21: CSSFloat, pub m22: CSSFloat,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct Translate2D(f32, f32);
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct Scale2D(f32, f32);
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct MatrixDecomposed2D {
|
||||
pub translate: Translate2D,
|
||||
pub scale: Scale2D,
|
||||
pub angle: f32,
|
||||
pub matrix: DecomposedMatrix,
|
||||
}
|
||||
|
||||
/// Decompose a matrix.
|
||||
/// https://drafts.csswg.org/css-transforms/#decomposing-a-2d-matrix
|
||||
fn decompose_matrix(matrix: ComputedMatrix) -> MatrixDecomposed2D {
|
||||
let mut row0x = matrix.m11;
|
||||
let mut row0y = matrix.m12;
|
||||
let mut row1x = matrix.m21;
|
||||
let mut row1y = matrix.m22;
|
||||
|
||||
let translate = Translate2D(matrix.m41, matrix.m42);
|
||||
let mut scale = Scale2D((row0x * row0x + row0y * row0y).sqrt(),
|
||||
(row1x * row1x + row1y * row1y).sqrt());
|
||||
|
||||
// If determinant is negative, one axis was flipped.
|
||||
let determinant = row0x * row1y - row0y * row1x;
|
||||
if determinant < 0. {
|
||||
if row0x < row1y {
|
||||
scale.0 = -scale.0;
|
||||
} else {
|
||||
scale.1 = -scale.1;
|
||||
}
|
||||
}
|
||||
|
||||
// Renormalize matrix to remove scale.
|
||||
if scale.0 != 0.0 {
|
||||
row0x *= 1. / scale.0;
|
||||
row0y *= 1. / scale.0;
|
||||
}
|
||||
if scale.1 != 0.0 {
|
||||
row1x *= 1. / scale.1;
|
||||
row1y *= 1. / scale.1;
|
||||
}
|
||||
|
||||
// Compute rotation and renormalize matrix.
|
||||
let mut angle = row0y.atan2(row0x);
|
||||
if angle != 0.0 {
|
||||
let sn = -row0y;
|
||||
let cs = row0x;
|
||||
let m11 = row0x;
|
||||
let m12 = row0y;
|
||||
let m21 = row1x;
|
||||
let m22 = row1y;
|
||||
row0x = cs * m11 + sn * m21;
|
||||
row0y = cs * m12 + sn * m22;
|
||||
row1x = -sn * m11 + cs * m21;
|
||||
row1y = -sn * m12 + cs * m22;
|
||||
}
|
||||
|
||||
let m = DecomposedMatrix {
|
||||
m11: row0x, m12: row0y,
|
||||
m21: row1x, m22: row1y,
|
||||
};
|
||||
|
||||
// Convert into degrees because our rotation functions expect it.
|
||||
angle = angle.to_degrees();
|
||||
MatrixDecomposed2D {
|
||||
translate: translate,
|
||||
scale: scale,
|
||||
angle: angle,
|
||||
matrix: m,
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
|
||||
impl Interpolate for TransformList {
|
||||
#[inline]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue