prawn 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/Rakefile +12 -0
- data/lib/prawn.rb +9 -21
- data/lib/prawn/document.rb +95 -68
- data/lib/prawn/document/bounding_box.rb +22 -4
- data/lib/prawn/document/column_box.rb +2 -0
- data/lib/prawn/document/graphics_state.rb +1 -1
- data/lib/prawn/document/internals.rb +2 -2
- data/lib/prawn/document/snapshot.rb +2 -1
- data/lib/prawn/document/span.rb +2 -0
- data/lib/prawn/encoding.rb +1 -1
- data/lib/prawn/font.rb +89 -75
- data/lib/prawn/font/afm.rb +3 -0
- data/lib/prawn/font/dfont.rb +1 -0
- data/lib/prawn/font/ttf.rb +2 -0
- data/lib/prawn/font_metric_cache.rb +3 -1
- data/lib/prawn/graphics.rb +2 -14
- data/lib/prawn/graphics/cap_style.rb +1 -0
- data/lib/prawn/graphics/color.rb +1 -0
- data/lib/prawn/graphics/dash.rb +3 -2
- data/lib/prawn/graphics/join_style.rb +2 -0
- data/lib/prawn/graphics/patterns.rb +1 -0
- data/lib/prawn/graphics/transformation.rb +1 -0
- data/lib/prawn/graphics/transparency.rb +2 -0
- data/lib/prawn/image_handler.rb +2 -0
- data/lib/prawn/images.rb +5 -0
- data/lib/prawn/images/image.rb +1 -0
- data/lib/prawn/images/jpg.rb +3 -0
- data/lib/prawn/images/png.rb +2 -0
- data/lib/prawn/layout.rb +8 -13
- data/lib/prawn/layout/grid.rb +15 -3
- data/lib/prawn/measurement_extensions.rb +4 -0
- data/lib/prawn/measurements.rb +2 -0
- data/lib/prawn/outline.rb +3 -1
- data/lib/prawn/repeater.rb +3 -1
- data/lib/prawn/security.rb +15 -7
- data/lib/prawn/security/arcfour.rb +52 -0
- data/lib/prawn/soft_mask.rb +3 -1
- data/lib/prawn/stamp.rb +2 -0
- data/lib/prawn/table.rb +2 -0
- data/lib/prawn/table/cell.rb +4 -1
- data/lib/prawn/table/cell/image.rb +1 -2
- data/lib/prawn/table/cell/in_table.rb +2 -0
- data/lib/prawn/table/cell/span_dummy.rb +1 -0
- data/lib/prawn/table/cells.rb +7 -2
- data/lib/prawn/table/column_width_calculator.rb +8 -2
- data/lib/prawn/text.rb +4 -2
- data/lib/prawn/text/box.rb +3 -0
- data/lib/prawn/text/formatted/arranger.rb +2 -0
- data/lib/prawn/text/formatted/box.rb +55 -50
- data/lib/prawn/text/formatted/fragment.rb +2 -0
- data/lib/prawn/text/formatted/line_wrap.rb +1 -0
- data/lib/prawn/text/formatted/parser.rb +2 -0
- data/lib/prawn/text/formatted/wrap.rb +2 -0
- data/lib/prawn/utilities.rb +5 -3
- data/manual/graphics/common_lines.rb +2 -0
- data/manual/text/group.rb +2 -0
- data/manual/text/text.rb +1 -1
- data/prawn.gemspec +4 -3
- data/spec/grid_spec.rb +11 -0
- data/spec/object_store_spec.rb +1 -96
- data/spec/reference_spec.rb +0 -57
- data/spec/spec_helper.rb +7 -0
- data/spec/table_spec.rb +26 -0
- metadata +172 -185
- data/lib/pdf/core.rb +0 -35
- data/lib/pdf/core/annotations.rb +0 -60
- data/lib/pdf/core/byte_string.rb +0 -9
- data/lib/pdf/core/destinations.rb +0 -90
- data/lib/pdf/core/document_state.rb +0 -79
- data/lib/pdf/core/filter_list.rb +0 -51
- data/lib/pdf/core/filters.rb +0 -36
- data/lib/pdf/core/graphics_state.rb +0 -89
- data/lib/pdf/core/literal_string.rb +0 -16
- data/lib/pdf/core/name_tree.rb +0 -177
- data/lib/pdf/core/object_store.rb +0 -311
- data/lib/pdf/core/outline.rb +0 -315
- data/lib/pdf/core/page.rb +0 -212
- data/lib/pdf/core/page_geometry.rb +0 -126
- data/lib/pdf/core/pdf_object.rb +0 -99
- data/lib/pdf/core/reference.rb +0 -103
- data/lib/pdf/core/stream.rb +0 -98
- data/lib/pdf/core/text.rb +0 -275
- data/lib/prawn/templates.rb +0 -75
- data/spec/filters_spec.rb +0 -34
- data/spec/name_tree_spec.rb +0 -112
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/stream_spec.rb +0 -58
- data/spec/template_spec_obsolete.rb +0 -352
@@ -1,126 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# Describes PDF page geometries
|
4
|
-
#
|
5
|
-
# Copyright April 2008, Gregory Brown. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
|
-
module PDF
|
10
|
-
module Core
|
11
|
-
|
12
|
-
# Dimensions pulled from PDF::Writer, rubyforge.org/projects/ruby-pdf
|
13
|
-
#
|
14
|
-
# All of these dimensions are in PDF Points (1/72 inch)
|
15
|
-
#
|
16
|
-
# ===Inbuilt Sizes:
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# 4A0:: => 4767.87 x 6740.79
|
20
|
-
# 2A0:: => 3370.39 x 4767.87
|
21
|
-
# A0:: => 2383.94 x 3370.39
|
22
|
-
# A1:: => 1683.78 x 2383.94
|
23
|
-
# A2:: => 1190.55 x 1683.78
|
24
|
-
# A3:: => 841.89 x 1190.55
|
25
|
-
# A4:: => 595.28 x 841.89
|
26
|
-
# A5:: => 419.53 x 595.28
|
27
|
-
# A6:: => 297.64 x 419.53
|
28
|
-
# A7:: => 209.76 x 297.64
|
29
|
-
# A8:: => 147.40 x 209.76
|
30
|
-
# A9:: => 104.88 x 147.40
|
31
|
-
# A10:: => 73.70 x 104.88
|
32
|
-
# B0:: => 2834.65 x 4008.19
|
33
|
-
# B1:: => 2004.09 x 2834.65
|
34
|
-
# B2:: => 1417.32 x 2004.09
|
35
|
-
# B3:: => 1000.63 x 1417.32
|
36
|
-
# B4:: => 708.66 x 1000.63
|
37
|
-
# B5:: => 498.90 x 708.66
|
38
|
-
# B6:: => 354.33 x 498.90
|
39
|
-
# B7:: => 249.45 x 354.33
|
40
|
-
# B8:: => 175.75 x 249.45
|
41
|
-
# B9:: => 124.72 x 175.75
|
42
|
-
# B10:: => 87.87 x 124.72
|
43
|
-
# C0:: => 2599.37 x 3676.54
|
44
|
-
# C1:: => 1836.85 x 2599.37
|
45
|
-
# C2:: => 1298.27 x 1836.85
|
46
|
-
# C3:: => 918.43 x 1298.27
|
47
|
-
# C4:: => 649.13 x 918.43
|
48
|
-
# C5:: => 459.21 x 649.13
|
49
|
-
# C6:: => 323.15 x 459.21
|
50
|
-
# C7:: => 229.61 x 323.15
|
51
|
-
# C8:: => 161.57 x 229.61
|
52
|
-
# C9:: => 113.39 x 161.57
|
53
|
-
# C10:: => 79.37 x 113.39
|
54
|
-
# RA0:: => 2437.80 x 3458.27
|
55
|
-
# RA1:: => 1729.13 x 2437.80
|
56
|
-
# RA2:: => 1218.90 x 1729.13
|
57
|
-
# RA3:: => 864.57 x 1218.90
|
58
|
-
# RA4:: => 609.45 x 864.57
|
59
|
-
# SRA0:: => 2551.18 x 3628.35
|
60
|
-
# SRA1:: => 1814.17 x 2551.18
|
61
|
-
# SRA2:: => 1275.59 x 1814.17
|
62
|
-
# SRA3:: => 907.09 x 1275.59
|
63
|
-
# SRA4:: => 637.80 x 907.09
|
64
|
-
# EXECUTIVE:: => 521.86 x 756.00
|
65
|
-
# FOLIO:: => 612.00 x 936.00
|
66
|
-
# LEGAL:: => 612.00 x 1008.00
|
67
|
-
# LETTER:: => 612.00 x 792.00
|
68
|
-
# TABLOID:: => 792.00 x 1224.00
|
69
|
-
#
|
70
|
-
module PageGeometry
|
71
|
-
|
72
|
-
SIZES = { "4A0" => [4767.87, 6740.79],
|
73
|
-
"2A0" => [3370.39, 4767.87],
|
74
|
-
"A0" => [2383.94, 3370.39],
|
75
|
-
"A1" => [1683.78, 2383.94],
|
76
|
-
"A2" => [1190.55, 1683.78],
|
77
|
-
"A3" => [841.89, 1190.55],
|
78
|
-
"A4" => [595.28, 841.89],
|
79
|
-
"A5" => [419.53, 595.28],
|
80
|
-
"A6" => [297.64, 419.53],
|
81
|
-
"A7" => [209.76, 297.64],
|
82
|
-
"A8" => [147.40, 209.76],
|
83
|
-
"A9" => [104.88, 147.40],
|
84
|
-
"A10" => [73.70, 104.88],
|
85
|
-
"B0" => [2834.65, 4008.19],
|
86
|
-
"B1" => [2004.09, 2834.65],
|
87
|
-
"B2" => [1417.32, 2004.09],
|
88
|
-
"B3" => [1000.63, 1417.32],
|
89
|
-
"B4" => [708.66, 1000.63],
|
90
|
-
"B5" => [498.90, 708.66],
|
91
|
-
"B6" => [354.33, 498.90],
|
92
|
-
"B7" => [249.45, 354.33],
|
93
|
-
"B8" => [175.75, 249.45],
|
94
|
-
"B9" => [124.72, 175.75],
|
95
|
-
"B10" => [87.87, 124.72],
|
96
|
-
"C0" => [2599.37, 3676.54],
|
97
|
-
"C1" => [1836.85, 2599.37],
|
98
|
-
"C2" => [1298.27, 1836.85],
|
99
|
-
"C3" => [918.43, 1298.27],
|
100
|
-
"C4" => [649.13, 918.43],
|
101
|
-
"C5" => [459.21, 649.13],
|
102
|
-
"C6" => [323.15, 459.21],
|
103
|
-
"C7" => [229.61, 323.15],
|
104
|
-
"C8" => [161.57, 229.61],
|
105
|
-
"C9" => [113.39, 161.57],
|
106
|
-
"C10" => [79.37, 113.39],
|
107
|
-
"RA0" => [2437.80, 3458.27],
|
108
|
-
"RA1" => [1729.13, 2437.80],
|
109
|
-
"RA2" => [1218.90, 1729.13],
|
110
|
-
"RA3" => [864.57, 1218.90],
|
111
|
-
"RA4" => [609.45, 864.57],
|
112
|
-
"SRA0" => [2551.18, 3628.35],
|
113
|
-
"SRA1" => [1814.17, 2551.18],
|
114
|
-
"SRA2" => [1275.59, 1814.17],
|
115
|
-
"SRA3" => [907.09, 1275.59],
|
116
|
-
"SRA4" => [637.80, 907.09],
|
117
|
-
"EXECUTIVE" => [521.86, 756.00],
|
118
|
-
"FOLIO" => [612.00, 936.00],
|
119
|
-
"LEGAL" => [612.00, 1008.00],
|
120
|
-
"LETTER" => [612.00, 792.00],
|
121
|
-
"TABLOID" => [792.00, 1224.00] }
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
data/lib/pdf/core/pdf_object.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
|
-
# pdf_object.rb : Handles Ruby to PDF object serialization
|
4
|
-
#
|
5
|
-
# Copyright April 2008, Gregory Brown. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
|
-
# Top level Module
|
10
|
-
#
|
11
|
-
module PDF
|
12
|
-
module Core
|
13
|
-
module_function
|
14
|
-
|
15
|
-
def utf8_to_utf16(str)
|
16
|
-
"\xFE\xFF".force_encoding(::Encoding::UTF_16BE) + str.encode(::Encoding::UTF_16BE)
|
17
|
-
end
|
18
|
-
|
19
|
-
# encodes any string into a hex representation. The result is a string
|
20
|
-
# with only 0-9 and a-f characters. That result is valid ASCII so tag
|
21
|
-
# it as such to account for behaviour of different ruby VMs
|
22
|
-
def string_to_hex(str)
|
23
|
-
str.unpack("H*").first.force_encoding(::Encoding::US_ASCII)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Serializes Ruby objects to their PDF equivalents. Most primitive objects
|
27
|
-
# will work as expected, but please note that Name objects are represented
|
28
|
-
# by Ruby Symbol objects and Dictionary objects are represented by Ruby hashes
|
29
|
-
# (keyed by symbols)
|
30
|
-
#
|
31
|
-
# Examples:
|
32
|
-
#
|
33
|
-
# PdfObject(true) #=> "true"
|
34
|
-
# PdfObject(false) #=> "false"
|
35
|
-
# PdfObject(1.2124) #=> "1.2124"
|
36
|
-
# PdfObject("foo bar") #=> "(foo bar)"
|
37
|
-
# PdfObject(:Symbol) #=> "/Symbol"
|
38
|
-
# PdfObject(["foo",:bar, [1,2]]) #=> "[foo /bar [1 2]]"
|
39
|
-
#
|
40
|
-
def PdfObject(obj, in_content_stream = false)
|
41
|
-
case(obj)
|
42
|
-
when NilClass then "null"
|
43
|
-
when TrueClass then "true"
|
44
|
-
when FalseClass then "false"
|
45
|
-
when Numeric
|
46
|
-
if (str = String(obj)) =~ /e/i
|
47
|
-
# scientific notation is not supported in PDF
|
48
|
-
sprintf("%.16f", obj).gsub(/\.?0+\z/, "")
|
49
|
-
else
|
50
|
-
str
|
51
|
-
end
|
52
|
-
when Array
|
53
|
-
"[" << obj.map { |e| PdfObject(e, in_content_stream) }.join(' ') << "]"
|
54
|
-
when PDF::Core::LiteralString
|
55
|
-
obj = obj.gsub(/[\\\n\r\t\b\f\(\)]/n) { |m| "\\#{m}" }
|
56
|
-
"(#{obj})"
|
57
|
-
when Time
|
58
|
-
obj = obj.strftime("D:%Y%m%d%H%M%S%z").chop.chop + "'00'"
|
59
|
-
obj = obj.gsub(/[\\\n\r\t\b\f\(\)]/n) { |m| "\\#{m}" }
|
60
|
-
"(#{obj})"
|
61
|
-
when PDF::Core::ByteString
|
62
|
-
"<" << obj.unpack("H*").first << ">"
|
63
|
-
when String
|
64
|
-
obj = utf8_to_utf16(obj) unless in_content_stream
|
65
|
-
"<" << string_to_hex(obj) << ">"
|
66
|
-
when Symbol
|
67
|
-
"/" + obj.to_s.unpack("C*").map { |n|
|
68
|
-
if n < 33 || n > 126 || [35,40,41,47,60,62].include?(n)
|
69
|
-
"#" + n.to_s(16).upcase
|
70
|
-
else
|
71
|
-
[n].pack("C*")
|
72
|
-
end
|
73
|
-
}.join
|
74
|
-
when ::Hash
|
75
|
-
output = "<< "
|
76
|
-
obj.each do |k,v|
|
77
|
-
unless String === k || Symbol === k
|
78
|
-
raise PDF::Core::Errors::FailedObjectConversion,
|
79
|
-
"A PDF Dictionary must be keyed by names"
|
80
|
-
end
|
81
|
-
output << PdfObject(k.to_sym, in_content_stream) << " " <<
|
82
|
-
PdfObject(v, in_content_stream) << "\n"
|
83
|
-
end
|
84
|
-
output << ">>"
|
85
|
-
when PDF::Core::Reference
|
86
|
-
obj.to_s
|
87
|
-
when PDF::Core::NameTree::Node
|
88
|
-
PdfObject(obj.to_hash)
|
89
|
-
when PDF::Core::NameTree::Value
|
90
|
-
PdfObject(obj.name) + " " + PdfObject(obj.value)
|
91
|
-
when PDF::Core::OutlineRoot, PDF::Core::OutlineItem
|
92
|
-
PdfObject(obj.to_hash)
|
93
|
-
else
|
94
|
-
raise PDF::Core::Errors::FailedObjectConversion,
|
95
|
-
"This object cannot be serialized to PDF (#{obj.inspect})"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
data/lib/pdf/core/reference.rb
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# reference.rb : Implementation of PDF indirect objects
|
4
|
-
#
|
5
|
-
# Copyright April 2008, Gregory Brown. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
|
-
|
10
|
-
module PDF
|
11
|
-
module Core
|
12
|
-
class Reference #:nodoc:
|
13
|
-
|
14
|
-
attr_accessor :gen, :data, :offset, :stream, :live, :identifier
|
15
|
-
|
16
|
-
def initialize(id, data)
|
17
|
-
@identifier = id
|
18
|
-
@gen = 0
|
19
|
-
@data = data
|
20
|
-
@stream = Stream.new
|
21
|
-
end
|
22
|
-
|
23
|
-
def object
|
24
|
-
output = "#{@identifier} #{gen} obj\n"
|
25
|
-
unless @stream.empty?
|
26
|
-
output << PDF::Core::PdfObject(data.merge @stream.data) << "\n" << @stream.object
|
27
|
-
else
|
28
|
-
output << PDF::Core::PdfObject(data) << "\n"
|
29
|
-
end
|
30
|
-
|
31
|
-
output << "endobj\n"
|
32
|
-
end
|
33
|
-
|
34
|
-
def <<(io)
|
35
|
-
raise "Cannot attach stream to non-dictionary object" unless @data.is_a?(::Hash)
|
36
|
-
(@stream ||= Stream.new) << io
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_s
|
40
|
-
"#{@identifier} #{gen} R"
|
41
|
-
end
|
42
|
-
|
43
|
-
# Creates a deep copy of this ref. If +share+ is provided, shares the
|
44
|
-
# given dictionary entries between the old ref and the new.
|
45
|
-
#
|
46
|
-
def deep_copy(share=[])
|
47
|
-
r = dup
|
48
|
-
|
49
|
-
case r.data
|
50
|
-
when ::Hash
|
51
|
-
# Copy each entry not in +share+.
|
52
|
-
(r.data.keys - share).each do |k|
|
53
|
-
r.data[k] = Marshal.load(Marshal.dump(r.data[k]))
|
54
|
-
end
|
55
|
-
when PDF::Core::NameTree::Node
|
56
|
-
r.data = r.data.deep_copy
|
57
|
-
else
|
58
|
-
r.data = Marshal.load(Marshal.dump(r.data))
|
59
|
-
end
|
60
|
-
|
61
|
-
r.stream = Marshal.load(Marshal.dump(r.stream))
|
62
|
-
r
|
63
|
-
end
|
64
|
-
|
65
|
-
# Replaces the data and stream with that of other_ref.
|
66
|
-
def replace(other_ref)
|
67
|
-
@data = other_ref.data
|
68
|
-
@stream = other_ref.stream
|
69
|
-
end
|
70
|
-
|
71
|
-
# Marks this and all referenced objects live, recursively.
|
72
|
-
def mark_live
|
73
|
-
return if defined?(@live) && @live
|
74
|
-
@live = true
|
75
|
-
referenced_objects.each { |o| o.mark_live }
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
# All objects referenced by this one. Used for GC.
|
81
|
-
def referenced_objects(obj=@data)
|
82
|
-
case obj
|
83
|
-
when self.class
|
84
|
-
[]
|
85
|
-
when ::Hash
|
86
|
-
obj.values.map{|v| [v] + referenced_objects(v) }
|
87
|
-
when Array
|
88
|
-
obj.map{|v| [v] + referenced_objects(v) }
|
89
|
-
when PDF::Core::OutlineRoot, PDF::Core::OutlineItem
|
90
|
-
referenced_objects(obj.to_hash)
|
91
|
-
else []
|
92
|
-
end.flatten.grep(self.class)
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
module_function
|
98
|
-
|
99
|
-
def Reference(*args, &block) #:nodoc:
|
100
|
-
Reference.new(*args, &block)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
data/lib/pdf/core/stream.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# prawn/core/stream.rb : Implements Stream objects
|
4
|
-
#
|
5
|
-
# Copyright February 2013, Alexander Mankuta. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
|
-
module PDF
|
10
|
-
module Core
|
11
|
-
class Stream
|
12
|
-
attr_reader :filters
|
13
|
-
|
14
|
-
def initialize(io = nil)
|
15
|
-
@filtered_stream = ''
|
16
|
-
@stream = io
|
17
|
-
@filters = FilterList.new
|
18
|
-
end
|
19
|
-
|
20
|
-
def <<(io)
|
21
|
-
(@stream ||= '') << io
|
22
|
-
@filtered_stream = nil
|
23
|
-
self
|
24
|
-
end
|
25
|
-
|
26
|
-
def compress!
|
27
|
-
unless @filters.names.include? :FlateDecode
|
28
|
-
@filtered_stream = nil
|
29
|
-
@filters << :FlateDecode
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def compressed?
|
34
|
-
@filters.names.include? :FlateDecode
|
35
|
-
end
|
36
|
-
|
37
|
-
def empty?
|
38
|
-
@stream.nil?
|
39
|
-
end
|
40
|
-
|
41
|
-
def filtered_stream
|
42
|
-
if @stream
|
43
|
-
if @filtered_stream.nil?
|
44
|
-
@filtered_stream = @stream.dup
|
45
|
-
|
46
|
-
@filters.each do |(filter_name, params)|
|
47
|
-
if filter = PDF::Core::Filters.const_get(filter_name)
|
48
|
-
@filtered_stream = filter.encode @filtered_stream, params
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
@filtered_stream
|
54
|
-
# XXX Fillter stream
|
55
|
-
else
|
56
|
-
nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def length
|
61
|
-
@stream.length
|
62
|
-
end
|
63
|
-
|
64
|
-
def object
|
65
|
-
if filtered_stream
|
66
|
-
"stream\n#{filtered_stream}\nendstream\n"
|
67
|
-
else
|
68
|
-
''
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def data
|
73
|
-
if @stream
|
74
|
-
filter_names = @filters.names
|
75
|
-
filter_params = @filters.decode_params
|
76
|
-
|
77
|
-
d = {
|
78
|
-
:Length => filtered_stream.length
|
79
|
-
}
|
80
|
-
if filter_names.any?
|
81
|
-
d[:Filter] = filter_names
|
82
|
-
end
|
83
|
-
if filter_params.any? {|f| !f.nil? }
|
84
|
-
d[:DecodeParms] = filter_params
|
85
|
-
end
|
86
|
-
|
87
|
-
d
|
88
|
-
else
|
89
|
-
{}
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def inspect
|
94
|
-
"#<#{self.class.name}:0x#{'%014x' % object_id} @stream=#{@stream.inspect}, @filters=#{@filters.inspect}>"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
data/lib/pdf/core/text.rb
DELETED
@@ -1,275 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# prawn/core/text.rb : Implements low level text helpers for Prawn
|
4
|
-
#
|
5
|
-
# Copyright January 2010, Daniel Nelson. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
|
-
module PDF
|
10
|
-
module Core
|
11
|
-
module Text #:nodoc:
|
12
|
-
|
13
|
-
# These should be used as a base. Extensions may build on this list
|
14
|
-
#
|
15
|
-
VALID_OPTIONS = [:kerning, :size, :style]
|
16
|
-
MODES = { :fill => 0, :stroke => 1, :fill_stroke => 2, :invisible => 3,
|
17
|
-
:fill_clip => 4, :stroke_clip => 5, :fill_stroke_clip => 6,
|
18
|
-
:clip => 7 }
|
19
|
-
|
20
|
-
attr_reader :skip_encoding
|
21
|
-
|
22
|
-
# Low level text placement method. All font and size alterations
|
23
|
-
# should already be set
|
24
|
-
#
|
25
|
-
def draw_text!(text, options)
|
26
|
-
x,y = map_to_absolute(options[:at])
|
27
|
-
add_text_content(text,x,y,options)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Low level call to set the current font style and extract text options from
|
31
|
-
# an options hash. Should be called from within a save_font block
|
32
|
-
#
|
33
|
-
def process_text_options(options)
|
34
|
-
if options[:style]
|
35
|
-
raise "Bad font family" unless font.family
|
36
|
-
font(font.family, :style => options[:style])
|
37
|
-
end
|
38
|
-
|
39
|
-
# must compare against false to keep kerning on as default
|
40
|
-
unless options[:kerning] == false
|
41
|
-
options[:kerning] = font.has_kerning_data?
|
42
|
-
end
|
43
|
-
|
44
|
-
options[:size] ||= font_size
|
45
|
-
end
|
46
|
-
|
47
|
-
# Retrieve the current default kerning setting.
|
48
|
-
#
|
49
|
-
# Defaults to true
|
50
|
-
#
|
51
|
-
def default_kerning?
|
52
|
-
return true if !defined?(@default_kerning)
|
53
|
-
@default_kerning
|
54
|
-
end
|
55
|
-
|
56
|
-
# Call with a boolean to set the document-wide kerning setting. This can be
|
57
|
-
# overridden using the :kerning text option when drawing text or a text
|
58
|
-
# box.
|
59
|
-
#
|
60
|
-
# pdf.default_kerning = false
|
61
|
-
# pdf.text("hello world") # text is not kerned
|
62
|
-
# pdf.text("hello world", :kerning => true) # text is kerned
|
63
|
-
#
|
64
|
-
def default_kerning(boolean)
|
65
|
-
@default_kerning = boolean
|
66
|
-
end
|
67
|
-
|
68
|
-
alias_method :default_kerning=, :default_kerning
|
69
|
-
|
70
|
-
# Call with no argument to retrieve the current default leading.
|
71
|
-
#
|
72
|
-
# Call with a number to set the document-wide text leading. This can be
|
73
|
-
# overridden using the :leading text option when drawing text or a text
|
74
|
-
# box.
|
75
|
-
#
|
76
|
-
# pdf.default_leading = 7
|
77
|
-
# pdf.text("hello world") # a leading of 7 is used
|
78
|
-
# pdf.text("hello world", :leading => 0) # a leading of 0 is used
|
79
|
-
#
|
80
|
-
# Defaults to 0
|
81
|
-
#
|
82
|
-
def default_leading(number=nil)
|
83
|
-
if number.nil?
|
84
|
-
defined?(@default_leading) && @default_leading || 0
|
85
|
-
else
|
86
|
-
@default_leading = number
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
alias_method :default_leading=, :default_leading
|
91
|
-
|
92
|
-
# Call with no argument to retrieve the current text direction.
|
93
|
-
#
|
94
|
-
# Call with a symbol to set the document-wide text direction. This can be
|
95
|
-
# overridden using the :direction text option when drawing text or a text
|
96
|
-
# box.
|
97
|
-
#
|
98
|
-
# pdf.text_direction = :rtl
|
99
|
-
# pdf.text("hello world") # prints "dlrow olleh"
|
100
|
-
# pdf.text("hello world", :direction => :ltr) # prints "hello world"
|
101
|
-
#
|
102
|
-
# Valid directions are:
|
103
|
-
#
|
104
|
-
# * :ltr - left-to-right (default)
|
105
|
-
# * :rtl - right-to-left
|
106
|
-
#
|
107
|
-
# Side effects:
|
108
|
-
#
|
109
|
-
# * When printing left-to-right, the default text alignment is :left
|
110
|
-
# * When printing right-to-left, the default text alignment is :right
|
111
|
-
#
|
112
|
-
def text_direction(direction=nil)
|
113
|
-
if direction.nil?
|
114
|
-
defined?(@text_direction) && @text_direction || :ltr
|
115
|
-
else
|
116
|
-
@text_direction = direction
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
alias_method :text_direction=, :text_direction
|
121
|
-
|
122
|
-
# Call with no argument to retrieve the current fallback fonts.
|
123
|
-
#
|
124
|
-
# Call with an array of font names. Each name must be the name of an AFM
|
125
|
-
# font or the name that was used to register a family of TTF fonts (see
|
126
|
-
# Prawn::Document#font_families). If present, then each glyph will be
|
127
|
-
# rendered using the first font that includes the glyph, starting with the
|
128
|
-
# current font and then moving through :fallback_fonts from left to right.
|
129
|
-
#
|
130
|
-
# Call with an empty array to turn off fallback fonts
|
131
|
-
#
|
132
|
-
# file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
|
133
|
-
# font_families["Kai"] = {
|
134
|
-
# :normal => { :file => file, :font => "Kai" }
|
135
|
-
# }
|
136
|
-
# file = "#{Prawn::DATADIR}/fonts/Action Man.dfont"
|
137
|
-
# font_families["Action Man"] = {
|
138
|
-
# :normal => { :file => file, :font => "ActionMan" },
|
139
|
-
# }
|
140
|
-
# fallback_fonts ["Times-Roman", "Kai"]
|
141
|
-
# font "Action Man"
|
142
|
-
# text "hello ƒ 你好"
|
143
|
-
# > hello prints in Action Man
|
144
|
-
# > ƒ prints in Times-Roman
|
145
|
-
# > 你好 prints in Kai
|
146
|
-
#
|
147
|
-
# fallback_fonts [] # clears document-wide fallback fonts
|
148
|
-
#
|
149
|
-
# Side effects:
|
150
|
-
#
|
151
|
-
# * Increased overhead when fallback fonts are declared as each glyph is
|
152
|
-
# checked to see whether it exists in the current font
|
153
|
-
#
|
154
|
-
def fallback_fonts(fallback_fonts=nil)
|
155
|
-
if fallback_fonts.nil?
|
156
|
-
defined?(@fallback_fonts) && @fallback_fonts || []
|
157
|
-
else
|
158
|
-
@fallback_fonts = fallback_fonts
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
alias_method :fallback_fonts=, :fallback_fonts
|
163
|
-
|
164
|
-
# Call with no argument to retrieve the current text rendering mode.
|
165
|
-
#
|
166
|
-
# Call with a symbol and block to temporarily change the current
|
167
|
-
# text rendering mode.
|
168
|
-
#
|
169
|
-
# pdf.text_rendering_mode(:stroke) do
|
170
|
-
# pdf.text("Outlined Text")
|
171
|
-
# end
|
172
|
-
#
|
173
|
-
# Valid modes are:
|
174
|
-
#
|
175
|
-
# * :fill - fill text (default)
|
176
|
-
# * :stroke - stroke text
|
177
|
-
# * :fill_stroke - fill, then stroke text
|
178
|
-
# * :invisible - invisible text
|
179
|
-
# * :fill_clip - fill text then add to path for clipping
|
180
|
-
# * :stroke_clip - stroke text then add to path for clipping
|
181
|
-
# * :fill_stroke_clip - fill then stroke text, then add to path for clipping
|
182
|
-
# * :clip - add text to path for clipping
|
183
|
-
#
|
184
|
-
# There's the special mode :unknown which only occurs when we're working
|
185
|
-
# with templates. If left in :unknown, the first text command will force
|
186
|
-
# an assertion to :fill.
|
187
|
-
def text_rendering_mode(mode=nil)
|
188
|
-
return (defined?(@text_rendering_mode) && @text_rendering_mode || :fill) if mode.nil?
|
189
|
-
unless MODES.key?(mode)
|
190
|
-
raise ArgumentError, "mode must be between one of #{MODES.keys.join(', ')} (#{mode})"
|
191
|
-
end
|
192
|
-
original_mode = self.text_rendering_mode
|
193
|
-
if original_mode == :unknown
|
194
|
-
original_mode = :fill
|
195
|
-
add_content "\n#{MODES[:fill]} Tr"
|
196
|
-
end
|
197
|
-
if original_mode == mode
|
198
|
-
yield
|
199
|
-
else
|
200
|
-
@text_rendering_mode = mode
|
201
|
-
add_content "\n#{MODES[mode]} Tr"
|
202
|
-
yield
|
203
|
-
add_content "\n#{MODES[original_mode]} Tr"
|
204
|
-
@text_rendering_mode = original_mode
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def forget_text_rendering_mode!
|
209
|
-
@text_rendering_mode = :unknown
|
210
|
-
end
|
211
|
-
|
212
|
-
# Increases or decreases the space between characters.
|
213
|
-
# For horizontal text, a positive value will increase the space.
|
214
|
-
# For veritical text, a positive value will decrease the space.
|
215
|
-
#
|
216
|
-
def character_spacing(amount=nil)
|
217
|
-
return defined?(@character_spacing) && @character_spacing || 0 if amount.nil?
|
218
|
-
original_character_spacing = character_spacing
|
219
|
-
if original_character_spacing == amount
|
220
|
-
yield
|
221
|
-
else
|
222
|
-
@character_spacing = amount
|
223
|
-
add_content "\n%.3f Tc" % amount
|
224
|
-
yield
|
225
|
-
add_content "\n%.3f Tc" % original_character_spacing
|
226
|
-
@character_spacing = original_character_spacing
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
# Increases or decreases the space between words.
|
231
|
-
# For horizontal text, a positive value will increase the space.
|
232
|
-
# For veritical text, a positive value will decrease the space.
|
233
|
-
#
|
234
|
-
def word_spacing(amount=nil)
|
235
|
-
return defined?(@word_spacing) && @word_spacing || 0 if amount.nil?
|
236
|
-
original_word_spacing = word_spacing
|
237
|
-
if original_word_spacing == amount
|
238
|
-
yield
|
239
|
-
else
|
240
|
-
@word_spacing = amount
|
241
|
-
add_content "\n%.3f Tw" % amount
|
242
|
-
yield
|
243
|
-
add_content "\n%.3f Tw" % original_word_spacing
|
244
|
-
@word_spacing = original_word_spacing
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
private
|
249
|
-
|
250
|
-
def add_text_content(text, x, y, options)
|
251
|
-
chunks = font.encode_text(text,options)
|
252
|
-
|
253
|
-
add_content "\nBT"
|
254
|
-
|
255
|
-
if options[:rotate]
|
256
|
-
rad = options[:rotate].to_f * Math::PI / 180
|
257
|
-
arr = [ Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), x, y ]
|
258
|
-
add_content "%.3f %.3f %.3f %.3f %.3f %.3f Tm" % arr
|
259
|
-
else
|
260
|
-
add_content "#{x} #{y} Td"
|
261
|
-
end
|
262
|
-
|
263
|
-
chunks.each do |(subset, string)|
|
264
|
-
font.add_to_current_page(subset)
|
265
|
-
add_content "/#{font.identifier_for(subset)} #{font_size} Tf"
|
266
|
-
|
267
|
-
operation = options[:kerning] && string.is_a?(Array) ? "TJ" : "Tj"
|
268
|
-
add_content PDF::Core::PdfObject(string, true) << " " << operation
|
269
|
-
end
|
270
|
-
|
271
|
-
add_content "ET\n"
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|