prawn
prawn copied to clipboard
Dynamic repeater with fill_color -- causes missing text and an error in Acrobat Reader
Problem
Here's the perfect storm:
- more than "a little" text on the page
- stamp with
dynamic: true fill_colorset to'000000'
Steps to Reproduce
- Run the sample code (below)
- Open error.pdf in Acrobat Reader
- Scroll the 2nd page into view
...and you'll get this error:
An error exists on this page. Acrobat may not display the page correctly. Please contact the person who created the PDF document to correct the problem.
Dismiss the error, and notice that the footer only shows up on the 1st page.
Root Cause
Looks like the error.pdf is missing a /DeviceRGB cs, but I'll leave that decision for the PDF experts.
Sample Code
The following code generates a pdf with the error, plus variants to demonstrate the "edges" of the issue.
require "prawn"
LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
def create_pdf(name, options={})
Prawn::Document.generate(name) do |pdf|
# Default options
line_count = options[:line_count] || 12
page_count = options[:page_count] || 2
dynamic = !(options[:static] || false)
fill_color = options[:fill_color] || '000000'
pdf.fill_color fill_color unless fill_color.empty?
pdf.repeat(:all, :dynamic => dynamic) do
pdf.move_cursor_to 60
pdf.text "FOOTER TEXT"
pdf.text "PAGE ##{pdf.page_number.to_s}"
end
pdf.move_cursor_to pdf.bounds.top
line_count.times { |i| pdf.text(LOREM, size: 13) }
(page_count - 1).times do
pdf.start_new_page
line_count.times { |i| pdf.text(LOREM, size: 13) }
end
end
end
# Causes an error when the 2nd page is scrolled into view (Adobe Acrobat Reader)
create_pdf('error.pdf')
# No error here, but the footer ONLY shows on the 1st page
create_pdf('fewer_lines.pdf', page_count: 40, line_count: 10)
# Footer shows up, but page number is wrong after 1st page (obviously)
create_pdf('static_footer.pdf', static: true)
# Totally works, but text is now red ;)
create_pdf('red.pdf', fill_color: 'AA0000')
# Hacky work-around
create_pdf('slightly_darker_black.pdf', fill_color: '000001')
# Or if just avoid setting the fill_color, that works too
create_pdf('no_fill.pdf', fill_color: '')
Similar / Related Issues
- #925: Error in Acrobat Reader DC when using dynamic: true on repeater.
- #473: Dynamic repeater can break colorspace
- #200: Use of repeat stamp and fill_color results in blank document in Acrobat
+1
I'm pretty sure that #473 is related to this issue, in particular this comment: https://github.com/prawnpdf/prawn/issues/473#issuecomment-32369504
@twobitfool Thanks so much for an incredibly clear and helpful bug report.
@practicingruby -- Thank you for an amazing PDF library :)
As previously stated, the problem is that certain call sequences can result in the color space not being set for a page. I want to mention that a quick workaround for the sample code above is to explicitly update the colors after a new page is started.
pdf.start_new_page
pdf.send :update_colors
I mentioned that only to show that it confirms where the missing directives are.