Looking into it a bit closer, the approach with a callback looks like
a pretty akward path for what I'm trying to achieve.
All I want is to add the ability to render something before the text
inside Prawn::Text::Formatted::Fragment, in case certain options such
as :background are set on the fragment @format_state.
An internal feature addition, not something I want to control
externally.
I wouldn't want to have to use callbacks for this if I can avoid it.
A callback solution might be to add an 'underlay' callback in the
Fragment#initialize method depending on whether the @format_state has
a :background entry. This seems a bit crazy IMO. Callbacks are for
external use, not to be used like this from an internal context,
right?
In the end I just might have to use my original solution, something
like this. All I was trying to do was to internalize this kind of
behavior in Prawn core somehow.
b = Prawn::Text::Formatted::Box.new(line, options.merge(:document
=> pdf))
b.render(:dry_run => true)
puts "box width: #{b.width}, bounds width: #{pdf.bounds.width}"
pdf.fill_color("ffeeee")
pdf.fill_and_stroke_rectangle(at, min(b.width, pdf.bounds.width),
b.height)
b.render
----------------------------
Callback "solution" ?
class FragmentUnderlayCallback
def draw_fragment_underlay_box(fragment)
at =
fragment.bounding_box.at
at[1] += fragment.height
width = fragment.bounding_box.width
height = fragment.bounding_box.height
@document.join_style :miter
@document.line_width fragment.border if fragment.border
old_color = @document.stroke_color
@document.stroke_color = fragment.border_color if
fragment.border_color
if fragment.fill_color
puts "fill it: #{fragment.fill_color}"
@document.fill_color fragment.fill_color
@document.fill_and_stroke_rectangle(at, width, height)
else
puts "no filling :( : #{fragment.fill_color}"
@document.stroke_rectangle(at, width,
height)
end
@document.stroke_color = old_color
end
end
def underlay?(format_options)
format_options[:background_color] ||
format_options[:background_image]
end
def draw_line(pdf, line, options, height_adj = 0)
# height = line_height(pdf, line, options)
b = nil
pdf.pad_top(height_adj) do
at = [0, pdf.cursor]
options.merge!(:at => at)
puts "options: #{options.inspect}"
callback_object = FragmentUnderlayCallback.new
callback = {:callback => { :object => callback_object, :method
=> :draw_fragment_underlay_box } }
line.each{|o| o.merge!(callback) if underlay?(o)}
b = Prawn::Text::Formatted::Box.new(line, options.merge(:document
=> pdf))
# b.render(:dry_run => true)
b.render
end
b.height
end