From 2b97ce77a34a14367edc24f8942d9d09ee014042 Mon Sep 17 00:00:00 2001 From: Frederic Freyer Date: Wed, 24 Jan 2024 13:48:55 +0100 Subject: [PATCH] Fix CairoMakie transforms (#3552) * use plot transform_func * maybe improve compile time * use plot transform_func for the other overrides too * update NEWS * add refimg test --------- Co-authored-by: Simon --- CairoMakie/src/overrides.jl | 10 +++++----- CairoMakie/src/primitives.jl | 6 +++--- CairoMakie/src/utils.jl | 8 ++++---- NEWS.md | 2 ++ ReferenceTests/src/tests/primitives.jl | 27 ++++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/CairoMakie/src/overrides.jl b/CairoMakie/src/overrides.jl index 8bccdca5d3c..ec84e83444d 100644 --- a/CairoMakie/src/overrides.jl +++ b/CairoMakie/src/overrides.jl @@ -45,7 +45,7 @@ end function draw_poly(scene::Scene, screen::Screen, poly, points::Vector{<:Point2}, color::Union{Colorant, Cairo.CairoPattern}, model, strokecolor, strokestyle, strokewidth) space = to_value(get(poly, :space, :data)) - points = project_position.(Ref(scene), space, points, Ref(model)) + points = project_position.(Ref(poly), space, points, Ref(model)) Cairo.move_to(screen.context, points[1]...) for p in points[2:end] Cairo.line_to(screen.context, p...) @@ -78,7 +78,7 @@ draw_poly(scene::Scene, screen::Screen, poly, bezierpath::BezierPath) = draw_pol function draw_poly(scene::Scene, screen::Screen, poly, shapes::Vector{<:Union{Rect2,BezierPath}}) model = poly.model[] space = to_value(get(poly, :space, :data)) - projected_shapes = project_shape.(Ref(scene), space, shapes, Ref(model)) + projected_shapes = project_shape.(Ref(poly), space, shapes, Ref(model)) color = to_cairo_color(poly.color[], poly) @@ -175,7 +175,7 @@ end function draw_poly(scene::Scene, screen::Screen, poly, polygons::AbstractArray{<: MultiPolygon}) model = poly.model[] space = to_value(get(poly, :space, :data)) - projected_polys = project_multipolygon.(Ref(scene), space, polygons, Ref(model)) + projected_polys = project_multipolygon.(Ref(poly), space, polygons, Ref(model)) color = to_cairo_color(poly.color[], poly) strokecolor = to_cairo_color(poly.strokecolor[], poly) @@ -211,7 +211,7 @@ function draw_plot(scene::Scene, screen::Screen, points = vcat(lowerpoints, reverse(upperpoints)) model = band.model[] space = to_value(get(band, :space, :data)) - points = project_position.(Ref(scene), space, points, Ref(model)) + points = project_position.(Ref(band), space, points, Ref(model)) Cairo.move_to(screen.context, points[1]...) for p in points[2:end] Cairo.line_to(screen.context, p...) @@ -249,7 +249,7 @@ function draw_plot(scene::Scene, screen::Screen, tric::Tricontourf) polygons = pol[1][] model = pol.model[] space = to_value(get(pol, :space, :data)) - projected_polys = project_polygon.(Ref(scene), space, polygons, Ref(model)) + projected_polys = project_polygon.(Ref(tric), space, polygons, Ref(model)) function draw_tripolys(polys, colornumbers, colors) for (i, (pol, colnum, col)) in enumerate(zip(polys, colornumbers, colors)) diff --git a/CairoMakie/src/primitives.jl b/CairoMakie/src/primitives.jl index a37415d761b..b1c14e648c9 100644 --- a/CairoMakie/src/primitives.jl +++ b/CairoMakie/src/primitives.jl @@ -50,7 +50,7 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio end if primitive isa Lines && to_value(primitive.args[1]) isa BezierPath - return draw_bezierpath_lines(ctx, to_value(primitive.args[1]), scene, color, space, model, linewidth) + return draw_bezierpath_lines(ctx, to_value(primitive.args[1]), primitive, color, space, model, linewidth) end if color isa AbstractArray || linewidth isa AbstractArray @@ -728,8 +728,8 @@ function draw_atomic(scene::Scene, screen::Screen, @nospecialize(primitive::Unio # find projected image corners # this already takes care of flipping the image to correct cairo orientation space = to_value(get(primitive, :space, :data)) - xy = project_position(scene, space, Point2f(first.(imsize)), model) - xymax = project_position(scene, space, Point2f(last.(imsize)), model) + xy = project_position(primitive, space, Point2f(first.(imsize)), model) + xymax = project_position(primitive, space, Point2f(last.(imsize)), model) w, h = xymax .- xy can_use_fast_path = !(is_vector && !interpolate) && regular_grid && identity_transform && diff --git a/CairoMakie/src/utils.jl b/CairoMakie/src/utils.jl index e22b8938dc0..9f87e61af9d 100644 --- a/CairoMakie/src/utils.jl +++ b/CairoMakie/src/utils.jl @@ -24,7 +24,7 @@ function _project_position(scene::Scene, space, point, model, yflip::Bool) return p_0_to_1 .* res end -function project_position(scenelike, space, point, model, yflip::Bool = true) +function project_position(@nospecialize(scenelike), space, point, model, yflip::Bool = true) scene = Makie.get_scene(scenelike) project_position(scene, Makie.transform_func(scenelike), space, point, model, yflip) end @@ -47,13 +47,13 @@ function project_scale(scene::Scene, space, s, model = Mat4f(I)) end end -function project_shape(scenelike, space, rect::Rect, model) +function project_shape(@nospecialize(scenelike), space, rect::Rect, model) mini = project_position(scenelike, space, minimum(rect), model) maxi = project_position(scenelike, space, maximum(rect), model) return Rect(mini, maxi .- mini) end -function project_polygon(scenelike, space, poly::P, model) where P <: Polygon +function project_polygon(@nospecialize(scenelike), space, poly::P, model) where P <: Polygon ext = decompose(Point2f, poly.exterior) interiors = decompose.(Point2f, poly.interiors) Polygon( @@ -62,7 +62,7 @@ function project_polygon(scenelike, space, poly::P, model) where P <: Polygon ) end -function project_multipolygon(scenelike, space, multipoly::MP, model) where MP <: MultiPolygon +function project_multipolygon(@nospecialize(scenelike), space, multipoly::MP, model) where MP <: MultiPolygon return MultiPolygon(project_polygon.(Ref(scenelike), Ref(space), multipoly.polygons, Ref(model))) end diff --git a/NEWS.md b/NEWS.md index 093b9c07d0f..43043985961 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## master +- Use plot plot instead of scene transform functions in CairoMakie, fixing missplaced h/vspan. [#3552](https://github.com/MakieOrg/Makie.jl/pull/3552) + ## 0.20.4 - Changes for Bonito rename and WGLMakie docs improvements [#3477](https://github.com/MakieOrg/Makie.jl/pull/3477). diff --git a/ReferenceTests/src/tests/primitives.jl b/ReferenceTests/src/tests/primitives.jl index 7e6083f7c9c..79e495b0dbd 100644 --- a/ReferenceTests/src/tests/primitives.jl +++ b/ReferenceTests/src/tests/primitives.jl @@ -474,3 +474,30 @@ end fig end + +@reference_test "Plot transform overwrite" begin + # Tests that (primitive) plots can have different transform function to their + # parent scene (identity in this case) + fig = Figure() + + ax = Axis(fig[1, 1], xscale = log10, yscale = log10, backgroundcolor = :transparent) + xlims!(ax, 1, 10) + ylims!(ax, 1, 10) + empty!(ax.scene.lights) + hidedecorations!(ax) + + heatmap!(ax, 0..0.5, 0..0.5, [i+j for i in 1:10, j in 1:10], transformation = Transformation()) + image!(ax, 0..0.5, 0.5..1, [i+j for i in 1:10, j in 1:10], transformation = Transformation()) + mesh!(ax, Rect2f(0.5, 0.0, 1.0, 0.25), transformation = Transformation(), color = :green) + p = surface!(ax, 0.5..1, 0.25..0.75, [i+j for i in 1:10, j in 1:10], transformation = Transformation()) + translate!(p, Vec3f(0, 0, -20)) + poly!(ax, Rect2f(0.5, 0.75, 1.0, 1.0), transformation = Transformation(), color = :blue) + + lines!(ax, [0, 1], [0, 0.1], linewidth = 10, color = :red, transformation = Transformation()) + linesegments!(ax, [0, 1], [0.2, 0.3], linewidth = 10, color = :red, transformation = Transformation()) + scatter!(ax, [0.1, 0.9], [0.4, 0.5], markersize = 50, color = :red, transformation = Transformation()) + text!(ax, Point2f(0.5, 0.45), text = "Test", fontsize = 50, color = :red, align = (:center, :center), transformation = Transformation()) + meshscatter!(ax, [0.1, 0.9], [0.6, 0.7], markersize = 0.05, color = :red, transformation = Transformation()) + + fig +end \ No newline at end of file