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