Skip to content

Commit

Permalink
Support parsing Q/q in BezierPath (#4413)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielVandH authored Sep 27, 2024
1 parent b6658b9 commit 44d00b4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Show DataInspector tooltip on NaN values if `nan_color` has been set to other than `:transparent` [#4310](https://github.com/MakieOrg/Makie.jl/pull/4310)
- Fix `linestyle` not being used in `triplot` [#4332](https://github.com/MakieOrg/Makie.jl/pull/4332)
- Fix voxel clipping not being based on voxel centers [#4397](https://github.com/MakieOrg/Makie.jl/pull/4397)
- Parsing `Q` and `q` commands in svg paths with `BezierPath` is now supported [#4413](https://github.com/MakieOrg/Makie.jl/pull/4413)

## [0.21.11] - 2024-09-13

Expand Down
23 changes: 23 additions & 0 deletions src/bezier.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ CurveTo(cx1, cy1, cx2, cy2, p1, p2) = CurveTo(
Point2d(cx1, cy1), Point2d(cx2, cy2), Point2d(p1, p2)
)

"""
quadratic_curve_to(x0::Real, y0::Real, cx1::Real, cy1::Real, p1::Real, p2::Real)
A path command for use within a `BezierPath` which continues the current subpath with a quadratic
bezier curve to point `p`, with the control point `c`. The curve is converted into a cubic bezier
curve internally.
"""
quadratic_curve_to(x0, y0, cx1, cy1, p1, p2) = CurveTo(
x0 + 2/3 * (cx1 - x0), y0 + 2/3 * (cy1 - y0),
p1 + 2/3 * (cx1 - p1), p2 + 2/3 * (cy1 - p2),
p1, p2
)

"""
EllipticalArc(c::VecTypes, r1::Real, r2::Real, angle::Real, a1::Real, a2::Real)
EllipticalArc(cx::Real, cy::Real, r1::Real, r2::Real, angle::Real, a1::Real, a2::Real)
Expand Down Expand Up @@ -492,6 +505,16 @@ function parse_bezier_commands(svg)
l = lastp()
push!(commands, LineTo(Point2d(l[1], y)))
i += 2
elseif comm == "Q"
x0, y0 = lastp()
x1, y1, x2, y2 = parse.(Float64, args[i+1:i+4])
push!(commands, quadratic_curve_to(x0, y0, x1, y1, x2, y2))
i += 5
elseif comm == "q"
x0, y0 = lastp()
x1, y1, x2, y2 = parse.(Float64, args[i+1:i+4])
push!(commands, quadratic_curve_to(x0, y0, x1 + x0, y1 + y0, x2 + x0, y2 + y0))
i += 5
else
for c in commands
println(c)
Expand Down
16 changes: 15 additions & 1 deletion test/bezier.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ using Makie, Test
@test_nowarn BezierPath("m 0,9 L 0,5138 0,9 z")
@test_broken BezierPath("m 0,1e-5 L 0,5138 0,9 z") isa BezierPath
@test_nowarn BezierPath("M 100,100 C 100,200 200,100 200,200 z")
@test_broken BezierPath("M 100,100 Q 50,150,100,100 z") isa BezierPath
@test_nowarn BezierPath("M 100,100 Q 50,150,100,100 z") isa BezierPath
@test_broken BezierPath("M 3.0 10.0 A 10.0 7.5 0.0 0.0 0.0 20.0 15.0 z") isa BezierPath
end

@testset "Parsing Q/q" begin
x0, y0, x1, y1, x, y = 5.0, 0.0, 14.6, 5.2, 13.0, 15.9
C = Makie.quadratic_curve_to(x0, y0, x1, y1, x, y)
C2 = Makie.CurveTo(x0 + 2 / 3 * (x1 - x0), y0 + 2 / 3 * (y1 - y0), x + 2 / 3 * (x1 - x),
y + 2 / 3 * (y1 - y),
x, y)
@test C == C2
path = BezierPath("M 5.0 0.0 Q 14.6 5.2 13.0 15.9")
@test path.commands[2] == C2
path = BezierPath("M 5.0 0.0 q 0.2 2.3 1.0 -2.0")
C = Makie.quadratic_curve_to(x0, y0, x0 + 0.2, y0 + 2.3, x0 + 1.0, y0 - 2.0)
@test path.commands[2] == C
end

0 comments on commit 44d00b4

Please sign in to comment.