canvas: Use Transform2D<f64> instead of Transform2D<f32> (#38316)

I mostly did dumb replacement so please check that this is correct. In
addition, `canvas_data::draw_with_shadow` needs some a bit of a closer
look.

Testing: This is covered by existing tests, and it is likely that WPT
tests are unaffected by the precision of the transform, even though it
is technically more correct.
Fixes: #38256

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
This commit is contained in:
Narfinger 2025-08-11 18:46:25 +02:00 committed by GitHub
parent 4ff1e8dbd9
commit 3f7f9ba6cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 91 additions and 97 deletions

View file

@ -20,7 +20,7 @@ pub(crate) trait GenericDrawTarget {
fn new(size: Size2D<u32>) -> Self;
fn create_similar_draw_target(&self, size: &Size2D<i32>) -> Self;
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>);
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>);
fn copy_surface(
&mut self,
surface: Self::SourceSurface,
@ -35,7 +35,7 @@ pub(crate) trait GenericDrawTarget {
source: Rect<f64>,
filter: Filter,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
);
fn draw_surface_with_shadow(
&self,
@ -50,7 +50,7 @@ pub(crate) trait GenericDrawTarget {
fill_rule: FillRule,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
);
fn fill_text(
&mut self,
@ -58,18 +58,18 @@ pub(crate) trait GenericDrawTarget {
start: Point2D<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
);
fn fill_rect(
&mut self,
rect: &Rect<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
);
fn get_size(&self) -> Size2D<i32>;
fn pop_clip(&mut self);
fn push_clip(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f32>);
fn push_clip(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f64>);
fn push_clip_rect(&mut self, rect: &Rect<i32>);
fn stroke(
&mut self,
@ -77,7 +77,7 @@ pub(crate) trait GenericDrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
);
fn stroke_rect(
&mut self,
@ -85,7 +85,7 @@ pub(crate) trait GenericDrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
);
fn surface(&mut self) -> Self::SourceSurface;
fn image_descriptor_and_serializable_data(

View file

@ -141,7 +141,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
smoothing_enabled: bool,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
// We round up the floating pixel values to draw the pixels
let source_rect = source_rect.ceil();
@ -194,7 +194,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
style: FillOrStrokeStyle,
text_options: &TextOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
// > Step 2: Replace all ASCII whitespace in text with U+0020 SPACE characters.
let text = replace_ascii_whitespace(text);
@ -299,7 +299,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
text_options: TextOptions,
_shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
let Some(ref font_style) = text_options.font else {
return;
@ -481,7 +481,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
style: FillOrStrokeStyle,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
if style.is_zero_size_gradient() {
return; // Paint nothing if gradient size is zero.
@ -512,7 +512,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
}
}
pub(crate) fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) {
pub(crate) fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) {
self.drawtarget.clear_rect(rect, transform);
}
@ -523,7 +523,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
line_options: LineOptions,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
if style.is_zero_size_gradient() {
return; // Paint nothing if gradient size is zero.
@ -571,7 +571,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
style: FillOrStrokeStyle,
_shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
if style.is_zero_size_gradient() {
return; // Paint nothing if gradient size is zero.
@ -597,7 +597,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
line_options: LineOptions,
_shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
if style.is_zero_size_gradient() {
return; // Paint nothing if gradient size is zero.
@ -620,7 +620,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
&mut self,
path: &Path,
fill_rule: FillRule,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.drawtarget.push_clip(path, fill_rule, transform);
}
@ -673,21 +673,23 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
rect: &Rect<f32>,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
draw_shadow_source: F,
) where
F: FnOnce(&mut DrawTarget, Transform2D<f32>),
F: FnOnce(&mut DrawTarget, Transform2D<f64>),
{
let shadow_src_rect = transform.outer_transformed_rect(rect);
let mut new_draw_target = self.create_draw_target_for_shadow(&shadow_src_rect);
let shadow_transform = transform.then(
&Transform2D::identity()
.pre_translate(-shadow_src_rect.origin.to_vector().cast::<f32>()),
);
let shadow_src_rect = transform.outer_transformed_rect(&rect.cast());
// Because this comes from the rect on f32 precision, casting it down should be ok.
let mut new_draw_target = self.create_draw_target_for_shadow(&shadow_src_rect.cast());
let shadow_transform = transform
.then(&Transform2D::identity().pre_translate(-shadow_src_rect.origin.to_vector()));
draw_shadow_source(&mut new_draw_target, shadow_transform);
self.drawtarget.draw_surface_with_shadow(
new_draw_target.surface(),
&Point2D::new(shadow_src_rect.origin.x, shadow_src_rect.origin.y),
&Point2D::new(
shadow_src_rect.origin.x as f32,
shadow_src_rect.origin.y as f32,
),
shadow_options,
composition_options,
);
@ -700,7 +702,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
path_bound_box: &Rect<f64>,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
draw_shape: F,
) where
F: FnOnce(&mut Self, FillOrStrokeStyle),
@ -778,7 +780,7 @@ fn write_image<DrawTarget: GenericDrawTarget>(
dest_rect: Rect<f64>,
smoothing_enabled: bool,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
if snapshot.size().is_empty() {
return;

View file

@ -371,7 +371,7 @@ impl Canvas {
text_options: TextOptions,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
match self {
#[cfg(feature = "raqote")]
@ -423,7 +423,7 @@ impl Canvas {
style: FillOrStrokeStyle,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
match self {
#[cfg(feature = "raqote")]
@ -449,7 +449,7 @@ impl Canvas {
line_options: LineOptions,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
match self {
#[cfg(feature = "raqote")]
@ -490,7 +490,7 @@ impl Canvas {
style: FillOrStrokeStyle,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
match self {
#[cfg(feature = "raqote")]
@ -531,7 +531,7 @@ impl Canvas {
line_options: LineOptions,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
match self {
#[cfg(feature = "raqote")]
@ -565,7 +565,7 @@ impl Canvas {
}
}
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) {
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) {
match self {
#[cfg(feature = "raqote")]
Canvas::Raqote(canvas_data) => canvas_data.clear_rect(rect, transform),
@ -585,7 +585,7 @@ impl Canvas {
smoothing_enabled: bool,
shadow_options: ShadowOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
match self {
#[cfg(feature = "raqote")]
@ -646,7 +646,7 @@ impl Canvas {
}
}
fn clip_path(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f32>) {
fn clip_path(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f64>) {
match self {
#[cfg(feature = "raqote")]
Canvas::Raqote(canvas_data) => canvas_data.clip_path(path, fill_rule, transform),

View file

@ -184,7 +184,7 @@ impl GenericDrawTarget for raqote::DrawTarget {
raqote::DrawTarget::new(size.width as i32, size.height as i32)
}
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) {
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) {
<Self as GenericDrawTarget>::fill_rect(
self,
rect,
@ -230,7 +230,7 @@ impl GenericDrawTarget for raqote::DrawTarget {
src: Rect<f64>,
filter: Filter,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
let paint_transform =
raqote::Transform::translation(-dest.origin.x as f32, -dest.origin.y as f32)
@ -239,7 +239,7 @@ impl GenericDrawTarget for raqote::DrawTarget {
src.size.height as f32 / dest.size.height as f32,
);
self.set_transform(&transform);
self.set_transform(&transform.cast());
let dest = dest.cast();
let mut pb = raqote::PathBuilder::new();
pb.rect(
@ -280,9 +280,9 @@ impl GenericDrawTarget for raqote::DrawTarget {
fill_rule: FillRule,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.set_transform(&transform);
self.set_transform(&transform.cast());
let draw_options = draw_options(composition_options);
let pattern = style.to_raqote_pattern();
let mut path = to_path(path);
@ -299,9 +299,9 @@ impl GenericDrawTarget for raqote::DrawTarget {
start: Point2D<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.set_transform(&transform);
self.set_transform(&transform.cast());
let draw_options = draw_options(composition_options);
let pattern = style.to_raqote_pattern();
let mut advance = 0.;
@ -362,7 +362,7 @@ impl GenericDrawTarget for raqote::DrawTarget {
rect: &Rect<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
let rect = rect.cast();
let mut pb = canvas_traits::canvas::Path::new();
@ -392,9 +392,9 @@ impl GenericDrawTarget for raqote::DrawTarget {
&mut self,
path: &canvas_traits::canvas::Path,
fill_rule: FillRule,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.set_transform(&transform);
self.set_transform(&transform.cast());
let mut path = to_path(path);
path.winding = match fill_rule {
FillRule::Nonzero => raqote::Winding::NonZero,
@ -414,11 +414,11 @@ impl GenericDrawTarget for raqote::DrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
let pattern = style.to_raqote_pattern();
let options = draw_options(composition_options);
self.set_transform(&transform);
self.set_transform(&transform.cast());
self.stroke(
&to_path(path),
&source(&pattern),
@ -432,9 +432,9 @@ impl GenericDrawTarget for raqote::DrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.set_transform(&transform);
self.set_transform(&transform.cast());
let pattern = style.to_raqote_pattern();
let options = draw_options(composition_options);
let mut pb = raqote::PathBuilder::new();

View file

@ -169,8 +169,8 @@ impl VelloDrawTarget {
}
}
fn is_viewport_cleared(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) -> bool {
let transformed_rect = transform.outer_transformed_rect(rect);
fn is_viewport_cleared(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) -> bool {
let transformed_rect = transform.outer_transformed_rect(&rect.cast());
if transformed_rect.is_empty() {
return false;
}
@ -239,7 +239,7 @@ impl GenericDrawTarget for VelloDrawTarget {
Self::new_with_renderer(device, queue, Rc::new(RefCell::new(renderer)), size)
}
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) {
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) {
// vello scene only ever grows,
// so we use every opportunity to shrink it
if self.is_viewport_cleared(rect, transform) {
@ -250,7 +250,7 @@ impl GenericDrawTarget for VelloDrawTarget {
}
self.ensure_drawing();
let rect: kurbo::Rect = rect.cast().into();
let transform = transform.cast().into();
let transform = transform.into();
self.scene
.push_layer(peniko::Compose::Clear, 0.0, transform, &rect);
self.scene.fill(
@ -310,7 +310,7 @@ impl GenericDrawTarget for VelloDrawTarget {
source: Rect<f64>,
filter: Filter,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
let scale_up = dest.size.width > source.size.width || dest.size.height > source.size.height;
@ -367,7 +367,7 @@ impl GenericDrawTarget for VelloDrawTarget {
fill_rule: FillRule,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.with_composition(composition_options.composition_operation, |self_| {
@ -387,7 +387,7 @@ impl GenericDrawTarget for VelloDrawTarget {
start: Point2D<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
let pattern = convert_to_brush(style, composition_options);
@ -448,7 +448,7 @@ impl GenericDrawTarget for VelloDrawTarget {
rect: &Rect<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
let pattern = convert_to_brush(style, composition_options);
@ -471,7 +471,7 @@ impl GenericDrawTarget for VelloDrawTarget {
}
}
fn push_clip(&mut self, path: &Path, _fill_rule: FillRule, transform: Transform2D<f32>) {
fn push_clip(&mut self, path: &Path, _fill_rule: FillRule, transform: Transform2D<f64>) {
self.scene
.push_layer(peniko::Mix::Clip, 1.0, transform.cast().into(), &path.0);
let mut path = path.clone();
@ -497,7 +497,7 @@ impl GenericDrawTarget for VelloDrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.with_composition(composition_options.composition_operation, |self_| {
@ -517,7 +517,7 @@ impl GenericDrawTarget for VelloDrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
let rect: kurbo::Rect = rect.cast().into();

View file

@ -126,8 +126,8 @@ impl VelloCPUDrawTarget {
Size2D::new(self.ctx.width(), self.ctx.height()).cast()
}
fn is_viewport_cleared(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) -> bool {
let transformed_rect = transform.outer_transformed_rect(rect);
fn is_viewport_cleared(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) -> bool {
let transformed_rect = transform.outer_transformed_rect(&rect.cast());
if transformed_rect.is_empty() {
return false;
}
@ -156,7 +156,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
}
}
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f32>) {
fn clear_rect(&mut self, rect: &Rect<f32>, transform: Transform2D<f64>) {
// vello_cpu RenderingContext only ever grows,
// so we need to use every opportunity to shrink it
if self.is_viewport_cleared(rect, transform) {
@ -217,7 +217,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
source: Rect<f64>,
filter: Filter,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
let scale_up = dest.size.width > source.size.width || dest.size.height > source.size.height;
@ -272,7 +272,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
fill_rule: FillRule,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.with_composition(composition_options.composition_operation, |self_| {
@ -290,7 +290,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
start: Point2D<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.ctx.set_paint(paint(style, composition_options.alpha));
@ -348,7 +348,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
rect: &Rect<f32>,
style: FillOrStrokeStyle,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.with_composition(composition_options.composition_operation, |self_| {
@ -368,7 +368,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
}
}
fn push_clip(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f32>) {
fn push_clip(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f64>) {
self.ctx.set_transform(transform.cast().into());
let mut path = path.clone();
path.transform(transform.cast());
@ -396,7 +396,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.with_composition(composition_options.composition_operation, |self_| {
@ -413,7 +413,7 @@ impl GenericDrawTarget for VelloCPUDrawTarget {
style: FillOrStrokeStyle,
line_options: LineOptions,
composition_options: CompositionOptions,
transform: Transform2D<f32>,
transform: Transform2D<f64>,
) {
self.ensure_drawing();
self.with_composition(composition_options.composition_operation, |self_| {

View file

@ -105,7 +105,7 @@ pub(crate) struct CanvasContextState {
line_dash: Vec<f64>,
line_dash_offset: f64,
#[no_trace]
transform: Transform2D<f32>,
transform: Transform2D<f64>,
shadow_offset_x: f64,
shadow_offset_y: f64,
shadow_blur: f64,
@ -1005,7 +1005,7 @@ impl CanvasState {
(source_rect, dest_rect)
}
fn update_transform(&self, transform: Transform2D<f32>) {
fn update_transform(&self, transform: Transform2D<f64>) {
let mut state = self.state.borrow_mut();
self.current_default_path
.borrow_mut()
@ -1991,7 +1991,7 @@ impl CanvasState {
}
let transform = self.state.borrow().transform;
self.update_transform(transform.pre_scale(x as f32, y as f32))
self.update_transform(transform.pre_scale(x, y))
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-rotate
@ -2002,10 +2002,7 @@ impl CanvasState {
let (sin, cos) = (angle.sin(), angle.cos());
let transform = self.state.borrow().transform;
self.update_transform(
Transform2D::new(cos as f32, sin as f32, -sin as f32, cos as f32, 0.0, 0.0)
.then(&transform),
)
self.update_transform(Transform2D::new(cos, sin, -sin, cos, 0.0, 0.0).then(&transform))
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-translate
@ -2015,7 +2012,7 @@ impl CanvasState {
}
let transform = self.state.borrow().transform;
self.update_transform(transform.pre_translate(vec2(x as f32, y as f32)))
self.update_transform(transform.pre_translate(vec2(x, y)))
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-transform
@ -2031,16 +2028,13 @@ impl CanvasState {
}
let transform = self.state.borrow().transform;
self.update_transform(
Transform2D::new(a as f32, b as f32, c as f32, d as f32, e as f32, f as f32)
.then(&transform),
)
self.update_transform(Transform2D::new(a, b, c, d, e, f).then(&transform))
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-gettransform
pub(crate) fn get_transform(&self, global: &GlobalScope, can_gc: CanGc) -> DomRoot<DOMMatrix> {
let transform = self.state.borrow_mut().transform;
DOMMatrix::new(global, true, transform.cast::<f64>().to_3d(), can_gc)
DOMMatrix::new(global, true, transform.to_3d(), can_gc)
}
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform>
@ -2057,9 +2051,7 @@ impl CanvasState {
}
// Step 2. Reset the current transformation matrix to the matrix described by:
self.update_transform(Transform2D::new(
a as f32, b as f32, c as f32, d as f32, e as f32, f as f32,
))
self.update_transform(Transform2D::new(a, b, c, d, e, f))
}
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform-matrix>

View file

@ -462,7 +462,7 @@ pub enum Canvas2dMsg {
bool,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
DrawEmptyImage(
Size2D<u32>,
@ -470,7 +470,7 @@ pub enum Canvas2dMsg {
Rect<f64>,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
DrawImageInOther(
CanvasId,
@ -479,10 +479,10 @@ pub enum Canvas2dMsg {
bool,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
ClearRect(Rect<f32>, Transform2D<f32>),
ClipPath(Path, FillRule, Transform2D<f32>),
ClearRect(Rect<f32>, Transform2D<f64>),
ClipPath(Path, FillRule, Transform2D<f64>),
PopClips(usize),
FillPath(
FillOrStrokeStyle,
@ -490,7 +490,7 @@ pub enum Canvas2dMsg {
FillRule,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
FillText(
String,
@ -502,14 +502,14 @@ pub enum Canvas2dMsg {
TextOptions,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
FillRect(
Rect<f32>,
FillOrStrokeStyle,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
GetImageData(Option<Rect<u32>>, IpcSender<IpcSnapshot>),
MeasureText(String, IpcSender<TextMetrics>, TextOptions),
@ -520,7 +520,7 @@ pub enum Canvas2dMsg {
LineOptions,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
StrokePath(
Path,
@ -528,7 +528,7 @@ pub enum Canvas2dMsg {
LineOptions,
ShadowOptions,
CompositionOptions,
Transform2D<f32>,
Transform2D<f64>,
),
UpdateImage(IpcSender<()>),
}