Skip to content

Commit

Permalink
Merge pull request #68 from JuliaGizmos/teh/unit_conversion
Browse files Browse the repository at this point in the history
Perform unit conversions manually from cairomatrix
  • Loading branch information
timholy authored Jun 14, 2018
2 parents 8179c20 + 038e563 commit c1ea14b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
19 changes: 17 additions & 2 deletions src/graphics_interaction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Base.:>{U<:CairoUnit}(x::U, y::U) = Bool(x.val > y.val)
Base.abs{U<:CairoUnit}(x::U) = U(abs(x.val))
Base.min{U<:CairoUnit}(x::U, y::U) = U(min(x.val, y.val))
Base.max{U<:CairoUnit}(x::U, y::U) = U(max(x.val, y.val))
Base.isapprox(x::U, y::U; kwargs...) where U<:CairoUnit =
isapprox(x.val, y.val; kwargs...)
# Most of these are for ambiguity resolution
Base.convert{T<:CairoUnit}(::Type{T}, x::T) = x
Base.convert(::Type{Bool}, x::CairoUnit) = convert(Bool, x.val)
Expand Down Expand Up @@ -57,7 +59,15 @@ Base.promote_rule{U<:UserUnit,D<:DeviceUnit}(::Type{U}, ::Type{D}) =
error("UserUnit and DeviceUnit are incompatible, promotion not defined")

function convertunits(::Type{UserUnit}, c, x::DeviceUnit, y::DeviceUnit)
xu, yu = device_to_user(getgc(c), x.val, y.val)
# For some unknown reason, the following doesn't seem to work
# over a remote X connection:
# xu, yu = device_to_user(getgc(c), x.val, y.val)
# So just do the inversion directly (see https://www.cairographics.org/manual/cairo-cairo-matrix-t.html#cairo-matrix-t)
m = Cairo.get_matrix(getgc(c))
Δx, Δy = x.val - m.x0, y.val - m.y0
det = m.xx * m.yy - m.yx * m.xy # manually do inverse of 2x2 matrix
xu, yu = (m.yy * Δx - m.xy * Δy)/det, (-m.yx * Δx + m.xx * Δy)/det

UserUnit(xu), UserUnit(yu)
end
function convertunits(::Type{UserUnit}, c, x::UserUnit, y::UserUnit)
Expand All @@ -67,7 +77,12 @@ function convertunits(::Type{DeviceUnit}, c, x::DeviceUnit, y::DeviceUnit)
x, y
end
function convertunits(::Type{DeviceUnit}, c, x::UserUnit, y::UserUnit)
xd, yd = user_to_device(getgc(c), x.val, y.val)
# See above
# xd, yd = user_to_device(getgc(c), x.val, y.val)
m = Cairo.get_matrix(getgc(c))
xd = m.xx * x.val + m.xy * y.val + m.x0
yd = m.yx * x.val + m.yy * y.val + m.y0

DeviceUnit(xd), DeviceUnit(yd)
end

Expand Down
12 changes: 8 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ using GtkReactive, Gtk.ShortNames, IntervalSets, Graphics, Colors,
TestImages, FileIO, FixedPointNumbers, RoundingIntegers
using Base.Test

if !istaskdone(Reactive.runner_task)
rtask = Reactive.runner_task # starting with Reactive 0.7.0, this became a Ref
if isa(rtask, Base.RefValue)
rtask = rtask[]
end
if !istaskdone(rtask)
Reactive.stop()
wait(Reactive.runner_task)
wait(rtask)
end

include("tools.jl")
Expand Down Expand Up @@ -242,7 +246,7 @@ include("tools.jl")
@test value(pb) == 5
pb = progressbar(2:8)
@test value(pb) == 2

end

## button
Expand Down Expand Up @@ -348,7 +352,7 @@ end
(ZoomRegion((5:10, 3:5)), (UserUnit(5), UserUnit(10))),
((-1:1, 101:110), (UserUnit(110), UserUnit(1))))
set_coordinates(c, coords)
@test GtkReactive.convertunits(UserUnit, c, corner_dev...) == corner_usr
@test all(GtkReactive.convertunits(UserUnit, c, corner_dev...) .≈ corner_usr)
@test GtkReactive.convertunits(DeviceUnit, c, corner_dev...) == corner_dev
@test GtkReactive.convertunits(UserUnit, c, corner_usr...) == corner_usr
@test GtkReactive.convertunits(DeviceUnit, c, corner_usr...) == corner_dev
Expand Down

0 comments on commit c1ea14b

Please sign in to comment.