Skip to content

Instantly share code, notes, and snippets.

@jkrumbiegel
Created March 12, 2023 16:46
Show Gist options
  • Save jkrumbiegel/e6b998e1a0660dd550ce436beee67f2d to your computer and use it in GitHub Desktop.
Save jkrumbiegel/e6b998e1a0660dd550ce436beee67f2d to your computer and use it in GitHub Desktop.
using CairoMakie
using Cairo
using Poppler_jll
@recipe(PDF) do scene
Attributes(
bbox = BBox(0, 100, 0, 100)
)
end
Makie.plot!(p::PDF) = p
const poppler = Poppler_jll.libpoppler_glib
mutable struct GError
domain::Cint
code::Cint
message::Cstring
end
const _PopplerDocument = Cvoid
const PopplerDocument = _PopplerDocument
const PopplerPage = Cvoid
function poppler_document_new_from_file(uri, password, error)
ccall((:poppler_document_new_from_file, poppler), Ptr{PopplerDocument}, (Cstring, Cstring, Ptr{Ptr{GError}}), uri, password, error)
end
function poppler_document_get_n_pages(doc)
ccall((:poppler_document_get_n_pages, poppler), Cint, (Ptr{PopplerDocument},), doc)
end
function poppler_document_get_page(doc, i)
ccall((:poppler_document_get_page, poppler), Ptr{PopplerPage}, (Ptr{PopplerDocument}, Cint), doc, i)
end
function poppler_page_render_for_printing(page, cairocontext)
ccall((:poppler_page_render_for_printing, poppler), Ptr{PopplerPage}, (Ptr{PopplerPage}, Ptr{Nothing}), page, cairocontext)
end
function poppler_page_get_size(page)
w = Ref{Cdouble}()
h = Ref{Cdouble}()
ccall((:poppler_page_get_size, poppler), Cvoid, (Ptr{PopplerPage}, Ptr{Cdouble}, Ptr{Cdouble}), page, w, h)
return w[], h[]
end
function CairoMakie.draw_atomic(s::Makie.Scene, sc::CairoMakie.Screen, x::PDF)
ctx = sc.context
r = Ref{Ptr{GError}}(C_NULL)
uri = "file://" * abspath(x.path[])
doc = poppler_document_new_from_file(uri, C_NULL, r)
if (doc == C_NULL)
m = unsafe_load(r[]).message
print("poppler fail:", unsafe_string(m))
return
end
sc.context |> typeof
npages = poppler_document_get_n_pages(doc)
npages != 1 && error("Can currently only handle single-page pdfs, got $npages pages")
page = poppler_document_get_page(doc, 0)
w, h = poppler_page_get_size(page)
Cairo.translate(sc.context, x.bbox[].origin...)
ws = x.bbox[].widths
Cairo.scale(sc.context, (ws ./ (w, h))...)
poppler_page_render_for_printing(page, ctx.ptr)
return
end
##
f = lines(cumsum(randn(100)), color = :red; figure = (resolution = (400, 300)))
CairoMakie.save("f1.pdf", f)
f = lines(cumsum(randn(100)), color = :blue; figure = (resolution = (400, 300)))
CairoMakie.save("f2.pdf", f)
##
f = Figure(resolution = (600, 800))
pdf!(f.scene, path = "f1.pdf", bbox = (BBox(0, 600, 400, 800)))
pdf!(f.scene, path = "f2.pdf", bbox = (BBox(0, 600, 0, 400)))
CairoMakie.save("f1_f2.pdf")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment