-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Choose drawing size after placing contents? #260
Comments
Hi! I don't think there's anything simple that will do this. Interactive drawing applications probably store all graphics 'in the abstract' and then render them on any size drawing at scale/position, etc. And image editing applications can probably copy a buffer quickly onto another surface of a different size. With Cairo/Luxor, it's more like when you start to draw on a sheet of paper or whiteboard and then realize too late that you started out in the wrong place... :) The nearest you're going to get at present is by using a recording surface and snapshots. I don't know anything about these (the feature was coded by @hustf :)), but the idea is that you specify a bounding box when you output the file. Of course, you still have to be able to keep track of and calculate the bounding box somehow (since graphics are inaccessible once they've been drawn). Drawing(NaN, NaN, :rec) # no bounds
background("antiquewhite")
n_circles = 5
margin = 10
@layer begin # non-permanent transformations
for _ in 1:n_circles
randomhue()
circle(O, 10, :fill)
translate(30, 0)
end
end
snapshot(fname="/tmp/temp.svg",
cb=BoundingBox(Point(-margin, -100), Point(150, 100)))
finish() |
Talking of recording surfaces, there appears to be a Cairo function called function recording_surface_ink_extents()
x0 = Cdouble[0]
y0 = Cdouble[0]
w = Cdouble[0]
h = Cdouble[0]
d = Luxor._get_current_drawing_save()
if d.surfacetype === :rec
ccall((:cairo_recording_surface_ink_extents, Luxor.Cairo.libcairo),
Ptr{Nothing},
(Ptr{Nothing}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}),
d.surface.ptr, x0, y0, w, h)
return BoundingBox(Point(x0[1], y0[1]), Point(x0[1] + w[1], y0[1] + h[1]))
else
throw(error("not a recording surface"))
end
end See JuliaGraphics/Cairo.jl#356 for upstream solution. |
Thanks for the speedy response! I think the recording surface + snapshot looks like a great solution, and luckily in my case manually tracking the bounding box isn't too hard. From the docs on |
If you encounter problems, it night be worth running on the current master. There’s been some recent work on this which hasn’t yet been released. (Here’s a place to start: #150 ) |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Toy example: let's say I wanted to draw a bunch of circles in a row, but I don't know a priori how many.
If
n_circles
is too big, some of the circles won't fit in the drawing. Is there a way to draw things on some abstract canvas and then choose the drawing size?Of course in this example
n_circles
could be precomputed outside the@drawsvg
macro and from there a width and height computed. But in practice it may not be so easy to know the width and height needed before hand, for example if objects are placed using Luxor's drawing-specific geometric tools like relative translations.Also, even in this toy example, precomputing width and height offloads to the user some manual geometric calculation (how far does the right side of the drawing need to be? Well, the first circle at centered-origin is centered at
x = width/2
from the left side ... then each successive circle ... plus the stroke width ... plus some buffer ...).So in summary, I'm hoping for a Luxor-idiomatic way to do two related but separate things:
Thanks in advance for any help!
The text was updated successfully, but these errors were encountered: