prawn 0.2.3 → 0.3.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.
Files changed (144) hide show
  1. data/README +6 -10
  2. data/Rakefile +4 -13
  3. data/data/encodings/win_ansi.txt +29 -0
  4. data/data/images/fractal.jpg +0 -0
  5. data/data/images/letterhead.jpg +0 -0
  6. data/examples/bounding_box/bounding_boxes.rb +44 -0
  7. data/examples/bounding_box/lazy_bounding_boxes.rb +28 -0
  8. data/examples/bounding_box/padded_box.rb +24 -0
  9. data/examples/{russian_boxes.rb → bounding_box/russian_boxes.rb} +9 -6
  10. data/examples/general/background.rb +20 -0
  11. data/examples/{canvas.rb → general/canvas.rb} +6 -2
  12. data/examples/general/measurement_units.rb +52 -0
  13. data/examples/{multi_page_layout.rb → general/multi_page_layout.rb} +6 -3
  14. data/examples/{page_geometry.rb → general/page_geometry.rb} +6 -2
  15. data/examples/{image.rb → graphics/basic_images.rb} +8 -4
  16. data/examples/graphics/cmyk.rb +13 -0
  17. data/examples/graphics/curves.rb +12 -0
  18. data/examples/{hexagon.rb → graphics/hexagon.rb} +5 -5
  19. data/examples/graphics/image_fit.rb +16 -0
  20. data/examples/graphics/image_flow.rb +38 -0
  21. data/examples/graphics/image_position.rb +18 -0
  22. data/examples/{line.rb → graphics/line.rb} +4 -2
  23. data/examples/{png_types.rb → graphics/png_types.rb} +4 -4
  24. data/examples/{polygons.rb → graphics/polygons.rb} +5 -4
  25. data/examples/graphics/remote_images.rb +12 -0
  26. data/examples/{ruport_helpers.rb → graphics/ruport_style_helpers.rb} +8 -5
  27. data/examples/graphics/stroke_bounds.rb +23 -0
  28. data/examples/{chinese_text_wrapping.rb → m17n/chinese_text_wrapping.rb} +7 -4
  29. data/examples/m17n/euro.rb +16 -0
  30. data/examples/m17n/sjis.rb +29 -0
  31. data/examples/m17n/utf8.rb +14 -0
  32. data/examples/m17n/win_ansi_charset.rb +55 -0
  33. data/examples/{addressbook.csv → table/addressbook.csv} +0 -0
  34. data/examples/{cell.rb → table/cell.rb} +8 -6
  35. data/examples/{currency.csv → table/currency.csv} +0 -0
  36. data/examples/{fancy_table.rb → table/fancy_table.rb} +9 -6
  37. data/examples/{ruport_formatter.rb → table/ruport_formatter.rb} +6 -3
  38. data/examples/{table.rb → table/table.rb} +6 -2
  39. data/examples/table/table_alignment.rb +18 -0
  40. data/examples/table/table_border_color.rb +17 -0
  41. data/examples/table/table_colspan.rb +19 -0
  42. data/examples/table/table_header_color.rb +19 -0
  43. data/examples/table/table_header_underline.rb +15 -0
  44. data/examples/{alignment.rb → text/alignment.rb} +5 -2
  45. data/examples/text/family_based_styling.rb +25 -0
  46. data/examples/{flowing_text_with_header_and_footer.rb → text/flowing_text_with_header_and_footer.rb} +19 -8
  47. data/examples/text/font_calculations.rb +91 -0
  48. data/examples/text/font_size.rb +34 -0
  49. data/examples/{kerning.rb → text/kerning.rb} +5 -1
  50. data/examples/text/simple_text.rb +18 -0
  51. data/examples/text/simple_text_ttf.rb +18 -0
  52. data/examples/{span.rb → text/span.rb} +5 -2
  53. data/examples/text/text_box.rb +26 -0
  54. data/examples/{text_flow.rb → text/text_flow.rb} +5 -2
  55. data/lib/prawn.rb +26 -20
  56. data/lib/prawn/compatibility.rb +5 -8
  57. data/lib/prawn/document.rb +29 -13
  58. data/lib/prawn/document/annotations.rb +63 -0
  59. data/lib/prawn/document/bounding_box.rb +18 -3
  60. data/lib/prawn/document/destinations.rb +81 -0
  61. data/lib/prawn/document/internals.rb +16 -2
  62. data/lib/prawn/document/page_geometry.rb +58 -57
  63. data/lib/prawn/document/span.rb +8 -0
  64. data/lib/prawn/document/table.rb +81 -31
  65. data/lib/prawn/document/text.rb +66 -21
  66. data/lib/prawn/document/text/box.rb +77 -0
  67. data/lib/prawn/encoding.rb +121 -0
  68. data/lib/prawn/errors.rb +4 -0
  69. data/lib/prawn/font.rb +70 -42
  70. data/lib/prawn/font/metrics.rb +64 -119
  71. data/lib/prawn/graphics.rb +105 -87
  72. data/lib/prawn/graphics/cell.rb +55 -28
  73. data/lib/prawn/graphics/color.rb +8 -0
  74. data/lib/prawn/images.rb +55 -12
  75. data/lib/prawn/images/jpg.rb +2 -1
  76. data/lib/prawn/images/png.rb +2 -1
  77. data/lib/prawn/literal_string.rb +14 -0
  78. data/lib/prawn/measurement_extensions.rb +46 -0
  79. data/lib/prawn/measurements.rb +71 -0
  80. data/lib/prawn/name_tree.rb +165 -0
  81. data/lib/prawn/pdf_object.rb +8 -1
  82. data/spec/annotations_spec.rb +90 -0
  83. data/spec/destinations_spec.rb +15 -0
  84. data/spec/document_spec.rb +39 -2
  85. data/spec/font_spec.rb +22 -0
  86. data/spec/graphics_spec.rb +99 -87
  87. data/spec/images_spec.rb +29 -1
  88. data/spec/measurement_units_spec.rb +23 -0
  89. data/spec/metrics_spec.rb +3 -2
  90. data/spec/name_tree_spec.rb +103 -0
  91. data/spec/pdf_object_spec.rb +15 -5
  92. data/spec/png_spec.rb +14 -14
  93. data/spec/spec_helper.rb +8 -6
  94. data/spec/table_spec.rb +40 -0
  95. data/spec/text_spec.rb +6 -4
  96. data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
  97. data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
  98. data/vendor/ttfunk/example.rb +5 -0
  99. data/vendor/ttfunk/lib/ttfunk.rb +48 -0
  100. data/vendor/ttfunk/lib/ttfunk/table.rb +27 -0
  101. data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +94 -0
  102. data/vendor/ttfunk/lib/ttfunk/table/directory.rb +25 -0
  103. data/vendor/ttfunk/lib/ttfunk/table/head.rb +25 -0
  104. data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +27 -0
  105. data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +20 -0
  106. data/vendor/ttfunk/lib/ttfunk/table/kern.rb +48 -0
  107. data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +17 -0
  108. data/vendor/ttfunk/lib/ttfunk/table/name.rb +52 -0
  109. metadata +93 -62
  110. data/examples/bounding_boxes.rb +0 -30
  111. data/examples/curves.rb +0 -10
  112. data/examples/family_based_styling.rb +0 -21
  113. data/examples/font_size.rb +0 -19
  114. data/examples/image2.rb +0 -13
  115. data/examples/image_flow.rb +0 -29
  116. data/examples/lazy_bounding_boxes.rb +0 -19
  117. data/examples/remote_images.rb +0 -7
  118. data/examples/simple_text.rb +0 -15
  119. data/examples/simple_text_ttf.rb +0 -16
  120. data/examples/sjis.rb +0 -21
  121. data/examples/utf8.rb +0 -12
  122. data/vendor/font_ttf/ttf.rb +0 -20
  123. data/vendor/font_ttf/ttf/datatypes.rb +0 -189
  124. data/vendor/font_ttf/ttf/encodings.rb +0 -140
  125. data/vendor/font_ttf/ttf/exceptions.rb +0 -28
  126. data/vendor/font_ttf/ttf/file.rb +0 -290
  127. data/vendor/font_ttf/ttf/fontchunk.rb +0 -77
  128. data/vendor/font_ttf/ttf/table/cmap.rb +0 -408
  129. data/vendor/font_ttf/ttf/table/cvt.rb +0 -49
  130. data/vendor/font_ttf/ttf/table/fpgm.rb +0 -48
  131. data/vendor/font_ttf/ttf/table/gasp.rb +0 -88
  132. data/vendor/font_ttf/ttf/table/glyf.rb +0 -452
  133. data/vendor/font_ttf/ttf/table/head.rb +0 -86
  134. data/vendor/font_ttf/ttf/table/hhea.rb +0 -96
  135. data/vendor/font_ttf/ttf/table/hmtx.rb +0 -98
  136. data/vendor/font_ttf/ttf/table/kern.rb +0 -186
  137. data/vendor/font_ttf/ttf/table/loca.rb +0 -75
  138. data/vendor/font_ttf/ttf/table/maxp.rb +0 -81
  139. data/vendor/font_ttf/ttf/table/name.rb +0 -222
  140. data/vendor/font_ttf/ttf/table/os2.rb +0 -172
  141. data/vendor/font_ttf/ttf/table/post.rb +0 -120
  142. data/vendor/font_ttf/ttf/table/prep.rb +0 -27
  143. data/vendor/font_ttf/ttf/table/vhea.rb +0 -45
  144. 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
@@ -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 String
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
@@ -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
@@ -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
 
@@ -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