prawn 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +6 -10
- data/Rakefile +4 -13
- data/data/encodings/win_ansi.txt +29 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/examples/bounding_box/bounding_boxes.rb +44 -0
- data/examples/bounding_box/lazy_bounding_boxes.rb +28 -0
- data/examples/bounding_box/padded_box.rb +24 -0
- data/examples/{russian_boxes.rb → bounding_box/russian_boxes.rb} +9 -6
- data/examples/general/background.rb +20 -0
- data/examples/{canvas.rb → general/canvas.rb} +6 -2
- data/examples/general/measurement_units.rb +52 -0
- data/examples/{multi_page_layout.rb → general/multi_page_layout.rb} +6 -3
- data/examples/{page_geometry.rb → general/page_geometry.rb} +6 -2
- data/examples/{image.rb → graphics/basic_images.rb} +8 -4
- data/examples/graphics/cmyk.rb +13 -0
- data/examples/graphics/curves.rb +12 -0
- data/examples/{hexagon.rb → graphics/hexagon.rb} +5 -5
- data/examples/graphics/image_fit.rb +16 -0
- data/examples/graphics/image_flow.rb +38 -0
- data/examples/graphics/image_position.rb +18 -0
- data/examples/{line.rb → graphics/line.rb} +4 -2
- data/examples/{png_types.rb → graphics/png_types.rb} +4 -4
- data/examples/{polygons.rb → graphics/polygons.rb} +5 -4
- data/examples/graphics/remote_images.rb +12 -0
- data/examples/{ruport_helpers.rb → graphics/ruport_style_helpers.rb} +8 -5
- data/examples/graphics/stroke_bounds.rb +23 -0
- data/examples/{chinese_text_wrapping.rb → m17n/chinese_text_wrapping.rb} +7 -4
- data/examples/m17n/euro.rb +16 -0
- data/examples/m17n/sjis.rb +29 -0
- data/examples/m17n/utf8.rb +14 -0
- data/examples/m17n/win_ansi_charset.rb +55 -0
- data/examples/{addressbook.csv → table/addressbook.csv} +0 -0
- data/examples/{cell.rb → table/cell.rb} +8 -6
- data/examples/{currency.csv → table/currency.csv} +0 -0
- data/examples/{fancy_table.rb → table/fancy_table.rb} +9 -6
- data/examples/{ruport_formatter.rb → table/ruport_formatter.rb} +6 -3
- data/examples/{table.rb → table/table.rb} +6 -2
- data/examples/table/table_alignment.rb +18 -0
- data/examples/table/table_border_color.rb +17 -0
- data/examples/table/table_colspan.rb +19 -0
- data/examples/table/table_header_color.rb +19 -0
- data/examples/table/table_header_underline.rb +15 -0
- data/examples/{alignment.rb → text/alignment.rb} +5 -2
- data/examples/text/family_based_styling.rb +25 -0
- data/examples/{flowing_text_with_header_and_footer.rb → text/flowing_text_with_header_and_footer.rb} +19 -8
- data/examples/text/font_calculations.rb +91 -0
- data/examples/text/font_size.rb +34 -0
- data/examples/{kerning.rb → text/kerning.rb} +5 -1
- data/examples/text/simple_text.rb +18 -0
- data/examples/text/simple_text_ttf.rb +18 -0
- data/examples/{span.rb → text/span.rb} +5 -2
- data/examples/text/text_box.rb +26 -0
- data/examples/{text_flow.rb → text/text_flow.rb} +5 -2
- data/lib/prawn.rb +26 -20
- data/lib/prawn/compatibility.rb +5 -8
- data/lib/prawn/document.rb +29 -13
- data/lib/prawn/document/annotations.rb +63 -0
- data/lib/prawn/document/bounding_box.rb +18 -3
- data/lib/prawn/document/destinations.rb +81 -0
- data/lib/prawn/document/internals.rb +16 -2
- data/lib/prawn/document/page_geometry.rb +58 -57
- data/lib/prawn/document/span.rb +8 -0
- data/lib/prawn/document/table.rb +81 -31
- data/lib/prawn/document/text.rb +66 -21
- data/lib/prawn/document/text/box.rb +77 -0
- data/lib/prawn/encoding.rb +121 -0
- data/lib/prawn/errors.rb +4 -0
- data/lib/prawn/font.rb +70 -42
- data/lib/prawn/font/metrics.rb +64 -119
- data/lib/prawn/graphics.rb +105 -87
- data/lib/prawn/graphics/cell.rb +55 -28
- data/lib/prawn/graphics/color.rb +8 -0
- data/lib/prawn/images.rb +55 -12
- data/lib/prawn/images/jpg.rb +2 -1
- data/lib/prawn/images/png.rb +2 -1
- data/lib/prawn/literal_string.rb +14 -0
- data/lib/prawn/measurement_extensions.rb +46 -0
- data/lib/prawn/measurements.rb +71 -0
- data/lib/prawn/name_tree.rb +165 -0
- data/lib/prawn/pdf_object.rb +8 -1
- data/spec/annotations_spec.rb +90 -0
- data/spec/destinations_spec.rb +15 -0
- data/spec/document_spec.rb +39 -2
- data/spec/font_spec.rb +22 -0
- data/spec/graphics_spec.rb +99 -87
- data/spec/images_spec.rb +29 -1
- data/spec/measurement_units_spec.rb +23 -0
- data/spec/metrics_spec.rb +3 -2
- data/spec/name_tree_spec.rb +103 -0
- data/spec/pdf_object_spec.rb +15 -5
- data/spec/png_spec.rb +14 -14
- data/spec/spec_helper.rb +8 -6
- data/spec/table_spec.rb +40 -0
- data/spec/text_spec.rb +6 -4
- data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
- data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
- data/vendor/ttfunk/example.rb +5 -0
- data/vendor/ttfunk/lib/ttfunk.rb +48 -0
- data/vendor/ttfunk/lib/ttfunk/table.rb +27 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +94 -0
- data/vendor/ttfunk/lib/ttfunk/table/directory.rb +25 -0
- data/vendor/ttfunk/lib/ttfunk/table/head.rb +25 -0
- data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +27 -0
- data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +20 -0
- data/vendor/ttfunk/lib/ttfunk/table/kern.rb +48 -0
- data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/table/name.rb +52 -0
- metadata +93 -62
- data/examples/bounding_boxes.rb +0 -30
- data/examples/curves.rb +0 -10
- data/examples/family_based_styling.rb +0 -21
- data/examples/font_size.rb +0 -19
- data/examples/image2.rb +0 -13
- data/examples/image_flow.rb +0 -29
- data/examples/lazy_bounding_boxes.rb +0 -19
- data/examples/remote_images.rb +0 -7
- data/examples/simple_text.rb +0 -15
- data/examples/simple_text_ttf.rb +0 -16
- data/examples/sjis.rb +0 -21
- data/examples/utf8.rb +0 -12
- data/vendor/font_ttf/ttf.rb +0 -20
- data/vendor/font_ttf/ttf/datatypes.rb +0 -189
- data/vendor/font_ttf/ttf/encodings.rb +0 -140
- data/vendor/font_ttf/ttf/exceptions.rb +0 -28
- data/vendor/font_ttf/ttf/file.rb +0 -290
- data/vendor/font_ttf/ttf/fontchunk.rb +0 -77
- data/vendor/font_ttf/ttf/table/cmap.rb +0 -408
- data/vendor/font_ttf/ttf/table/cvt.rb +0 -49
- data/vendor/font_ttf/ttf/table/fpgm.rb +0 -48
- data/vendor/font_ttf/ttf/table/gasp.rb +0 -88
- data/vendor/font_ttf/ttf/table/glyf.rb +0 -452
- data/vendor/font_ttf/ttf/table/head.rb +0 -86
- data/vendor/font_ttf/ttf/table/hhea.rb +0 -96
- data/vendor/font_ttf/ttf/table/hmtx.rb +0 -98
- data/vendor/font_ttf/ttf/table/kern.rb +0 -186
- data/vendor/font_ttf/ttf/table/loca.rb +0 -75
- data/vendor/font_ttf/ttf/table/maxp.rb +0 -81
- data/vendor/font_ttf/ttf/table/name.rb +0 -222
- data/vendor/font_ttf/ttf/table/os2.rb +0 -172
- data/vendor/font_ttf/ttf/table/post.rb +0 -120
- data/vendor/font_ttf/ttf/table/prep.rb +0 -27
- data/vendor/font_ttf/ttf/table/vhea.rb +0 -45
- data/vendor/font_ttf/ttf/table/vmtx.rb +0 -36
@@ -0,0 +1,165 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# name_tree.rb : Implements NameTree for PDF
|
4
|
+
#
|
5
|
+
# Copyright November 2008, Jamis Buck. All Rights Reserved.
|
6
|
+
#
|
7
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
+
#
|
9
|
+
require 'prawn/literal_string'
|
10
|
+
require 'prawn/reference'
|
11
|
+
|
12
|
+
module Prawn
|
13
|
+
module NameTree #:nodoc:
|
14
|
+
class Node #:nodoc:
|
15
|
+
attr_reader :children
|
16
|
+
attr_reader :limit
|
17
|
+
attr_reader :document
|
18
|
+
attr_accessor :parent
|
19
|
+
attr_accessor :ref
|
20
|
+
|
21
|
+
def initialize(document, limit, parent=nil)
|
22
|
+
@document = document
|
23
|
+
@children = []
|
24
|
+
@limit = limit
|
25
|
+
@parent = parent
|
26
|
+
@ref = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def empty?
|
30
|
+
children.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def size
|
34
|
+
leaf? ? children.size : children.inject(0) { |sum, child| sum + child.size }
|
35
|
+
end
|
36
|
+
|
37
|
+
def leaf?
|
38
|
+
children.empty? || children.first.is_a?(Value)
|
39
|
+
end
|
40
|
+
|
41
|
+
def add(name, value)
|
42
|
+
self << Value.new(name, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_hash
|
46
|
+
hash = {}
|
47
|
+
|
48
|
+
hash[:Limits] = [least, greatest] if parent
|
49
|
+
if leaf?
|
50
|
+
hash[:Names] = children if leaf?
|
51
|
+
else
|
52
|
+
hash[:Kids] = children.map { |child| child.ref }
|
53
|
+
end
|
54
|
+
|
55
|
+
return hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def least
|
59
|
+
if leaf?
|
60
|
+
children.first.name
|
61
|
+
else
|
62
|
+
children.first.least
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def greatest
|
67
|
+
if leaf?
|
68
|
+
children.last.name
|
69
|
+
else
|
70
|
+
children.last.greatest
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def <<(value)
|
75
|
+
if children.empty?
|
76
|
+
children << value
|
77
|
+
elsif leaf?
|
78
|
+
children.insert(insertion_point(value), value)
|
79
|
+
split! if children.length > limit
|
80
|
+
else
|
81
|
+
fit = children.detect { |child| child >= value }
|
82
|
+
fit << value
|
83
|
+
end
|
84
|
+
|
85
|
+
value
|
86
|
+
end
|
87
|
+
|
88
|
+
def >=(value)
|
89
|
+
children.empty? || children.last >= value
|
90
|
+
end
|
91
|
+
|
92
|
+
def split!
|
93
|
+
if parent
|
94
|
+
parent.split(self)
|
95
|
+
else
|
96
|
+
left, right = new_node(self), new_node(self)
|
97
|
+
split_children(self, left, right)
|
98
|
+
children.replace([left, right])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
|
104
|
+
def split(node)
|
105
|
+
new_child = new_node(self)
|
106
|
+
split_children(node, node, new_child)
|
107
|
+
index = children.index(node)
|
108
|
+
children.insert(index+1, new_child)
|
109
|
+
split! if children.length > limit
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def new_node(parent=nil)
|
115
|
+
node = Node.new(document, limit, parent)
|
116
|
+
node.ref = document.ref(node)
|
117
|
+
return node
|
118
|
+
end
|
119
|
+
|
120
|
+
def split_children(node, left, right)
|
121
|
+
half = (node.limit+1)/2
|
122
|
+
|
123
|
+
left_children, right_children = node.children[0...half], node.children[half..-1]
|
124
|
+
|
125
|
+
left.children.replace(left_children)
|
126
|
+
right.children.replace(right_children)
|
127
|
+
|
128
|
+
unless node.leaf?
|
129
|
+
left_children.each { |child| child.parent = left }
|
130
|
+
right_children.each { |child| child.parent = right }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def insertion_point(value)
|
135
|
+
children.each_with_index do |child, index|
|
136
|
+
return index if child >= value
|
137
|
+
end
|
138
|
+
return children.length
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class Value #:nodoc:
|
143
|
+
include Comparable
|
144
|
+
|
145
|
+
attr_reader :name
|
146
|
+
attr_reader :value
|
147
|
+
|
148
|
+
def initialize(name, value)
|
149
|
+
@name, @value = Prawn::LiteralString.new(name), value
|
150
|
+
end
|
151
|
+
|
152
|
+
def <=>(leaf)
|
153
|
+
name <=> leaf.name
|
154
|
+
end
|
155
|
+
|
156
|
+
def inspect
|
157
|
+
"#<Value: #{name.inspect} : #{value.inspect}>"
|
158
|
+
end
|
159
|
+
|
160
|
+
def to_s
|
161
|
+
"#{name} : #{value}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/lib/prawn/pdf_object.rb
CHANGED
@@ -34,7 +34,10 @@ module Prawn
|
|
34
34
|
when Numeric then String(obj)
|
35
35
|
when Array
|
36
36
|
"[" << obj.map { |e| PdfObject(e, in_content_stream) }.join(' ') << "]"
|
37
|
-
when
|
37
|
+
when Prawn::LiteralString
|
38
|
+
obj = obj.gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
|
39
|
+
"(#{obj})"
|
40
|
+
when String
|
38
41
|
obj = "\xFE\xFF" + obj.unpack("U*").pack("n*") unless in_content_stream
|
39
42
|
"<" << obj.unpack("H*").first << ">"
|
40
43
|
when Symbol
|
@@ -57,6 +60,10 @@ module Prawn
|
|
57
60
|
output << ">>"
|
58
61
|
when Prawn::Reference
|
59
62
|
obj.to_s
|
63
|
+
when Prawn::NameTree::Node
|
64
|
+
PdfObject(obj.to_hash)
|
65
|
+
when Prawn::NameTree::Value
|
66
|
+
PdfObject(obj.name) + " " + PdfObject(obj.value)
|
60
67
|
else
|
61
68
|
raise Prawn::Errors::FailedObjectConversion,
|
62
69
|
"This object cannot be serialized to PDF"
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
|
+
|
5
|
+
class PageAnnotations
|
6
|
+
attr_reader :pages
|
7
|
+
|
8
|
+
def self.parse(document)
|
9
|
+
receiver = new
|
10
|
+
PDF::Reader.string(document.render, receiver)
|
11
|
+
return receiver
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@pages = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def begin_page(params)
|
19
|
+
@pages << params
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "When creating annotations" do
|
24
|
+
|
25
|
+
before(:each) { create_pdf }
|
26
|
+
|
27
|
+
it "should append annotation to current page" do
|
28
|
+
@pdf.start_new_page
|
29
|
+
@pdf.annotate(:Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
|
30
|
+
obj = PageAnnotations.parse(@pdf)
|
31
|
+
obj.pages[0][:Annots].nil?.should == true
|
32
|
+
obj.pages[1][:Annots].length.should == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should force :Type to be :Annot" do
|
36
|
+
opts = @pdf.annotate(:Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
|
37
|
+
opts[:Type].should == :Annot
|
38
|
+
opts = @pdf.annotate(:Type => :Bogus, :Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
|
39
|
+
opts[:Type].should == :Annot
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "When creating text annotations" do
|
45
|
+
|
46
|
+
before(:each) do
|
47
|
+
@rect = [0,0,10,10]
|
48
|
+
@content = "Hello, world!"
|
49
|
+
create_pdf
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should build appropriate annotation" do
|
53
|
+
opts = @pdf.text_annotation(@rect, @content)
|
54
|
+
opts[:Type].should == :Annot
|
55
|
+
opts[:Subtype].should == :Text
|
56
|
+
opts[:Rect].should == @rect
|
57
|
+
opts[:Contents].should == @content
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should merge extra options" do
|
61
|
+
opts = @pdf.text_annotation(@rect, @content, :Open => true, :Subtype => :Bogus)
|
62
|
+
opts[:Subtype].should == :Text
|
63
|
+
opts[:Open].should == true
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "When creating link annotations" do
|
69
|
+
|
70
|
+
before(:each) do
|
71
|
+
@rect = [0,0,10,10]
|
72
|
+
@dest = "home"
|
73
|
+
create_pdf
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should build appropriate annotation" do
|
77
|
+
opts = @pdf.link_annotation(@rect, :Dest => @dest)
|
78
|
+
opts[:Type].should == :Annot
|
79
|
+
opts[:Subtype].should == :Link
|
80
|
+
opts[:Rect].should == @rect
|
81
|
+
opts[:Dest].should == @dest
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should merge extra options" do
|
85
|
+
opts = @pdf.link_annotation(@rect, :Dest => @dest, :Subtype => :Bogus)
|
86
|
+
opts[:Subtype].should == :Link
|
87
|
+
opts[:Dest].should == @dest
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
|
+
|
5
|
+
describe "When creating destinations" do
|
6
|
+
|
7
|
+
before(:each) { create_pdf }
|
8
|
+
|
9
|
+
it "should add entry to Dests name tree" do
|
10
|
+
@pdf.dests.data.empty?.should == true
|
11
|
+
@pdf.add_dest "candy", "chocolate"
|
12
|
+
@pdf.dests.data.size.should == 1
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/spec/document_spec.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
|
+
|
5
|
+
describe "The cursor" do
|
6
|
+
it "should equal pdf.y - bounds.absolute_bottom" do
|
7
|
+
pdf = Prawn::Document.new
|
8
|
+
pdf.cursor.should == pdf.bounds.top
|
9
|
+
|
10
|
+
pdf.y = 300
|
11
|
+
pdf.cursor.should == pdf.y - pdf.bounds.absolute_bottom
|
12
|
+
end
|
13
|
+
end
|
4
14
|
|
5
15
|
describe "When creating multi-page documents" do
|
6
16
|
|
@@ -38,7 +48,23 @@ describe "When beginning each new page" do
|
|
38
48
|
pdf.render
|
39
49
|
|
40
50
|
call_count.should == 3
|
41
|
-
end
|
51
|
+
end
|
52
|
+
describe "Background template feature" do
|
53
|
+
before(:each) do
|
54
|
+
@filename = "#{Prawn::BASEDIR}/data/images/pigs.jpg"
|
55
|
+
@pdf = Prawn::Document.new(:background => @filename)
|
56
|
+
end
|
57
|
+
it "should place a background image if it is in options block" do
|
58
|
+
output = @pdf.render
|
59
|
+
images = PDF::Inspector::XObject.analyze(output)
|
60
|
+
# there should be 2 images in the page resources
|
61
|
+
images.page_xobjects.first.size.should == 1
|
62
|
+
end
|
63
|
+
it "should place a background image if it is in options block" do
|
64
|
+
@pdf.instance_variable_defined?(:@background).should == true
|
65
|
+
@pdf.instance_variable_get(:@background).should == @filename
|
66
|
+
end
|
67
|
+
end
|
42
68
|
|
43
69
|
end
|
44
70
|
|
@@ -84,6 +110,17 @@ describe "When ending each page" do
|
|
84
110
|
pdf.render
|
85
111
|
end
|
86
112
|
|
113
|
+
it "should result in a smaller file size when compressed" do
|
114
|
+
doc_uncompressed = Prawn::Document.new
|
115
|
+
doc_compressed = Prawn::Document.new(:compress => true)
|
116
|
+
[doc_compressed, doc_uncompressed].each do |pdf|
|
117
|
+
pdf.font "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
|
118
|
+
pdf.text "更可怕的是,同质化竞争对手可以按照URL中后面这个ID来遍历" * 10
|
119
|
+
end
|
120
|
+
|
121
|
+
doc_compressed.render.length.should.be < doc_uncompressed.render.length
|
122
|
+
end
|
123
|
+
|
87
124
|
end
|
88
125
|
|
89
126
|
describe "When setting page size" do
|
data/spec/font_spec.rb
CHANGED
@@ -70,6 +70,28 @@ describe "font style support" do
|
|
70
70
|
|
71
71
|
end
|
72
72
|
|
73
|
+
describe "Transactional font handling" do
|
74
|
+
before(:each) { create_pdf }
|
75
|
+
|
76
|
+
it "should allow setting of size directly when font is created" do
|
77
|
+
@pdf.font "Courier", :size => 16
|
78
|
+
@pdf.font.size.should == 16
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should allow temporary setting of a new font using a transaction" do
|
82
|
+
original = @pdf.font
|
83
|
+
|
84
|
+
@pdf.font "Courier", :size => 16 do
|
85
|
+
@pdf.font.name.should == "Courier"
|
86
|
+
@pdf.font.size.should == 16
|
87
|
+
end
|
88
|
+
|
89
|
+
@pdf.font.should == original
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
73
95
|
describe "Document#page_fonts" do
|
74
96
|
before(:each) { create_pdf }
|
75
97
|
|
data/spec/graphics_spec.rb
CHANGED
@@ -1,58 +1,70 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
|
-
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
|
+
|
5
5
|
describe "When drawing a line" do
|
6
|
-
|
6
|
+
|
7
7
|
before(:each) { create_pdf }
|
8
|
-
|
8
|
+
|
9
9
|
it "should draw a line from (100,600) to (100,500)" do
|
10
10
|
@pdf.line([100,600],[100,500])
|
11
|
-
|
11
|
+
|
12
12
|
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
13
|
-
|
14
|
-
line_drawing.points.should == [[100,600],[100,500]]
|
15
|
-
end
|
16
|
-
|
13
|
+
|
14
|
+
line_drawing.points.should == [[100,600],[100,500]]
|
15
|
+
end
|
16
|
+
|
17
17
|
it "should draw two lines at (100,600) to (100,500) " +
|
18
|
-
"and (75,100) to (50,125)" do
|
19
|
-
@pdf.line(100,600,100,500)
|
18
|
+
"and (75,100) to (50,125)" do
|
19
|
+
@pdf.line(100,600,100,500)
|
20
20
|
@pdf.line(75,100,50,125)
|
21
|
-
|
21
|
+
|
22
22
|
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
23
|
-
|
24
|
-
line_drawing.points.should ==
|
23
|
+
|
24
|
+
line_drawing.points.should ==
|
25
25
|
[[100.0, 600.0], [100.0, 500.0], [75.0, 100.0], [50.0, 125.0]]
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should properly set line width via line_width=" do
|
29
29
|
@pdf.line_width = 10
|
30
|
-
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
31
|
-
line.widths.first.should == 10
|
32
|
-
end
|
33
|
-
|
30
|
+
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
31
|
+
line.widths.first.should == 10
|
32
|
+
end
|
33
|
+
|
34
34
|
it "should properly set line width via line_width(width)" do
|
35
35
|
@pdf.line_width(10)
|
36
|
-
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
37
|
-
line.widths.first.should == 10
|
38
|
-
end
|
39
|
-
|
40
|
-
describe "(Horizontally)" do
|
41
|
-
|
42
|
-
before :each do
|
43
|
-
@pdf = Prawn::Document.new
|
36
|
+
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
37
|
+
line.widths.first.should == 10
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "(Horizontally)" do
|
41
|
+
it "should draw from [x1,pdf.y],[x2,pdf.y]" do
|
44
42
|
@pdf.horizontal_line(100,150)
|
45
43
|
@line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should draw from [x1,pdf.y],[x2,pdf.y]" do
|
49
44
|
@line.points.should == [[100.0 + @pdf.bounds.absolute_left, @pdf.y],
|
50
45
|
[150.0 + @pdf.bounds.absolute_left, @pdf.y]]
|
51
|
-
end
|
52
|
-
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should draw a line from (200, 250) to (300, 250)" do
|
49
|
+
@pdf.horizontal_line(200,300,:at => 250)
|
50
|
+
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
51
|
+
line_drawing.points.should == [[200,250],[300,250]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "(Vertically)" do
|
56
|
+
it "should draw a line from (350, 300) to (350, 400)" do
|
57
|
+
@pdf.vertical_line(300,400,:at => 350)
|
58
|
+
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
59
|
+
line_drawing.points.should == [[350,300],[350,400]]
|
60
|
+
end
|
61
|
+
it "should require a y coordinate" do
|
62
|
+
lambda { @pdf.vertical_line(400,500) }.
|
63
|
+
should.raise(ArgumentError)
|
64
|
+
end
|
53
65
|
end
|
54
|
-
|
55
|
-
end
|
66
|
+
|
67
|
+
end
|
56
68
|
|
57
69
|
describe "When drawing a polygon" do
|
58
70
|
|
@@ -61,11 +73,11 @@ describe "When drawing a polygon" do
|
|
61
73
|
it "should draw each line passed to polygon()" do
|
62
74
|
@pdf.polygon([100,500],[100,400],[200,400])
|
63
75
|
|
64
|
-
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
76
|
+
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
|
65
77
|
line_drawing.points.should == [[100,500],[100,400],[200,400],[100,500]]
|
66
78
|
end
|
67
79
|
|
68
|
-
end
|
80
|
+
end
|
69
81
|
|
70
82
|
describe "When drawing a rectangle" do
|
71
83
|
|
@@ -83,53 +95,53 @@ describe "When drawing a rectangle" do
|
|
83
95
|
|
84
96
|
end
|
85
97
|
|
86
|
-
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "When drawing a curve" do
|
87
101
|
|
88
|
-
describe "When drawing a curve" do
|
89
|
-
|
90
102
|
before(:each) { create_pdf }
|
91
|
-
|
103
|
+
|
92
104
|
it "should draw a bezier curve from 50,50 to 100,100" do
|
93
105
|
@pdf.move_to [50,50]
|
94
106
|
@pdf.curve_to [100,100],:bounds => [[20,90], [90,70]]
|
95
107
|
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
96
|
-
curve.coords.should == [50.0, 50.0, 20.0, 90.0, 90.0, 70.0, 100.0, 100.0]
|
97
|
-
end
|
98
|
-
|
108
|
+
curve.coords.should == [50.0, 50.0, 20.0, 90.0, 90.0, 70.0, 100.0, 100.0]
|
109
|
+
end
|
110
|
+
|
99
111
|
it "should draw a bezier curve from 100,100 to 50,50" do
|
100
|
-
@pdf.curve [100,100], [50,50], :bounds => [[20,90], [90,75]]
|
101
|
-
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
102
|
-
curve.coords.should == [100.0, 100.0, 20.0, 90.0, 90.0, 75.0, 50.0, 50.0]
|
112
|
+
@pdf.curve [100,100], [50,50], :bounds => [[20,90], [90,75]]
|
113
|
+
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
114
|
+
curve.coords.should == [100.0, 100.0, 20.0, 90.0, 90.0, 75.0, 50.0, 50.0]
|
103
115
|
end
|
104
|
-
|
105
|
-
end
|
116
|
+
|
117
|
+
end
|
106
118
|
|
107
119
|
describe "When drawing an ellipse" do
|
108
|
-
before(:each) do
|
120
|
+
before(:each) do
|
109
121
|
create_pdf
|
110
122
|
@pdf.ellipse_at [100,100], 25, 50
|
111
|
-
@curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
112
|
-
end
|
113
|
-
|
123
|
+
@curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
124
|
+
end
|
125
|
+
|
114
126
|
it "should move the pointer to the center of the ellipse after drawing" do
|
115
127
|
@curve.coords[-2..-1].should == [100,100]
|
116
|
-
end
|
117
|
-
|
118
|
-
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
119
131
|
|
120
132
|
describe "When drawing a circle" do
|
121
|
-
before(:each) do
|
133
|
+
before(:each) do
|
122
134
|
create_pdf
|
123
|
-
@pdf.circle_at [100,100], :radius => 25
|
135
|
+
@pdf.circle_at [100,100], :radius => 25
|
124
136
|
@pdf.ellipse_at [100,100], 25, 25
|
125
|
-
@curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
126
|
-
end
|
127
|
-
|
128
|
-
it "should stroke the same path as the equivalent ellipse" do
|
137
|
+
@curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should stroke the same path as the equivalent ellipse" do
|
129
141
|
middle = @curve.coords.length / 2
|
130
|
-
@curve.coords[0...middle].should == @curve.coords[middle..-1]
|
142
|
+
@curve.coords[0...middle].should == @curve.coords[middle..-1]
|
131
143
|
end
|
132
|
-
end
|
144
|
+
end
|
133
145
|
|
134
146
|
describe "When setting colors" do
|
135
147
|
|
@@ -144,54 +156,54 @@ describe "When setting colors" do
|
|
144
156
|
|
145
157
|
it "should set fill colors" do
|
146
158
|
@pdf.fill_color "ccff00"
|
147
|
-
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
159
|
+
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
148
160
|
# 80% red, 100% green, 0% blue
|
149
161
|
colors.fill_color.should == [0.8,1.0,0]
|
150
|
-
end
|
151
|
-
|
162
|
+
end
|
163
|
+
|
152
164
|
it "should reset the colors on each new page if they have been defined" do
|
153
165
|
@pdf.fill_color "ccff00"
|
154
|
-
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
155
|
-
|
156
|
-
colors.fill_color_count.should == 2
|
166
|
+
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
167
|
+
|
168
|
+
colors.fill_color_count.should == 2
|
157
169
|
colors.stroke_color_count.should == 1
|
158
|
-
@pdf.start_new_page
|
159
|
-
@pdf.stroke_color "ff00cc"
|
160
|
-
|
161
|
-
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
162
|
-
colors.fill_color_count.should == 3
|
170
|
+
@pdf.start_new_page
|
171
|
+
@pdf.stroke_color "ff00cc"
|
172
|
+
|
173
|
+
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
174
|
+
colors.fill_color_count.should == 3
|
163
175
|
colors.stroke_color_count.should == 3
|
164
|
-
|
176
|
+
|
165
177
|
@pdf.start_new_page
|
166
|
-
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
178
|
+
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
|
167
179
|
colors.fill_color_count.should == 4
|
168
180
|
colors.stroke_color_count.should == 4
|
169
|
-
|
181
|
+
|
170
182
|
colors.fill_color.should == [0.8,1.0,0.0]
|
171
|
-
colors.stroke_color.should == [1.0,0.0,0.8]
|
172
|
-
end
|
183
|
+
colors.stroke_color.should == [1.0,0.0,0.8]
|
184
|
+
end
|
173
185
|
|
174
186
|
end
|
175
187
|
|
176
188
|
describe "When using painting shortcuts" do
|
177
189
|
before(:each) { create_pdf }
|
178
|
-
|
190
|
+
|
179
191
|
it "should convert stroke_some_method(args) into some_method(args); stroke" do
|
180
192
|
@pdf.expects(:line_to).with([100,100])
|
181
193
|
@pdf.expects(:stroke)
|
182
|
-
|
194
|
+
|
183
195
|
@pdf.stroke_line_to [100,100]
|
184
|
-
end
|
185
|
-
|
196
|
+
end
|
197
|
+
|
186
198
|
it "should convert fill_some_method(args) into some_method(args); fill" do
|
187
|
-
@pdf.expects(:line_to).with([100,100])
|
199
|
+
@pdf.expects(:line_to).with([100,100])
|
188
200
|
@pdf.expects(:fill)
|
189
|
-
|
201
|
+
|
190
202
|
@pdf.fill_line_to [100,100]
|
191
203
|
end
|
192
|
-
|
204
|
+
|
193
205
|
it "should not break method_missing" do
|
194
206
|
lambda { @pdf.i_have_a_pretty_girlfriend_named_jia }.
|
195
|
-
should.raise(NoMethodError)
|
207
|
+
should.raise(NoMethodError)
|
196
208
|
end
|
197
|
-
end
|
209
|
+
end
|