gettalong / hexapdf

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

Undefined method `color_space` when using Page to initialize `HexaPDF::Content::Processor` #259

Closed jacoblange-dev closed 12 months ago

jacoblange-dev commented 12 months ago

This may be an issue of outdated examples or a legitimate edge case but when following along with examples that use HexaPDF::Content::Processor e.g. examples/008, the content processors pass Page objects as proxy for resources on initialization, this leads to an edge case when processing an xobject that doesn't have a resource dictionary.

Here's a full example that reproduces the standard error thrown when trying to call color_space on resources object.

require 'hexapdf'

doc = HexaPDF::Document.new
canvas = doc.pages.add.canvas

form = doc.add({Type: :XObject, Subtype: :Form, BBox: [0, 0, 100, 100]})
form.canvas.stroke_color(0.3)
form[:Resources] = nil # This is key, the xobject does not have it's own resources
canvas.xobject(form, at: [100, 100])

class ExampleProcessor < HexaPDF::Content::Processor
end

doc.pages.each do |page|
  processor = ExampleProcessor.new(page) # << issue here

  # This works (Processor.@original_resources defaults to page.resources type instead of page)
  # processor = ExampleProcessor.new

  page.process_contents(processor)
end

I think the preferred solution on my end is just to not pass anything on HexaPDF::Content::Processor initialization? I'm actually unsure after diving into this when it would be preferred to pass in the resources when initializing the processor

gettalong commented 12 months ago

In the example 008-show_char_bboxes.rb the page variable is passed to the HexaPDF::Content::Processor subclass because it is needed for creating the overlay canvas. You can see that it is not passed on in the call to super().

So if you are just using a HexaPDF::Content::Processor, you don't need to path anything on initialization. However, if you do, it needs to be a resources dictionary as stated in its API documentation.

jacoblange-dev commented 12 months ago

Ah of course, thanks I definitely missed the call to super was different.