lib/prawn/text/formatted/box.rb in prawn-1.0.0.rc2 vs lib/prawn/text/formatted/box.rb in prawn-1.0.0

- old
+ new

@@ -8,11 +8,12 @@ # module Prawn module Text module Formatted - + # @group Stable API + # Draws the requested formatted text into a box. When the text overflows # the rectangle shrink to fit or truncate the text. Text boxes are # independent of the document y position. # # == Formatted Text Array @@ -43,14 +44,20 @@ # a URL to which to create a link. A clickable link will be created # to that URL. Note that you must explicitly underline and color using # the appropriate tags if you which to draw attention to the link # <tt>:anchor</tt>:: # a destination that has already been or will be registered using - # Prawn::Core::Destinations#add_dest. A clickable link will be + # PDF::Core::Destinations#add_dest. A clickable link will be # 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>:local</tt>:: + # a file or application to be opened locally. A clickable link will be + # created to the provided local file or application. If the file is + # another PDF, it will be opened in a new window. 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: @@ -90,25 +97,13 @@ # conjunction with #render(:dry_run => true) enables one to do look-ahead # calculations prior to placing text on the page, or to determine how much # vertical space was consumed by the printed text # class Box - include Prawn::Core::Text::Formatted::Wrap + include Prawn::Text::Formatted::Wrap - def valid_options - Prawn::Core::Text::VALID_OPTIONS + [:at, :height, :width, - :align, :valign, - :rotate, :rotate_around, - :overflow, :min_font_size, - :leading, :character_spacing, - :mode, :single_line, - :skip_encoding, - :document, - :direction, - :fallback_fonts, - :draw_text_callback] - end + # @group Experimental API # The text that was successfully printed (or, if <tt>dry_run</tt> was # used, the text that would have been successfully printed) attr_reader :text @@ -137,46 +132,10 @@ def line_gap line_height - (ascender + descender) end - # - # Example (see Prawn::Text::Core::Formatted::Wrap for what is required - # of the wrap method if you want to override the default wrapping - # algorithm): - # - # - # module MyWrap - # - # def wrap(array) - # initialize_wrap([{ :text => 'all your base are belong to us' }]) - # @line_wrap.wrap_line(:document => @document, - # :kerning => @kerning, - # :width => 10000, - # :arranger => @arranger) - # fragment = @arranger.retrieve_fragment - # format_and_draw_fragment(fragment, 0, @line_wrap.width, 0) - # [] - # end - # - # end - # - # Prawn::Text::Formatted::Box.extensions << MyWrap - # - # box = Prawn::Text::Formatted::Box.new('hello world') - # box.render('why can't I print anything other than' + - # '"all your base are belong to us"?') - # - # - def self.extensions - @extensions ||= [] - end - - def self.inherited(base) #:nodoc: - extensions.each { |e| base.extensions << e } - end - # See Prawn::Text#text_box for valid options # def initialize(formatted_text, options={}) @inked = false Prawn.verify_options(valid_options, options) @@ -209,10 +168,15 @@ @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 the text rendering mode is :unknown, force it back to :fill + if @mode == :unknown + @mode = :fill + end + if @overflow == :expand # if set to expand, then we simply set the bottom # as the bottom of the document bounds, since that # is the maximum we should expand to @height = default_height @@ -276,11 +240,11 @@ def available_width @width end # The height actually used during the previous <tt>render</tt> - # + # def height return 0 if @baseline_y.nil? || @descender.nil? (@baseline_y - @descender).abs end @@ -326,10 +290,62 @@ draw_fragment_overlays(fragment) end end + # @group Extension API + + # Example (see Prawn::Text::Core::Formatted::Wrap for what is required + # of the wrap method if you want to override the default wrapping + # algorithm): + # + # + # module MyWrap + # + # def wrap(array) + # initialize_wrap([{ :text => 'all your base are belong to us' }]) + # @line_wrap.wrap_line(:document => @document, + # :kerning => @kerning, + # :width => 10000, + # :arranger => @arranger) + # fragment = @arranger.retrieve_fragment + # format_and_draw_fragment(fragment, 0, @line_wrap.width, 0) + # [] + # end + # + # end + # + # Prawn::Text::Formatted::Box.extensions << MyWrap + # + # box = Prawn::Text::Formatted::Box.new('hello world') + # box.render('why can't I print anything other than' + + # '"all your base are belong to us"?') + # + # + def self.extensions + @extensions ||= [] + end + + # @private + def self.inherited(base) + extensions.each { |e| base.extensions << e } + end + + def valid_options + PDF::Core::Text::VALID_OPTIONS + [:at, :height, :width, + :align, :valign, + :rotate, :rotate_around, + :overflow, :min_font_size, + :leading, :character_spacing, + :mode, :single_line, + :skip_encoding, + :document, + :direction, + :fallback_fonts, + :draw_text_callback] + end + private def original_text @original_array.collect { |hash| hash.dup } end @@ -379,11 +395,11 @@ fallback_fonts = @fallback_fonts.dup # always default back to the current font if the glyph is missing from # all fonts fallback_fonts << fragment_font - hash[:text].unicode_characters do |char| + hash[:text].each_char do |char| @document.font(fragment_font) font_glyph_pairs << [find_font_for_this_glyph(char, @document.font.family, fallback_fonts.dup), char] @@ -448,11 +464,11 @@ def process_vertical_alignment(text) # The vertical alignment must only be done once per text box, but # we need to wait until render() is called so that the fonts are set # up properly for wrapping. So guard with a boolean to ensure this is # only run once. - return if @vertical_alignment_processed + return if defined?(@vertical_alignment_processed) && @vertical_alignment_processed @vertical_alignment_processed = true return if @vertical_align == :top wrap(text) @@ -519,10 +535,11 @@ def draw_fragment_overlays(fragment) draw_fragment_overlay_styles(fragment) draw_fragment_overlay_link(fragment) draw_fragment_overlay_anchor(fragment) + draw_fragment_overlay_local(fragment) fragment.callback_objects.each do |obj| obj.render_in_front(fragment) if obj.respond_to?(:render_in_front) end end @@ -531,26 +548,37 @@ box = fragment.absolute_bounding_box @document.link_annotation(box, :Border => [0, 0, 0], :A => { :Type => :Action, :S => :URI, - :URI => Prawn::Core::LiteralString.new(fragment.link) }) + :URI => PDF::Core::LiteralString.new(fragment.link) }) end def draw_fragment_overlay_anchor(fragment) return unless fragment.anchor box = fragment.absolute_bounding_box @document.link_annotation(box, :Border => [0, 0, 0], :Dest => fragment.anchor) end + def draw_fragment_overlay_local(fragment) + return unless fragment.local + box = fragment.absolute_bounding_box + @document.link_annotation(box, + :Border => [0, 0, 0], + :A => { :Type => :Action, + :S => :Launch, + :F => PDF::Core::LiteralString.new(fragment.local), + :NewWindow => true }) + end + def draw_fragment_overlay_styles(fragment) underline = fragment.styles.include?(:underline) if underline @document.stroke_line(fragment.underline_points) end - + strikethrough = fragment.styles.include?(:strikethrough) if strikethrough @document.stroke_line(fragment.strikethrough_points) end end