From a6c2b0b059c881c548110fd9c80bafc77c375473 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Thu, 23 Mar 2017 18:27:36 -0400 Subject: [PATCH] Significantly improve :dpi support. pyplot plots now proportional to dpi. --- src/backends/pyplot.jl | 19 ++++++++++++------- src/layouts.jl | 8 +++++--- src/utils.jl | 5 +++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 6b29c111..a70be48a 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -327,9 +327,12 @@ py_extents(obj) = obj[:get_window_extent]()[:get_points]() # compute a bounding box (with origin top-left), however pyplot gives coords with origin bottom-left function py_bbox(obj) - fl, fr, fb, ft = py_extents(obj[:get_figure]()) + const fig = obj[:get_figure]() + const dpi = fig[:dpi] + const LENGTH_PIXEL = LENGTH_POINT*(72/dpi) + fl, fr, fb, ft = py_extents(fig) #malaforge: reads GUI size instead of *intended* size? l, r, b, t = py_extents(obj) - BoundingBox(l*px, (ft-t)*px, (r-l)*px, (t-b)*px) + BoundingBox(l*LENGTH_PIXEL, (ft-t)*LENGTH_PIXEL, (r-l)*LENGTH_PIXEL, (t-b)*LENGTH_PIXEL) end # get the bounding box of the union of the objects @@ -371,10 +374,11 @@ function py_bbox_title(ax) end #Re-scale font size (points) before sending to PyPlot: -py_font_scale(plt::Plot{PyPlotBackend}, ptsz) = Float64(ptsz) #Passthrough +py_font_scale(plt::Plot{PyPlotBackend}, ptsz) = Float64(ptsz) #Passthrough (Assume point value) #Convert pixels to PyPlot's unit (typography points): -py_dpi_scale(plt::Plot{PyPlotBackend}, px) = px2pt(px, plt[:dpi]) +py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz) = Float64(ptsz) #Passthrough (Assume point value) +#py_dpi_scale(plt::Plot{PyPlotBackend}, px) = px2pt(px, plt[:dpi]) #Assume dimensions in pixels. py_dpi_scale(plt::Plot{PyPlotBackend}, v::Vector) = Float64[py_dpi_scale(plt,px) for px in v] # --------------------------------------------------------------------------- @@ -987,8 +991,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) w, h = plt[:size] fig = plt.o fig[:clear]() - dpi = plt[:dpi] - fig[:set_size_inches](px2inch(w, dpi), px2inch(h, dpi), forward = true) + dpi = plt[:dpi] #User-requested resolution + #Set size assuming all line/font sizes/image dimensions are in points: + fig[:set_size_inches](pt2inch(w), pt2inch(h), forward = true) fig[:set_facecolor](py_color(plt[:background_color_outside])) fig[:set_dpi](dpi) @@ -1216,7 +1221,7 @@ function _update_plot_object(plt::Plot{PyPlotBackend}) ax = sp.o ax == nothing && return figw, figh = sp.plt[:size] - figw, figh = figw*px, figh*px + figw, figh = figw*LENGTH_POINT, figh*LENGTH_POINT pcts = bbox_to_pcts(sp.plotarea, figw, figh) ax[:set_position](pcts) diff --git a/src/layouts.jl b/src/layouts.jl index 71f8b7a1..93dbcf41 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -2,10 +2,12 @@ # NOTE: (0,0) is the top-left !!! # allow pixels and percentages -const px = AbsoluteLength(0.254) -const pct = Length{:pct, Float64}(1.0) +const LENGTH_POINT = AbsoluteLength(MM_PER_POINT) +const px = LENGTH_POINT #malaforge: Hack. Should deprecate. +#const px = AbsoluteLength(0.254) #Old def assumed 100 dpi... why? +const pct = Length{:pct, Float64}(1.0) #Represents 1% -to_pixels(m::AbsoluteLength) = m.value / 0.254 +to_pixels(m::AbsoluteLength) = m.value / MM_PER_POINT #malaforge: should be called "to_point" const _cbar_width = 5mm diff --git a/src/utils.jl b/src/utils.jl index c6ede431..40a3e049 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -860,13 +860,14 @@ end const DTPPOINTS_PER_INCH = 72 #Typography (desktop publishing) points per inch const DEFAULT_DPI = DTPPOINTS_PER_INCH const MM_PER_INCH = 25.4 +const MM_PER_POINT = MM_PER_INCH/DTPPOINTS_PER_INCH inch2mm(inches::Real) = float(inches * MM_PER_INCH) mm2inch(mm::Real) = float(mm / MM_PER_INCH) px2inch(px::Float64, dpi::Float64) = px / dpi px2inch(px::Real, dpi::Real) = px2inch(Float64(px), Float64(dpi)) - -#Convert to typography "points": +pt2inch(pt::Float64) = pt / DTPPOINTS_PER_INCH +pt2inch(pt::Real) = pt2inch(Float64(pt)) px2pt(px::Float64, dpi::Float64) = px * (DTPPOINTS_PER_INCH / dpi) px2pt(px::Real, dpi::Real) = px2pt(Float64(px), Float64(dpi))