[Proposal] Make at: more flexible, by adding a top-left-at (starting at the top left of a page).
Sers Thomas,
Right now the recommended, or only way possible, way to add text, it seems, via at: goes like this:
canvas.text(this_text, at: [150, 150])
An example for this can be found in the excellent documentation here:
https://hexapdf.gettalong.org/documentation/basics/creating-a-pdf-from-scratch.html
It is explained here:
"The coordinate system of a PDF page has its origin at the lower-left corner"
Now, while that may be the mathematically correct way (lower-left corner is typically the place where 0 is), when I work on an existing .pdf file, I often want to "append" to an existing page, and I then actually think from "top-left to bottom-left". So, still on the left side, but rather than starting from bottom, I would like to start from the top.
Would it be possible to add a keyword here that would allow us to do so? The default behaviour is still via at:, but perhaps we could add an API such as:
top_left_at:
top:
top_at:
from_top:
Just showing a few examples how this could be.
The first line is counted from the top, so 5 pixels (px) would count from top-to-bottom.
The logic used for at: can be re-used here, just that we would do an "inverse count", e. g. we calculate from the top place. So we could re-use the code that governs at:, with the sole difference that we would count from top.
I am not sure how many users would like this; perhaps it was already suggested before (I admittedly had this as spontaneous idea, actually as my current task is to append to an existing .pdf file; I may suggest something for this too, but for now this is just for top-to-bottom counting.)
At any rate thank you for reading this suggestion.
Thanks for the suggestions!
So, first, I will have to update that documentation page to mention the newer canvas.composer method that provides the ability to use the high-level layout functionality on a single canvas. With that the layout of text (and everything else) flows - as expected - from top to bottom.
As for amending the canvas.text method I'm not sure if that would be a good idea. Everything in the canvas works under the assumption that we have a coordinate system with the origin (0,0) at the bottom-left corner of the page. So making the #text method special in that in could act in two ways would complicate matters - I think.
You could do something like this:
require 'hexapdf'
doc = HexaPDF::Document.new
canvas = doc.pages.add.canvas
canvas.translate(0, canvas.context.box.height)
canvas.font('Helvetica', size: 10)
canvas.text('Hello world', at: [100, -150])
canvas.circle(100, -150, 3).stroke
doc.write('/tmp/out.pdf')
This would set the origin to the top-left corner but then you would need to use negative y-coordinates.
I have updated the linked page so that it mentions the HexaPDF::Composer class and added a link to the composer tutorial.