lib/prawn/document/text.rb in prawn-0.2.3 vs lib/prawn/document/text.rb in prawn-0.3.0
- old
+ new
@@ -4,14 +4,16 @@
#
# Copyright May 2008, Gregory Brown. All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.
require "zlib"
+require "prawn/document/text/box"
module Prawn
class Document
module Text
+
# Draws text on the page. If a point is specified via the +:at+
# option the text will begin exactly at that point, and the string is
# assumed to be pre-formatted to properly fit the page.
#
# pdf.text "Hello World", :at => [100,100]
@@ -35,19 +37,49 @@
#
# If your font contains kerning pairs data that Prawn can parse, the
# text will be kerned by default. You can disable this feature by passing
# <tt>:kerning => false</tt>.
#
- # === Character Encoding Details:
+ # === Text Positioning Details:
#
+ # When using the :at parameter, Prawn will position your text by its
+ # baseline, and flow along a single line.
+ #
+ # When using automatic text flow, Prawn currently does a bunch of nasty
+ # hacks to get things to position nicely in bounding boxes, table cells,
+ # etc.
+ #
+ # For AFM fonts, the first line of text is positioned font.height below
+ # the baseline.
+ #
+ # For TTF fonts, the first line is possitioned font.ascender below the
+ # baseline.
+ #
+ # The issue here is that there are complex issues with determining the
+ # size of the glyphs above and below the baseline in TTF that we haven't
+ # figured out yet, and that AFM and TTF appear to handle things very
+ # differently.
+ #
+ # The moral of the story is that if you want reliable font positioning
+ # for your advanced needs, use :at, otherwise, just let Prawn do its
+ # positioning magic for you, or investigate and help us get rid of this
+ # ugly issue.
+ #
+ # == Rotation
+ #
+ # Text can be rotated before it is placed on the canvas by specifying the
+ # :rotate option. Rotation occurs counter-clockwise.
+ #
+ # == Encoding
+ #
# Note that strings passed to this function should be encoded as UTF-8.
# If you get unexpected characters appearing in your rendered document,
# check this.
#
# If the current font is a built-in one, although the string must be
- # encoded as UTF-8, only characters that are available in ISO-8859-1
- # are allowed (transliteration will be attempted).
+ # encoded as UTF-8, only characters that are available in WinAnsi
+ # are allowed.
#
# If an empty box is rendered to your PDF instead of the character you
# wanted it usually means the current font doesn't include that character.
#
def text(text,options={})
@@ -65,10 +97,13 @@
if options[:at]
x,y = translate(options[:at])
font.size(options[:size]) { add_text_content(text,x,y,options) }
else
+ if options[:rotate]
+ raise ArgumentError, "Rotated text may only be used with :at"
+ end
wrapped_text(text,options)
end
font(original_font)
end
@@ -84,11 +119,11 @@
private
def process_text_options(options)
Prawn.verify_options [:style, :kerning, :size, :at, :wrap,
- :spacing, :align ], options
+ :spacing, :align, :rotate ], options
if options[:style]
raise "Bad font family" unless font.family
font(font.family,:style => options[:style])
end
@@ -113,14 +148,18 @@
font.size(options[:size]) do
text = font.metrics.naive_wrap(text, bounds.right, font.size,
:kerning => options[:kerning], :mode => options[:wrap])
- lines = text.lines
+ lines = text.lines.to_a
- lines.each do |e|
- move_text_position( font.height + font.descender )
+ lines.each_with_index do |e,i|
+ if font.metrics.type0?
+ move_text_position(font.ascender)
+ else
+ move_text_position(font.height)
+ end
line_width = font.width_of(e)
case(options[:align])
when :left
x = @bounding_box.absolute_left
@@ -130,29 +169,35 @@
when :right
x = @bounding_box.absolute_right - line_width
end
add_text_content(e,x,y,options)
- move_text_position(options[:spacing] || -font.descender )
+
+ if font.metrics.type0? && i < lines.length - 1
+ move_text_position(font.height - font.ascender)
+ end
+
+ move_text_position(options[:spacing]) if options[:spacing]
end
end
end
-
+
def add_text_content(text, x, y, options)
text = font.metrics.convert_text(text,options)
- add_content %Q{
- BT
- /#{font.identifier} #{font.size} Tf
- #{x} #{y} Td
- }
-
+ add_content "\nBT"
+ add_content "/#{font.identifier} #{font.size} Tf"
+ if options[:rotate]
+ rad = options[:rotate].to_i * Math::PI / 180
+ arr = [ Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), x, y ]
+ add_content "%.3f %.3f %.3f %.3f %.3f %.3f Tm" % arr
+ else
+ add_content "#{x} #{y} Td"
+ end
+ rad = 1.570796
add_content Prawn::PdfObject(text, true) <<
- " #{options[:kerning] ? 'TJ' : 'Tj'}\n"
-
- add_content %Q{
- ET
- }
- end
+ " #{options[:kerning] ? 'TJ' : 'Tj'}"
+ add_content "ET\n"
+ end
end
end
end