prawn 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -1
- data/data/fonts/Action Man.dfont +0 -0
- data/examples/general/measurement_units.rb +2 -2
- data/examples/graphics/image_flow.rb +2 -2
- data/examples/graphics/stroke_bounds.rb +1 -1
- data/examples/m17n/win_ansi_charset.rb +3 -3
- data/examples/text/dfont.rb +49 -0
- data/examples/text/flowing_text_with_header_and_footer.rb +2 -48
- data/examples/text/font_calculations.rb +7 -6
- data/examples/text/font_size.rb +4 -4
- data/examples/text/text_flow.rb +1 -1
- data/lib/prawn.rb +6 -3
- data/lib/prawn/compatibility.rb +12 -17
- data/lib/prawn/document.rb +10 -10
- data/lib/prawn/document/internals.rb +8 -3
- data/lib/prawn/document/text.rb +39 -57
- data/lib/prawn/document/text/box.rb +1 -2
- data/lib/prawn/document/text/wrapping.rb +59 -0
- data/lib/prawn/errors.rb +0 -8
- data/lib/prawn/font.rb +192 -277
- data/lib/prawn/font/afm.rb +199 -0
- data/lib/prawn/font/dfont.rb +31 -0
- data/lib/prawn/font/ttf.rb +318 -0
- data/lib/prawn/graphics.rb +7 -2
- data/lib/prawn/images/png.rb +1 -1
- data/lib/prawn/reference.rb +7 -4
- data/spec/font_spec.rb +154 -61
- data/spec/text_spec.rb +47 -6
- data/vendor/pdf-inspector/lib/pdf/inspector.rb +1 -1
- data/vendor/ttfunk/example.rb +42 -2
- data/vendor/ttfunk/lib/ttfunk.rb +96 -42
- data/vendor/ttfunk/lib/ttfunk/directory.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +88 -0
- data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +69 -0
- data/vendor/ttfunk/lib/ttfunk/reader.rb +44 -0
- data/vendor/ttfunk/lib/ttfunk/resource_file.rb +78 -0
- data/vendor/ttfunk/lib/ttfunk/subset.rb +18 -0
- data/vendor/ttfunk/lib/ttfunk/subset/base.rb +141 -0
- data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +46 -0
- data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +48 -0
- data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +63 -0
- data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +51 -0
- data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +72 -0
- data/vendor/ttfunk/lib/ttfunk/table.rb +37 -18
- data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +24 -84
- data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +54 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +126 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +79 -0
- data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +64 -0
- data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +81 -0
- data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +37 -0
- data/vendor/ttfunk/lib/ttfunk/table/head.rb +38 -19
- data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +35 -21
- data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +40 -13
- data/vendor/ttfunk/lib/ttfunk/table/kern.rb +69 -38
- data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +62 -0
- data/vendor/ttfunk/lib/ttfunk/table/loca.rb +43 -0
- data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +34 -11
- data/vendor/ttfunk/lib/ttfunk/table/name.rb +109 -42
- data/vendor/ttfunk/lib/ttfunk/table/os2.rb +78 -0
- data/vendor/ttfunk/lib/ttfunk/table/post.rb +91 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +43 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +35 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +23 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/table/simple.rb +14 -0
- metadata +54 -25
- data/examples/table/addressbook.csv +0 -6
- data/examples/table/cell.rb +0 -40
- data/examples/table/currency.csv +0 -1834
- data/examples/table/fancy_table.rb +0 -62
- data/examples/table/ruport_formatter.rb +0 -53
- data/examples/table/table.rb +0 -51
- data/examples/table/table_alignment.rb +0 -18
- data/examples/table/table_border_color.rb +0 -17
- data/examples/table/table_colspan.rb +0 -19
- data/examples/table/table_header_color.rb +0 -19
- data/examples/table/table_header_underline.rb +0 -15
- data/lib/prawn/document/table.rb +0 -338
- data/lib/prawn/font/cmap.rb +0 -59
- data/lib/prawn/font/metrics.rb +0 -378
- data/lib/prawn/font/wrapping.rb +0 -47
- data/lib/prawn/graphics/cell.rb +0 -264
- data/spec/metrics_spec.rb +0 -62
- data/spec/table_spec.rb +0 -179
- data/vendor/ttfunk/lib/ttfunk/table/directory.rb +0 -25
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
|
|
4
4
|
require "rake/rdoctask"
|
5
5
|
require "rake/gempackagetask"
|
6
6
|
|
7
|
-
PRAWN_VERSION = "0.
|
7
|
+
PRAWN_VERSION = "0.4.0"
|
8
8
|
|
9
9
|
task :default => [:test]
|
10
10
|
|
@@ -52,6 +52,8 @@ spec = Gem::Specification.new do |spec|
|
|
52
52
|
spec.files = Dir.glob("{examples,lib,spec,vendor,data}/**/**/*") +
|
53
53
|
["Rakefile"]
|
54
54
|
spec.require_path = "lib"
|
55
|
+
|
56
|
+
spec.add_dependency('prawn-layout')
|
55
57
|
|
56
58
|
spec.test_files = Dir[ "test/*_test.rb" ]
|
57
59
|
spec.has_rdoc = true
|
Binary file
|
@@ -22,7 +22,7 @@ pdf = Prawn::Document.new(
|
|
22
22
|
:top_margin => 0.1.dm, # work
|
23
23
|
:bottom_margin => 0.01.m) # well
|
24
24
|
|
25
|
-
pdf.
|
25
|
+
pdf.font_size = 6
|
26
26
|
pdf.line_width = 0.05
|
27
27
|
|
28
28
|
units_long = %w[Millimeters Centimeters Decimeters Inches Foot Points]
|
@@ -49,4 +49,4 @@ pdf.text_box temp,
|
|
49
49
|
:width => 5.cm, :height => pdf.font.height * units_long.length,
|
50
50
|
:at => [offset_multiplier * units_long.length, pdf.bounds.top]
|
51
51
|
|
52
|
-
pdf.render_file "measurement_units.pdf"
|
52
|
+
pdf.render_file "measurement_units.pdf"
|
@@ -9,7 +9,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
|
9
9
|
require "prawn"
|
10
10
|
|
11
11
|
Prawn::Document.generate("image-flow.pdf", :page_layout => :landscape) do
|
12
|
-
|
12
|
+
self.font_size = 8
|
13
13
|
stef = "#{Prawn::BASEDIR}/data/images/stef.jpg"
|
14
14
|
|
15
15
|
text "Image at default position with no arguments"
|
@@ -35,4 +35,4 @@ Prawn::Document.generate("image-flow.pdf", :page_layout => :landscape) do
|
|
35
35
|
text "Flowing image at x=50"
|
36
36
|
|
37
37
|
image stef, :position => 50
|
38
|
-
end
|
38
|
+
end
|
@@ -31,14 +31,14 @@ Prawn::Document.generate("win-ansi.pdf") do
|
|
31
31
|
code = "%d." % index
|
32
32
|
char = index.chr
|
33
33
|
|
34
|
-
width = 1000 * font.
|
34
|
+
width = 1000 * font.width_of(char, :size => FONT_SIZE) / FONT_SIZE
|
35
35
|
size = "%d" % width
|
36
36
|
|
37
37
|
data = [code, nil, char, size, nil, name]
|
38
38
|
dx = x
|
39
39
|
fields.zip(data).each do |(total_width, align), field|
|
40
40
|
if field
|
41
|
-
width = font.
|
41
|
+
width = font.width_of(field, :size => FONT_SIZE)
|
42
42
|
|
43
43
|
case align
|
44
44
|
when :left then offset = 0
|
@@ -52,4 +52,4 @@ Prawn::Document.generate("win-ansi.pdf") do
|
|
52
52
|
dx += total_width
|
53
53
|
end
|
54
54
|
end
|
55
|
-
end
|
55
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
4
|
+
require "prawn"
|
5
|
+
|
6
|
+
DFONT_FILE = "#{Prawn::BASEDIR}/data/fonts/Action Man.dfont"
|
7
|
+
puts "There are #{Prawn::Font::DFont.font_count(DFONT_FILE)} fonts in #{DFONT_FILE}:"
|
8
|
+
Prawn::Font::DFont.named_fonts(DFONT_FILE).each do |name|
|
9
|
+
puts "* #{name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
puts
|
13
|
+
puts "generating sample document in 'dfont.pdf'..."
|
14
|
+
|
15
|
+
Prawn::Document.generate "dfont.pdf" do
|
16
|
+
fill_color "0000ff"
|
17
|
+
|
18
|
+
font DFONT_FILE, :font => "ActionMan-Bold", :size => 24
|
19
|
+
text "Introducing Action Man!"
|
20
|
+
|
21
|
+
move_text_position 24
|
22
|
+
|
23
|
+
font_families["Action Man"] = {
|
24
|
+
:normal => { :file => DFONT_FILE, :font => "ActionMan" },
|
25
|
+
:bold => { :file => DFONT_FILE, :font => "ActionMan-Bold" },
|
26
|
+
:italic => { :file => DFONT_FILE, :font => "ActionMan-Italic" },
|
27
|
+
:bold_italic => { :file => DFONT_FILE, :font => "ActionMan-BoldItalic" }
|
28
|
+
}
|
29
|
+
|
30
|
+
font "Action Man", :size => 16
|
31
|
+
text "Action Man is feeling normal here."
|
32
|
+
|
33
|
+
move_text_position 16
|
34
|
+
|
35
|
+
font "Action Man", :style => :bold, :size => 16
|
36
|
+
text "Action Man is feeling bold here!"
|
37
|
+
|
38
|
+
move_text_position 16
|
39
|
+
|
40
|
+
font "Action Man", :style => :italic, :size => 16
|
41
|
+
text "Here, we see Action Man feeling italicized. Slick!"
|
42
|
+
|
43
|
+
move_text_position 16
|
44
|
+
|
45
|
+
font "Action Man", :style => :bold_italic, :size => 16
|
46
|
+
text "Lastly, we observe Mr. Action Man being bold AND italicized. Excellent!"
|
47
|
+
end
|
48
|
+
|
49
|
+
puts "done"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Multi-faceted example that demonstrates a document flowing between header
|
4
4
|
# and footer regions. At the moment, headers and footers in Prawn are run
|
5
|
-
# using the current font settings (among other things), for each page.
|
5
|
+
# using the current font settings (among other things), for each page. This
|
6
6
|
# means that it is important to non-destructively set your desired styling
|
7
7
|
# within your headers and footers, as shown below.
|
8
8
|
#
|
@@ -31,53 +31,7 @@ Prawn::Document.generate("flow_with_headers_and_footers.pdf") do
|
|
31
31
|
:width => bounds.width, :height => bounds.height - 100) do
|
32
32
|
text "this is some flowing text " * 200
|
33
33
|
|
34
|
-
move_down(20)
|
35
34
|
|
36
|
-
font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
|
37
|
-
table [["ὕαλον ϕαγεῖν", "baaar", "1" ],
|
38
|
-
["This is","a sample", "2" ],
|
39
|
-
["Table", "dont\ncha\nknow?", "3" ],
|
40
|
-
[ "It", "Rules", "4" ],
|
41
|
-
[ "It", "Rules", "4" ],
|
42
|
-
[ "It", "Rules", "4" ],
|
43
|
-
[ "It", "Rules", "4" ],
|
44
|
-
[ "It", "Rules", "4" ],
|
45
|
-
[ "It", "Rules", "4" ],
|
46
|
-
[ "It", "Rules", "4" ],
|
47
|
-
[ "It", "Rules", "4" ],
|
48
|
-
[ "It", "Rules", "4" ],
|
49
|
-
[ "It", "Rules\nwith an iron fist", "x" ],
|
50
|
-
[ "It", "Rules", "4" ],
|
51
|
-
[ "It", "Rules", "4" ],
|
52
|
-
[ "It", "Rules", "4" ],
|
53
|
-
[ "It", "Rules", "4" ],
|
54
|
-
[ "It", "Rules", "4" ],
|
55
|
-
[ "It", "Rules", "4" ],
|
56
|
-
[ "It", "Rules", "4" ],
|
57
|
-
[ "It", "Rules", "4" ],
|
58
|
-
[ "It", "Rules", "4" ],
|
59
|
-
[ "It", "Rules", "4" ],
|
60
|
-
[ "It", "Rules", "4" ],
|
61
|
-
[ "It", "Rules", "4" ],
|
62
|
-
[ "It", "Rules", "4" ],
|
63
|
-
[ "It", "Rules", "4" ],
|
64
|
-
[ "It", "Rules", "4" ],
|
65
|
-
[ "It", "Rules", "4" ],
|
66
|
-
[ "It", "Rules", "4" ],
|
67
|
-
[ "It", "Rules", "4" ],
|
68
|
-
[ "It", "Rules", "4" ],
|
69
|
-
[ "It", "Rules", "4" ],
|
70
|
-
[ "It", "Rules", "4" ],
|
71
|
-
[ "It", "Rules", "4" ],
|
72
|
-
[ "It", "Rules", "4" ]],
|
73
|
-
|
74
|
-
:font_size => 24,
|
75
|
-
:horizontal_padding => 10,
|
76
|
-
:vertical_padding => 3,
|
77
|
-
:border_width => 2,
|
78
|
-
:position => :center,
|
79
|
-
:headers => ["Column A","Column B","#"]
|
80
|
-
|
81
35
|
end
|
82
36
|
|
83
|
-
end
|
37
|
+
end
|
@@ -9,13 +9,14 @@ require 'prawn'
|
|
9
9
|
|
10
10
|
Prawn::Document.generate('font_calculations.pdf') do
|
11
11
|
|
12
|
-
def demonstration
|
12
|
+
def demonstration
|
13
|
+
font_size 12
|
13
14
|
move_down 10
|
14
15
|
|
15
16
|
stroke_horizontal_rule
|
16
17
|
|
17
18
|
text "When using flowing text, Prawn will position text\n" +
|
18
|
-
"starting font
|
19
|
+
"starting font.ascender below the baseline, and leave\n" +
|
19
20
|
"the y-cursor at the baseline of the next line of text"
|
20
21
|
|
21
22
|
stroke_horizontal_rule
|
@@ -52,7 +53,7 @@ Prawn::Document.generate('font_calculations.pdf') do
|
|
52
53
|
text "FONT_HEIGHT"
|
53
54
|
|
54
55
|
fill_color "000000"
|
55
|
-
|
56
|
+
font_size 16
|
56
57
|
|
57
58
|
move_down 40
|
58
59
|
|
@@ -81,11 +82,11 @@ Prawn::Document.generate('font_calculations.pdf') do
|
|
81
82
|
end
|
82
83
|
|
83
84
|
text "Using AFM", :size => 20
|
84
|
-
demonstration
|
85
|
+
demonstration
|
85
86
|
|
86
87
|
move_down 75
|
87
88
|
font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
|
88
89
|
text "Using TTF", :size => 20
|
89
|
-
demonstration
|
90
|
+
demonstration
|
90
91
|
|
91
|
-
end
|
92
|
+
end
|
data/examples/text/font_size.rb
CHANGED
@@ -9,12 +9,12 @@ Prawn::Document.generate "font_size.pdf", :page_size => "A4" do
|
|
9
9
|
|
10
10
|
# Explicit global changes
|
11
11
|
font 'Helvetica'
|
12
|
-
|
12
|
+
self.font_size = 16
|
13
13
|
|
14
14
|
text 'Font at 16 point'
|
15
15
|
|
16
16
|
# Transactional changes rolled back after block exit
|
17
|
-
|
17
|
+
font_size 9 do
|
18
18
|
text 'Font at 9 point'
|
19
19
|
# single line changes, not persisted.
|
20
20
|
text 'Font at manual override 20 point', :size => 20
|
@@ -24,11 +24,11 @@ Prawn::Document.generate "font_size.pdf", :page_size => "A4" do
|
|
24
24
|
# Transactional changes rolled back after block exit on full fonts.
|
25
25
|
font("Times-Roman", :style => :italic, :size => 12) do
|
26
26
|
text "Font in times at 12"
|
27
|
-
|
27
|
+
font_size(16) { text "Font in Times at 16" }
|
28
28
|
end
|
29
29
|
|
30
30
|
text 'Font at 16 point'
|
31
31
|
|
32
32
|
font "Courier", :size => 40
|
33
33
|
text "40 pt!"
|
34
|
-
end
|
34
|
+
end
|
data/examples/text/text_flow.rb
CHANGED
@@ -60,7 +60,7 @@ Prawn::Document.generate("flow.pdf") do |pdf|
|
|
60
60
|
pdf.bounding_box([100,450], :width => 300) do
|
61
61
|
pdf.stroke_line [pdf.bounds.left, pdf.bounds.top],
|
62
62
|
[pdf.bounds.right, pdf.bounds.top]
|
63
|
-
pdf.text poem, :size =>
|
63
|
+
pdf.text poem, :size => 10, :spacing => 5
|
64
64
|
end
|
65
65
|
|
66
66
|
pdf.text "And this text automatically goes below the poem", :size => 18
|
data/lib/prawn.rb
CHANGED
@@ -20,10 +20,13 @@ module Prawn
|
|
20
20
|
# The base source directory for Prawn as installed on the system
|
21
21
|
BASEDIR = File.expand_path(File.join(dir, '..'))
|
22
22
|
|
23
|
-
VERSION = "0.
|
23
|
+
VERSION = "0.4.0"
|
24
24
|
|
25
25
|
extend self
|
26
|
-
|
26
|
+
|
27
|
+
# Whe set to true, Prawn will verify hash options to ensure only valid keys
|
28
|
+
# are used. Off by default.
|
29
|
+
#
|
27
30
|
attr_accessor :debug
|
28
31
|
|
29
32
|
def verify_options(accepted,actual) #:nodoc:
|
@@ -66,4 +69,4 @@ require "prawn/document"
|
|
66
69
|
require "prawn/reference"
|
67
70
|
require "prawn/font"
|
68
71
|
require "prawn/encoding"
|
69
|
-
require "prawn/measurements"
|
72
|
+
require "prawn/measurements"
|
data/lib/prawn/compatibility.rb
CHANGED
@@ -1,26 +1,21 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
1
3
|
# Why would we ever use Ruby 1.8.7 when we can backport with something
|
2
4
|
# as simple as this?
|
3
5
|
#
|
4
|
-
|
5
|
-
|
6
|
-
if RUBY_VERSION < "1.9"
|
7
|
-
require "strscan"
|
8
|
-
|
9
|
-
class String #:nodoc:
|
6
|
+
class String #:nodoc:
|
7
|
+
unless "".respond_to?(:lines)
|
10
8
|
alias_method :lines, :to_a
|
11
|
-
|
12
|
-
def each_char
|
13
|
-
scanner, char = StringScanner.new(self), /./mu
|
14
|
-
loop { yield(scanner.scan(char) || break) }
|
15
|
-
end
|
16
|
-
|
17
9
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
10
|
+
end
|
11
|
+
|
12
|
+
unless File.respond_to?(:binread)
|
13
|
+
def File.binread(file)
|
14
|
+
File.open(file,"rb") { |f| f.read }
|
23
15
|
end
|
16
|
+
end
|
17
|
+
|
18
|
+
if RUBY_VERSION < "1.9"
|
24
19
|
|
25
20
|
def ruby_18 #:nodoc:
|
26
21
|
yield
|
data/lib/prawn/document.rb
CHANGED
@@ -9,26 +9,26 @@
|
|
9
9
|
require "stringio"
|
10
10
|
require "prawn/document/page_geometry"
|
11
11
|
require "prawn/document/bounding_box"
|
12
|
-
require "prawn/document/text"
|
13
|
-
require "prawn/document/table"
|
14
12
|
require "prawn/document/internals"
|
15
13
|
require "prawn/document/span"
|
14
|
+
require "prawn/document/text"
|
16
15
|
require "prawn/document/annotations"
|
17
16
|
require "prawn/document/destinations"
|
18
17
|
|
19
18
|
module Prawn
|
20
19
|
class Document
|
21
20
|
|
22
|
-
include
|
23
|
-
include
|
24
|
-
include
|
25
|
-
include
|
21
|
+
include Text
|
22
|
+
include PageGeometry
|
23
|
+
include Internals
|
24
|
+
include Annotations
|
25
|
+
include Destinations
|
26
|
+
include Prawn::Graphics
|
26
27
|
include Prawn::Images
|
27
|
-
|
28
|
-
include PageGeometry
|
29
|
-
|
28
|
+
|
30
29
|
attr_accessor :y, :margin_box
|
31
30
|
attr_reader :margins, :page_size, :page_layout
|
31
|
+
attr_writer :font_size
|
32
32
|
|
33
33
|
# Creates and renders a PDF document.
|
34
34
|
#
|
@@ -96,6 +96,7 @@ module Prawn
|
|
96
96
|
@compress = options[:compress] || false
|
97
97
|
@skip_encoding = options[:skip_encoding]
|
98
98
|
@background = options[:background]
|
99
|
+
@font_size = 12
|
99
100
|
|
100
101
|
text_options.update(options[:text_options] || {})
|
101
102
|
|
@@ -286,7 +287,6 @@ module Prawn
|
|
286
287
|
:Parent => @pages,
|
287
288
|
:MediaBox => page_dimensions,
|
288
289
|
:Contents => @page_content)
|
289
|
-
font.add_to_current_page if @font
|
290
290
|
update_colors
|
291
291
|
end
|
292
292
|
|
@@ -17,8 +17,13 @@ module Prawn
|
|
17
17
|
module Internals
|
18
18
|
# Creates a new Prawn::Reference and adds it to the Document's object
|
19
19
|
# list. The +data+ argument is anything that Prawn::PdfObject() can convert.
|
20
|
-
|
21
|
-
|
20
|
+
#
|
21
|
+
# If a block is given, it will be invoked just before the object is written
|
22
|
+
# out to the PDF document stream. This allows you to do deferred processing
|
23
|
+
# on some references (such as fonts, which you might know all the details
|
24
|
+
# about until the last page of the document is finished).
|
25
|
+
def ref(data, &block)
|
26
|
+
@objects.push(Prawn::Reference.new(@objects.size + 1, data, &block)).last
|
22
27
|
end
|
23
28
|
|
24
29
|
# Appends a raw string to the current page content.
|
@@ -103,7 +108,7 @@ module Prawn
|
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
106
|
-
# Write out the PDF
|
111
|
+
# Write out the PDF Trailer, as per spec 3.4.4
|
107
112
|
def render_trailer(output)
|
108
113
|
trailer_hash = {:Size => @objects.size + 1,
|
109
114
|
:Root => @root,
|
data/lib/prawn/document/text.rb
CHANGED
@@ -7,10 +7,12 @@
|
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
require "zlib"
|
9
9
|
require "prawn/document/text/box"
|
10
|
+
require "prawn/document/text/wrapping"
|
10
11
|
|
11
12
|
module Prawn
|
12
13
|
class Document
|
13
14
|
module Text
|
15
|
+
include Wrapping
|
14
16
|
|
15
17
|
# Draws text on the page. If a point is specified via the +:at+
|
16
18
|
# option the text will begin exactly at that point, and the string is
|
@@ -44,25 +46,8 @@ module Prawn
|
|
44
46
|
# When using the :at parameter, Prawn will position your text by its
|
45
47
|
# baseline, and flow along a single line.
|
46
48
|
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# etc.
|
50
|
-
#
|
51
|
-
# For AFM fonts, the first line of text is positioned font.height below
|
52
|
-
# the baseline.
|
53
|
-
#
|
54
|
-
# For TTF fonts, the first line is possitioned font.ascender below the
|
55
|
-
# baseline.
|
56
|
-
#
|
57
|
-
# The issue here is that there are complex issues with determining the
|
58
|
-
# size of the glyphs above and below the baseline in TTF that we haven't
|
59
|
-
# figured out yet, and that AFM and TTF appear to handle things very
|
60
|
-
# differently.
|
61
|
-
#
|
62
|
-
# The moral of the story is that if you want reliable font positioning
|
63
|
-
# for your advanced needs, use :at, otherwise, just let Prawn do its
|
64
|
-
# positioning magic for you, or investigate and help us get rid of this
|
65
|
-
# ugly issue.
|
49
|
+
# Otherwise, the text is positioned at font.ascender below the baseline,
|
50
|
+
# making it easy to use this method within bounding boxes and spans.
|
66
51
|
#
|
67
52
|
# == Rotation
|
68
53
|
#
|
@@ -87,25 +72,22 @@ module Prawn
|
|
87
72
|
# original string
|
88
73
|
text = text.to_s.dup
|
89
74
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
font.normalize_encoding(text) unless @skip_encoding
|
97
|
-
|
98
|
-
if options[:at]
|
99
|
-
x,y = translate(options[:at])
|
100
|
-
font.size(options[:size]) { add_text_content(text,x,y,options) }
|
101
|
-
else
|
102
|
-
if options[:rotate]
|
103
|
-
raise ArgumentError, "Rotated text may only be used with :at"
|
104
|
-
end
|
105
|
-
wrapped_text(text,options)
|
106
|
-
end
|
75
|
+
save_font do
|
76
|
+
options = text_options.merge(options)
|
77
|
+
process_text_options(options)
|
78
|
+
|
79
|
+
font.normalize_encoding(text) unless @skip_encoding
|
107
80
|
|
108
|
-
|
81
|
+
if options[:at]
|
82
|
+
x,y = translate(options[:at])
|
83
|
+
font_size(options[:size]) { add_text_content(text,x,y,options) }
|
84
|
+
else
|
85
|
+
if options[:rotate]
|
86
|
+
raise ArgumentError, "Rotated text may only be used with :at"
|
87
|
+
end
|
88
|
+
wrapped_text(text,options)
|
89
|
+
end
|
90
|
+
end
|
109
91
|
end
|
110
92
|
|
111
93
|
# A hash of configuration options, to be used globally by text().
|
@@ -121,7 +103,7 @@ module Prawn
|
|
121
103
|
|
122
104
|
def process_text_options(options)
|
123
105
|
Prawn.verify_options [:style, :kerning, :size, :at, :wrap,
|
124
|
-
:spacing, :align, :rotate ], options
|
106
|
+
:spacing, :align, :rotate, :final_gap ], options
|
125
107
|
|
126
108
|
if options[:style]
|
127
109
|
raise "Bad font family" unless font.family
|
@@ -129,10 +111,10 @@ module Prawn
|
|
129
111
|
end
|
130
112
|
|
131
113
|
unless options.key?(:kerning)
|
132
|
-
options[:kerning] = font.
|
114
|
+
options[:kerning] = font.has_kerning_data?
|
133
115
|
end
|
134
116
|
|
135
|
-
options[:size] ||=
|
117
|
+
options[:size] ||= font_size
|
136
118
|
end
|
137
119
|
|
138
120
|
def move_text_position(dy)
|
@@ -146,20 +128,17 @@ module Prawn
|
|
146
128
|
def wrapped_text(text,options)
|
147
129
|
options[:align] ||= :left
|
148
130
|
|
149
|
-
|
150
|
-
text =
|
131
|
+
font_size(options[:size]) do
|
132
|
+
text = naive_wrap(text, bounds.right, font_size,
|
151
133
|
:kerning => options[:kerning], :mode => options[:wrap])
|
152
134
|
|
153
135
|
lines = text.lines.to_a
|
136
|
+
last_gap_before = options.fetch(:final_gap, true) ? lines.length : lines.length-1
|
154
137
|
|
155
138
|
lines.each_with_index do |e,i|
|
156
|
-
|
157
|
-
move_text_position(font.ascender)
|
158
|
-
else
|
159
|
-
move_text_position(font.height)
|
160
|
-
end
|
139
|
+
move_text_position(font.ascender)
|
161
140
|
|
162
|
-
line_width = font.width_of(e)
|
141
|
+
line_width = font.width_of(e, :kerning => options[:kerning])
|
163
142
|
case(options[:align])
|
164
143
|
when :left
|
165
144
|
x = @bounding_box.absolute_left
|
@@ -172,20 +151,18 @@ module Prawn
|
|
172
151
|
|
173
152
|
add_text_content(e,x,y,options)
|
174
153
|
|
175
|
-
if
|
176
|
-
move_text_position(font.
|
154
|
+
if i < last_gap_before
|
155
|
+
move_text_position(font.line_gap - font.descender)
|
156
|
+
move_text_position(options[:spacing]) if options[:spacing]
|
177
157
|
end
|
178
|
-
|
179
|
-
move_text_position(options[:spacing]) if options[:spacing]
|
180
158
|
end
|
181
159
|
end
|
182
160
|
end
|
183
161
|
|
184
162
|
def add_text_content(text, x, y, options)
|
185
|
-
|
163
|
+
chunks = font.encode_text(text,options)
|
186
164
|
|
187
165
|
add_content "\nBT"
|
188
|
-
add_content "/#{font.identifier} #{font.size} Tf"
|
189
166
|
if options[:rotate]
|
190
167
|
rad = options[:rotate].to_i * Math::PI / 180
|
191
168
|
arr = [ Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), x, y ]
|
@@ -193,9 +170,14 @@ module Prawn
|
|
193
170
|
else
|
194
171
|
add_content "#{x} #{y} Td"
|
195
172
|
end
|
196
|
-
|
197
|
-
|
198
|
-
|
173
|
+
|
174
|
+
chunks.each do |(subset, string)|
|
175
|
+
font.add_to_current_page(subset)
|
176
|
+
add_content "/#{font.identifier_for(subset)} #{font_size} Tf"
|
177
|
+
|
178
|
+
operation = options[:kerning] && string.is_a?(Array) ? "TJ" : "Tj"
|
179
|
+
add_content Prawn::PdfObject(string, true) << " " << operation
|
180
|
+
end
|
199
181
|
add_content "ET\n"
|
200
182
|
end
|
201
183
|
end
|