prawn icon indicating copy to clipboard operation
prawn copied to clipboard

Dynamic repeater with fill_color -- causes missing text and an error in Acrobat Reader

Open twobitfool opened this issue 9 years ago • 4 comments

Problem

Here's the perfect storm:

  • more than "a little" text on the page
  • stamp with dynamic: true
  • fill_color set to '000000'

Steps to Reproduce

  1. Run the sample code (below)
  2. Open error.pdf in Acrobat Reader
  3. 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

twobitfool avatar Mar 03 '16 20:03 twobitfool

+1

xavier avatar Mar 14 '16 10:03 xavier

I'm pretty sure that #473 is related to this issue, in particular this comment: https://github.com/prawnpdf/prawn/issues/473#issuecomment-32369504

practicingruby avatar Mar 29 '16 22:03 practicingruby

@twobitfool Thanks so much for an incredibly clear and helpful bug report.

practicingruby avatar Mar 29 '16 22:03 practicingruby

@practicingruby -- Thank you for an amazing PDF library :)

twobitfool avatar Mar 30 '16 15:03 twobitfool

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.

mojavelinux avatar Sep 21 '16 06:09 mojavelinux