shairontoledo / rghost

RGhost is a document creation and conversion API. It uses the Ghostscript framework for the format conversion, utilizes EPS templates and is optimized to work with larger documents. Support(PDF,PS,GIF,TIF,PNG,JPG,etc)
http://rghost.rubyforge.org
MIT License
187 stars 46 forks source link

dynamic height #50

Open ollym opened 10 years ago

ollym commented 10 years ago

I'm trying to use rghost to generate a order receipt. The width of the receipt is fixed but the height varies depending on how many items were purchased.

Is there a way to have a flexible page height?

shairontoledo commented 10 years ago

Yeap you can use width and height programatically https://github.com/shairontoledo/rghost/wiki/Paper-and-Page-Layout#custom-paper keep in mind that you need to know the size before the document creating.

ollym commented 10 years ago

Yea that's my problem, is It's going to be incredibly difficult to work that out by hand. Is there no way to do a dry–run render, and work out the height first?

UPDATE: Or maybe set the height to 10000 and then crop it to the final cursor position when rendering?

shairontoledo commented 10 years ago

That could work, do you need a precise height for this receipt? If you have a sample of what you're expecting would help me help you.

ollym commented 10 years ago

Say for example:

screen shot 2014-03-25 at 17 37 20

The height obviously changes with the more tickets being purchased. At the moment I have a dynamic height calculation done in prawnpdf which looks a bit like:

class ReceiptPdf < Prawn::Document
  include Prawn::Measurements

  def initialize(order, width = nil)
    margin = 20
    super page_size: [mm2pt(width || 80), 10000], margin: margin
    y_before = self.y

    transaction do
      draw_content(order)
      rollback
    end

    height = (y_before - self.y) + (margin * 2)

    self.page_height = height
    self.y = height - margin
    draw_content(order)
  end

  def page_height=(value)
    page.dictionary.data[:MediaBox][3] = value.to_f
  end

I just wondered if there was a similar or easier way to do it using rghost?

shairontoledo commented 10 years ago

Understood, there is not way to do that in rghost since the variables to define paper/page is defined in the beginning of the document.

ollym commented 10 years ago

@shairontoledo you have to do that with prawn too. But the physical height variables obviously aren't written until you render the document. The page_height= method you see is a hack to achieve that.

The same will be possible with rghost, the difficulty comes with calculating heights for individual elements, like when generating a QR Code etc. then adding them all together to work out the total height of the document.

I'll have a play with this tomorrow and see what I come up with and will report back here. Thanks anyway for checking this over.

ollym commented 10 years ago

Edit: A version that actually works correctly:

margin_top, margin_bottom = paper.instance_variable_get(:@options)
  .values_at :margin_top, :margin_bottom

variables[:rows_per_page] = @rows + 1
default_variables

page_height = ((variables[:row_height] * @rows + 1) + margin_top + margin_bottom) * 72 / 2.545
head.instance_variable_get(:@body).gsub!(/\/pagesize \[(\d+) \d+\]/, "/pagesize [\\1 #{page_height}]")

PS. I'll leave this issue open so that eventually I (or someone) can produce a proper fix.