gettalong / hexapdf

Versatile PDF creation and manipulation for Ruby
https://hexapdf.gettalong.org
Other
1.24k stars 70 forks source link

Box doesn't fit on empty page (HexaPDF::Error) #316

Closed reiz closed 3 months ago

reiz commented 3 months ago

I'm using this in my Gemfile:

gem 'hexapdf', '~> 0.45.0'

With ruby 3.1.6p260 (2024-05-29 revision a777087be6) [arm64-darwin22]. My class looks like this:

class InvoiceService

  require 'hexapdf'

  def self.build
    HexaPDF::Composer.create('test.pdf', page_size: :A4, margin: 36) do |c|
      c.document.config['debug'] = false
      c.style(:base, font: 'Helvetica', font_size: 10, line_spacing: 1.2)
      c.style(:top_line, font_size: 8, text_align: :justify)
      c.style(:top_line_box, padding: [100, 0, 0])
      c.style(:top_line_line, margin: [0, 0, 10], border: {width: [1, 0, 0]})

      c.formatted_text([{text: 'AgencyOne GmbH', font: ['Helvetica', variant: :bold]},
                        " - Taal-Str. 1 - 58199 Bonn"], style: :top_line, box_style: :top_line_box)
      c.box(:base, height: 1, style: :top_line_line)
    end
  end

end 

When I run the code, I'm getting this error: Box doesn't fit on empty page (HexaPDF::Error). Any idea?

reiz commented 3 months ago

@gettalong I just found a solution for this problem. It seems that height: 1 and border: {width: [1, 0, 0]} do not work together. Or at least not with this values. If I remove border: {width: [1, 0, 0]} from the styles then it works. I updated the style like this:

c.style(:top_line_line, margin: [2, 0, 10], background_color: "black" )
c.box(:base, height: 1, style: :top_line_line)

and now it works. But the error message Box doesn't fit on empty page is somehow misleading.

gettalong commented 3 months ago

The height attribute defines the height of the box and this includes the border and padding but not the margin. So when you say height: 1 and border: {width: [1, 0, 0]}, there is no room for the content anymore because the content_height of the box would be 0. Therefore this box never fits. First it doesn't fit after the formatted text. Then HexaPDF tries to fit that box on an empty page and that doesn't work either. Since it doesn't make sense to do another try at this point, the error is raised.

The error message is indeed somewhat misleading, maybe it would be better to use "Box didn't fit multiple times, even on an empty page".

Circling back to the original reason for the error: Since other boxes happily work with a content height of zero, I think the base box should also work this way. I will change that for the next release.

reiz commented 3 months ago

Thx for the explanation. Makes sense now.