Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prawn PDF line fit to bounding box

Is there a way to adjust xy coordinates to fit within a bounding box in Prawn PDF if they are larger then the height of the box?

I'm using the gem 'signature-pad-rails' to capture signatures which then stores the following:

[{"lx":98,"ly":23,"mx":98,"my":22},{"lx":98,"ly":21,"mx":98,"my":23},{"lx":98,"ly":18,"mx":98,"my":21}, ... {"lx":405,"ly":68,"mx":403,"my":67},{"lx":406,"ly":69,"mx":405,"my":68}]

I have the follow to show the signature in my pdf:

bounding_box([0, cursor], width: 540, height: 100) do
      stroke_bounds
      @witness_signature.each do |e|
        stroke { line [e["lx"], 100 - e["ly"]],
                      [e["mx"], 100 - e["my"] ] }
      end
    end

But the signature runs off the page in some cases, isn't centre and just generally runs amuck.

like image 971
DollarChills Avatar asked Apr 21 '17 05:04

DollarChills


1 Answers

Your question is pretty vague, so I'm guessing what you mean.

To rescale a sequence of coordinates (x[i], y[i]), i = 1..n to fit in a given bounding box of size (width, height) with origin (0,0) as in Postscript, first decide whether to preserve the aspect ratio of the original image. Fitting to a box won't generally do that. Since you probably don't want to distort the signature, say the answer is "yes."

When scaling an image into a box preserving aspect ratio, either the x- or y-axis determines the scale factor unless the box happens to have exactly the image's aspect. So next is to decide what to do with the "extra space" on the alternate axis. E.g. if the image is tall and thin compared to the bounding box, the extra space will be on the x-axis; if short and fat, it's the y-axis.

Let's say center the image within the extra space; that seems appropriate for a signature.

Then here is pseudocode to re-scale the points to fit the box:

x_min = y_min = +infty, x_max = y_max = -infty
for i in 1 to n
  if x[i] < x_min, x_min = x[i]
  if x[i] > x_max, x_max = x[i]
  if y[i] < y_min, y_min = y[i]
  if y[i] > y_max, y_max = y[i]
end for
dx = x_max - x_min
dy = y_max - y_min
x_scale = width / dx
y_scale = height / dy
if x_scale < y_scale then
  // extra space is on the y-dimension
  scale = x_scale
  x_org = 0
  y_org = 0.5 * (height - dy * scale) // equal top and bottom extra space
else
  // extra space is on the x_dimension
  scale = y_scale
  x_org = 0.5 * (width - dx * scale) // equal left and right extra space
  y_org = 0
end
for i in 1 to n
  x[i] = x_org + scale * (x[i] - x_min)
  y[i] = y_org + scale * (y[i] - y_min)
end
like image 129
Gene Avatar answered Oct 29 '22 14:10

Gene