diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 29ea5a66..dafa8f6f 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -33,6 +33,7 @@ use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, RenderTarget, S use std::borrow::Cow; use std::default::Default; use std::f32::consts::PI; +use std::f32; use std::fmt::{Debug, Error as FmtError, Formatter}; use std::mem; use std::sync::Arc; @@ -274,8 +275,9 @@ impl CanvasRenderingContext2D { // The smaller scale is relevant here, as we multiply by it and want to ensure it is always // bigger than `HAIRLINE_STROKE_WIDTH`. - let transform_scale = f32::min(self.current_state.transform.m11(), - self.current_state.transform.m22()); + let transform_scales = self.current_state.transform.extract_scale(); + let transform_scale = f32::min(transform_scales.x(), transform_scales.y()); + // Avoid the division in the normal case of sufficient thickness. if stroke_style.line_width * transform_scale < HAIRLINE_STROKE_WIDTH { stroke_style.line_width = HAIRLINE_STROKE_WIDTH / transform_scale; diff --git a/geometry/src/transform2d.rs b/geometry/src/transform2d.rs index acd462e4..8b139852 100644 --- a/geometry/src/transform2d.rs +++ b/geometry/src/transform2d.rs @@ -76,6 +76,13 @@ impl Matrix2x2F { Matrix2x2F(self.0 * F32x4::splat(factor)) } + /// Extracts the scale from this matrix. + #[inline] + pub fn extract_scale(&self) -> Vector2F { + let squared = self.0 * self.0; + Vector2F((squared.xy() + squared.zw()).sqrt()) + } + #[inline] pub fn m11(&self) -> f32 { self.0[0] @@ -212,6 +219,12 @@ impl Transform2F { *self == Transform2F::default() } + /// Extracts the scale from this matrix. + #[inline] + pub fn extract_scale(&self) -> Vector2F { + self.matrix.extract_scale() + } + #[inline] pub fn m11(&self) -> f32 { self.matrix.m11()