Permalink
Browse files

Add :draw_text_callback for Text::Box to intercept text drawing

  • Loading branch information...
1 parent 66d49f1 commit b31489409765959185de2185271a41058d4370a9 @bradediger bradediger committed Dec 16, 2011
Showing with 44 additions and 3 deletions.
  1. +13 −3 lib/prawn/text/formatted/box.rb
  2. +31 −0 spec/text_box_spec.rb
@@ -49,6 +49,9 @@ module Formatted
# created to that destination. Note that you must explicitly underline
# and color using the appropriate tags if you which to draw attention
# to the link
+ # <tt>:draw_text_callback</tt>:
+ # if provided, this Proc will be called instead of #draw_text! once
+ # per fragment for every low-level addition of text to the page.
# <tt>:callback</tt>::
# an object (or array of such objects) with two methods:
# #render_behind and #render_in_front, which are called immediately
@@ -101,7 +104,8 @@ def valid_options
:skip_encoding,
:document,
:direction,
- :fallback_fonts]
+ :fallback_fonts,
+ :draw_text_callback]
end
# The text that was successfully printed (or, if <tt>dry_run</tt> was
@@ -205,6 +209,7 @@ def initialize(formatted_text, options={})
@rotate_around = options[:rotate_around] || :upper_left
@single_line = options[:single_line]
@skip_encoding = options[:skip_encoding] || @document.skip_encoding
+ @draw_text_callback = options[:draw_text_callback]
if @overflow == :expand
# if set to expand, then we simply set the bottom
@@ -310,8 +315,13 @@ def draw_fragment(fragment, accumulated_width=0, line_width=0, word_spacing=0) #
draw_fragment_underlays(fragment)
@document.word_spacing(word_spacing) {
- @document.draw_text!(fragment.text, :at => [x, y],
- :kerning => @kerning)
+ if @draw_text_callback
+ @draw_text_callback.call(fragment.text, :at => [x, y],
+ :kerning => @kerning)
+ else
+ @document.draw_text!(fragment.text, :at => [x, y],
+ :kerning => @kerning)
+ end
}
draw_fragment_overlays(fragment)
View
@@ -184,6 +184,37 @@
end
end
+describe "Text::Box with :draw_text_callback" do
+ before(:each) { create_pdf }
+
+ it "hits the callback whenever text is drawn" do
+ draw_block = stub()
+ draw_block.expects(:kick).with("this text is long enough to")
+ draw_block.expects(:kick).with("span two lines")
+
+ @pdf.text_box "this text is long enough to span two lines",
+ :width => 150,
+ :draw_text_callback => lambda { |text, _| draw_block.kick(text) }
+ end
+
+ it "hits the callback once per fragment for :inline_format" do
+ draw_block = stub()
+ draw_block.expects(:kick).with("this text has ")
+ draw_block.expects(:kick).with("fancy")
+ draw_block.expects(:kick).with(" formatting")
+
+ @pdf.text_box "this text has <b>fancy</b> formatting",
+ :inline_format => true, :width => 500,
+ :draw_text_callback => lambda { |text, _| draw_block.kick(text) }
+ end
+
+ it "does not call #draw_text!" do
+ @pdf.expects(:draw_text!).never
+ @pdf.text_box "some text", :width => 500,
+ :draw_text_callback => lambda { |_, _| }
+ end
+end
+
describe "Text::Box#valid_options" do
it "should return an array" do
create_pdf

0 comments on commit b314894

Please sign in to comment.