prawn
prawn copied to clipboard
Padding is read from wrong box when creating new page
When creating a new page, the padding is read from the margin box instead of the current bounding box. This can cause the indent function to effectively remove the padding twice, leading to a left margin that migrates further and further to the left.
I reported a similar problem in prawn-table. See https://github.com/prawnpdf/prawn-table/issues/114
What it comes down to is that the bounding_box and indent functions don't play well together. Here's a script that reproduces the problem:
Prawn::Document.generate 'test.pdf' do
initial_absolute_left = bounds.absolute_left
text 'paragraph'
bounding_box [0, cursor], width: bounds.width do
text 'paragraph in bounding box'
bounds.move_past_bottom
text 'paragraph in bounding box'
end
indent 20 do
bounds.move_past_bottom
end
if bounds.absolute_left != initial_absolute_left
warn 'bounds were not properly restored after call to indent'
end
text 'paragraph'
end
The problematic logic is here: https://github.com/prawnpdf/prawn/blob/c5842a27b15f912f2f0ad5818a9ef38992978b3c/lib/prawn/document.rb#L723-L731
I believe the following logic will resolve the problem:
# update bounding box if not flowing from the previous page
unless @bounding_box && @bounding_box.parent
old_margin_box = @bounding_box
@bounding_box = @margin_box
end
# maintains indentation settings across page breaks
if old_margin_box
@margin_box.add_left_padding(old_margin_box.total_left_padding)
@margin_box.add_right_padding(old_margin_box.total_right_padding)
end
Not only does it fix the example scenario I provided, the change also passes all tests in Asciidoctor PDF (which uses bounding boxes extensively).
The same problem occurs in go_to_page. In fact, it can happen anytime generate_margin_box is called, given the right conditions.