prawn-core 0.5.0.1
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.
- data/COPYING +340 -0
- data/LICENSE +56 -0
- data/README +121 -0
- data/Rakefile +74 -0
- data/data/encodings/win_ansi.txt +29 -0
- data/data/fonts/Action Man.dfont +0 -0
- data/data/fonts/Activa.ttf +0 -0
- data/data/fonts/Chalkboard.ttf +0 -0
- data/data/fonts/Courier-Bold.afm +342 -0
- data/data/fonts/Courier-BoldOblique.afm +342 -0
- data/data/fonts/Courier-Oblique.afm +342 -0
- data/data/fonts/Courier.afm +342 -0
- data/data/fonts/DejaVuSans.ttf +0 -0
- data/data/fonts/Dustismo_Roman.ttf +0 -0
- data/data/fonts/Helvetica-Bold.afm +2827 -0
- data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
- data/data/fonts/Helvetica-Oblique.afm +3051 -0
- data/data/fonts/Helvetica.afm +3051 -0
- data/data/fonts/MustRead.html +19 -0
- data/data/fonts/Symbol.afm +213 -0
- data/data/fonts/Times-Bold.afm +2588 -0
- data/data/fonts/Times-BoldItalic.afm +2384 -0
- data/data/fonts/Times-Italic.afm +2667 -0
- data/data/fonts/Times-Roman.afm +2419 -0
- data/data/fonts/ZapfDingbats.afm +225 -0
- data/data/fonts/comicsans.ttf +0 -0
- data/data/fonts/gkai00mp.ttf +0 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.dat +0 -0
- data/data/images/16bit.png +0 -0
- data/data/images/arrow.png +0 -0
- data/data/images/arrow2.png +0 -0
- data/data/images/barcode_issue.png +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.dat +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.dat +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/rails.dat +0 -0
- data/data/images/rails.png +0 -0
- data/data/images/ruport.png +0 -0
- data/data/images/ruport_data.dat +0 -0
- data/data/images/ruport_transparent.png +0 -0
- data/data/images/ruport_type0.png +0 -0
- data/data/images/stef.jpg +0 -0
- data/data/images/tru256.bmp +0 -0
- data/data/images/web-links.dat +1 -0
- data/data/images/web-links.png +0 -0
- data/data/shift_jis_text.txt +1 -0
- data/examples/bounding_box/bounding_boxes.rb +44 -0
- data/examples/bounding_box/russian_boxes.rb +37 -0
- data/examples/column_box/column_box_example.rb +44 -0
- data/examples/general/background.rb +20 -0
- data/examples/general/canvas.rb +16 -0
- data/examples/general/measurement_units.rb +52 -0
- data/examples/general/metadata-info.rb +17 -0
- data/examples/general/multi_page_layout.rb +17 -0
- data/examples/general/page_geometry.rb +32 -0
- data/examples/graphics/basic_images.rb +24 -0
- data/examples/graphics/cmyk.rb +13 -0
- data/examples/graphics/curves.rb +12 -0
- data/examples/graphics/hexagon.rb +14 -0
- 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/graphics/line.rb +33 -0
- data/examples/graphics/png_types.rb +23 -0
- data/examples/graphics/polygons.rb +17 -0
- data/examples/graphics/remote_images.rb +12 -0
- data/examples/graphics/ruport_style_helpers.rb +20 -0
- data/examples/graphics/stroke_bounds.rb +21 -0
- data/examples/m17n/chinese_text_wrapping.rb +20 -0
- 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/text/alignment.rb +19 -0
- data/examples/text/dfont.rb +49 -0
- data/examples/text/family_based_styling.rb +25 -0
- data/examples/text/font_calculations.rb +92 -0
- data/examples/text/font_size.rb +34 -0
- data/examples/text/kerning.rb +31 -0
- data/examples/text/simple_text.rb +18 -0
- data/examples/text/simple_text_ttf.rb +18 -0
- data/examples/text/span.rb +30 -0
- data/examples/text/text_box.rb +26 -0
- data/examples/text/text_flow.rb +68 -0
- data/lib/prawn/compatibility.rb +38 -0
- data/lib/prawn/core.rb +79 -0
- data/lib/prawn/document.rb +399 -0
- data/lib/prawn/document/annotations.rb +63 -0
- data/lib/prawn/document/bounding_box.rb +377 -0
- data/lib/prawn/document/column_box.rb +89 -0
- data/lib/prawn/document/destinations.rb +81 -0
- data/lib/prawn/document/internals.rb +133 -0
- data/lib/prawn/document/page_geometry.rb +149 -0
- data/lib/prawn/document/span.rb +55 -0
- data/lib/prawn/document/text.rb +186 -0
- data/lib/prawn/document/text/box.rb +83 -0
- data/lib/prawn/document/text/wrapping.rb +59 -0
- data/lib/prawn/encoding.rb +121 -0
- data/lib/prawn/errors.rb +49 -0
- data/lib/prawn/font.rb +292 -0
- data/lib/prawn/font/afm.rb +202 -0
- data/lib/prawn/font/dfont.rb +31 -0
- data/lib/prawn/font/ttf.rb +327 -0
- data/lib/prawn/graphics.rb +257 -0
- data/lib/prawn/graphics/color.rb +141 -0
- data/lib/prawn/images.rb +339 -0
- data/lib/prawn/images/jpg.rb +45 -0
- data/lib/prawn/images/png.rb +217 -0
- 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 +77 -0
- data/lib/prawn/reference.rb +59 -0
- data/spec/annotations_spec.rb +90 -0
- data/spec/bounding_box_spec.rb +141 -0
- data/spec/destinations_spec.rb +15 -0
- data/spec/document_spec.rb +178 -0
- data/spec/font_spec.rb +274 -0
- data/spec/graphics_spec.rb +209 -0
- data/spec/images_spec.rb +79 -0
- data/spec/jpg_spec.rb +25 -0
- data/spec/measurement_units_spec.rb +23 -0
- data/spec/name_tree_spec.rb +103 -0
- data/spec/pdf_object_spec.rb +117 -0
- data/spec/png_spec.rb +236 -0
- data/spec/reference_spec.rb +42 -0
- data/spec/span_spec.rb +45 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/text_box_spec.rb +83 -0
- data/spec/text_spec.rb +178 -0
- data/vendor/pdf-inspector/README +18 -0
- data/vendor/pdf-inspector/lib/pdf/inspector.rb +25 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +80 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/page.rb +16 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/text.rb +31 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/xobject.rb +19 -0
- data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
- data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
- data/vendor/ttfunk/example.rb +45 -0
- data/vendor/ttfunk/lib/ttfunk.rb +102 -0
- 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 +46 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +34 -0
- 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 +44 -0
- data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +41 -0
- data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +47 -0
- data/vendor/ttfunk/lib/ttfunk/table/kern.rb +79 -0
- 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 +40 -0
- data/vendor/ttfunk/lib/ttfunk/table/name.rb +119 -0
- 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 +245 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
4
|
+
|
|
5
|
+
describe "A Reference object" do
|
|
6
|
+
it "should produce a PDF reference on #to_s call" do
|
|
7
|
+
ref = Prawn::Reference(1,true)
|
|
8
|
+
ref.to_s.should == "1 0 R"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should allow changing generation number" do
|
|
12
|
+
ref = Prawn::Reference(1,true)
|
|
13
|
+
ref.gen = 1
|
|
14
|
+
ref.to_s.should == "1 1 R"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should generate a valid PDF object for the referenced data" do
|
|
18
|
+
ref = Prawn::Reference(2,[1,"foo"])
|
|
19
|
+
ref.object.should == "2 0 obj\n#{Prawn::PdfObject([1,"foo"])}\nendobj\n"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should automatically open a stream when #<< is used" do
|
|
23
|
+
ref = Prawn::Reference(1, :Length => 41)
|
|
24
|
+
ref << "BT\n/F1 12 Tf\n72 712 Td\n( A stream ) Tj\nET"
|
|
25
|
+
ref.object.should == "1 0 obj\n<< /Length 41\n>>\nstream"+
|
|
26
|
+
"\nBT\n/F1 12 Tf\n72 712 Td\n( A stream ) Tj\nET" +
|
|
27
|
+
"\nendstream\nendobj\n"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should compress a stream upon request" do
|
|
31
|
+
ref = Prawn::Reference(2,{})
|
|
32
|
+
ref << "Hi There " * 20
|
|
33
|
+
|
|
34
|
+
cref = Prawn::Reference(2,{})
|
|
35
|
+
cref << "Hi There " * 20
|
|
36
|
+
cref.compress_stream
|
|
37
|
+
|
|
38
|
+
assert cref.stream.size < ref.stream.size,
|
|
39
|
+
"compressed stream expected to be smaller than source but wasn't"
|
|
40
|
+
cref.data[:Filter].should == :FlateDecode
|
|
41
|
+
end
|
|
42
|
+
end
|
data/spec/span_spec.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
4
|
+
|
|
5
|
+
describe "drawing span" do
|
|
6
|
+
|
|
7
|
+
before(:each) {
|
|
8
|
+
Prawn.debug = false
|
|
9
|
+
create_pdf
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
it "should only accept :position as option in debug mode" do
|
|
13
|
+
Prawn.debug = true
|
|
14
|
+
lambda { @pdf.span(350, {:x => 3}) {} }.should.raise(Prawn::Errors::UnknownOption)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should have raise an error if :position is invalid" do
|
|
18
|
+
lambda { @pdf.span(350, :position => :x) {} }.should.raise(ArgumentError)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should restore the margin box when bounding box exits" do
|
|
22
|
+
margin_box = @pdf.bounds
|
|
23
|
+
|
|
24
|
+
@pdf.span(350, :position => :center) do
|
|
25
|
+
@pdf.text "Here's some centered text in a 350 point column. " * 100
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@pdf.bounds.should == margin_box
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should do create a margin box" do
|
|
33
|
+
y = @pdf.y
|
|
34
|
+
margin_box = @pdf.span(350, :position => :center) do
|
|
35
|
+
@pdf.text "Here's some centered text in a 350 point column. " * 100
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
margin_box.top.should == 792.0
|
|
39
|
+
margin_box.bottom.should == 0
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
puts "Prawn specs: Running on Ruby Version: #{RUBY_VERSION}"
|
|
4
|
+
|
|
5
|
+
require "rubygems"
|
|
6
|
+
require "test/spec"
|
|
7
|
+
require "mocha"
|
|
8
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
|
9
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'vendor','pdf-inspector','lib')
|
|
10
|
+
require "prawn/core"
|
|
11
|
+
|
|
12
|
+
Prawn.debug = true
|
|
13
|
+
|
|
14
|
+
gem 'pdf-reader', ">=0.7.3"
|
|
15
|
+
require "pdf/reader"
|
|
16
|
+
require "pdf/inspector"
|
|
17
|
+
|
|
18
|
+
def create_pdf(klass=Prawn::Document)
|
|
19
|
+
@pdf = klass.new(:left_margin => 0,
|
|
20
|
+
:right_margin => 0,
|
|
21
|
+
:top_margin => 0,
|
|
22
|
+
:bottom_margin => 0)
|
|
23
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
4
|
+
|
|
5
|
+
describe "A text box" do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
create_pdf
|
|
9
|
+
@x = 100
|
|
10
|
+
@y = 125
|
|
11
|
+
@width = 50
|
|
12
|
+
@height = @pdf.font.height * 10
|
|
13
|
+
@text = "Oh hai text box. " * 200
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should have a truncated text" do
|
|
17
|
+
@overflow = :truncate
|
|
18
|
+
create_text_box
|
|
19
|
+
@box.render
|
|
20
|
+
@box.text.should == "Oh hai\ntext box.\n" * 5
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should have a height equal to @height" do
|
|
24
|
+
@overflow = :truncate
|
|
25
|
+
create_text_box
|
|
26
|
+
@box.render
|
|
27
|
+
@box.height.should == @height
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should add ... to for overflow :ellipses" do
|
|
31
|
+
@overflow = :ellipses
|
|
32
|
+
@height = @pdf.font.height * 2
|
|
33
|
+
@text = "Oh hai text box.\n" * 4
|
|
34
|
+
create_text_box
|
|
35
|
+
@box.render
|
|
36
|
+
@box.text.should == "Oh hai\ntext bo..."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should not fail if height is smaller than 1 line" do
|
|
40
|
+
@text = "a b c d e fgi"
|
|
41
|
+
@width = 30
|
|
42
|
+
@height = @pdf.font.height * 0.5
|
|
43
|
+
@overflow = :ellipses
|
|
44
|
+
create_text_box
|
|
45
|
+
@box.render
|
|
46
|
+
@box.text.should == ""
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should keep text intact for overflow :expand" do
|
|
50
|
+
@overflow = :expand
|
|
51
|
+
@text = "Oh hai text box.\n" * 4
|
|
52
|
+
@height = 0
|
|
53
|
+
create_text_box
|
|
54
|
+
@box.render
|
|
55
|
+
@box.text.should == "Oh hai\ntext box.\n" * 4
|
|
56
|
+
@box.height.should == 0
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create_text_box
|
|
60
|
+
@box = Prawn::Document::Text::Box.new(@text,
|
|
61
|
+
:width => @width, :height => @height,
|
|
62
|
+
:overflow => @overflow,
|
|
63
|
+
:at => [@x, @y],
|
|
64
|
+
:for => @pdf)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "drawing bounding boxes" do
|
|
69
|
+
|
|
70
|
+
before(:each) { create_pdf }
|
|
71
|
+
|
|
72
|
+
it "should restore the margin box when bounding box exits" do
|
|
73
|
+
margin_box = @pdf.bounds
|
|
74
|
+
|
|
75
|
+
@pdf.text_box "Oh hai text box. " * 11, :height => @pdf.font.height * 10
|
|
76
|
+
|
|
77
|
+
@pdf.bounds.should == margin_box
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
data/spec/text_spec.rb
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
4
|
+
|
|
5
|
+
describe "when drawing text" do
|
|
6
|
+
|
|
7
|
+
before(:each) { create_pdf }
|
|
8
|
+
|
|
9
|
+
it "should advance down the document based on font_height" do
|
|
10
|
+
position = @pdf.y
|
|
11
|
+
@pdf.text "Foo"
|
|
12
|
+
|
|
13
|
+
@pdf.y.should.be.close(position - @pdf.font.height, 0.0001)
|
|
14
|
+
|
|
15
|
+
position = @pdf.y
|
|
16
|
+
@pdf.text "Foo\nBar\nBaz"
|
|
17
|
+
@pdf.y.should.be.close(position - 3*@pdf.font.height, 0.0001)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should advance down the document based on font ascender only if final_gap is given" do
|
|
21
|
+
position = @pdf.y
|
|
22
|
+
@pdf.text "Foo", :final_gap => false
|
|
23
|
+
|
|
24
|
+
@pdf.y.should.be.close(position - @pdf.font.ascender, 0.0001)
|
|
25
|
+
|
|
26
|
+
position = @pdf.y
|
|
27
|
+
@pdf.text "Foo\nBar\nBaz", :final_gap => false
|
|
28
|
+
@pdf.y.should.be.close(position - 2*@pdf.font.height - @pdf.font.ascender, 0.0001)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should default to 12 point helvetica" do
|
|
32
|
+
@pdf.text "Blah", :at => [100,100]
|
|
33
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
34
|
+
text.font_settings[0][:name].should == :Helvetica
|
|
35
|
+
text.font_settings[0][:size].should == 12
|
|
36
|
+
text.strings.first.should == "Blah"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should allow setting font size" do
|
|
40
|
+
@pdf.text "Blah", :at => [100,100], :size => 16
|
|
41
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
42
|
+
text.font_settings[0][:size].should == 16
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should allow setting a default font size" do
|
|
46
|
+
@pdf.font_size = 16
|
|
47
|
+
@pdf.text "Blah"
|
|
48
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
49
|
+
text.font_settings[0][:size].should == 16
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should allow setting font size in DSL style" do
|
|
53
|
+
@pdf.font_size 20
|
|
54
|
+
@pdf.font_size.should == 20
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should allow overriding default font for a single instance" do
|
|
58
|
+
@pdf.font_size = 16
|
|
59
|
+
|
|
60
|
+
@pdf.text "Blah", :size => 11
|
|
61
|
+
@pdf.text "Blaz"
|
|
62
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
63
|
+
text.font_settings[0][:size].should == 11
|
|
64
|
+
text.font_settings[1][:size].should == 16
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should allow setting a font size transaction with a block" do
|
|
68
|
+
@pdf.font_size 16 do
|
|
69
|
+
@pdf.text 'Blah'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@pdf.text 'blah'
|
|
73
|
+
|
|
74
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
75
|
+
text.font_settings[0][:size].should == 16
|
|
76
|
+
text.font_settings[1][:size].should == 12
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should allow manual setting the font size " +
|
|
80
|
+
"when in a font size block" do
|
|
81
|
+
@pdf.font_size(16) do
|
|
82
|
+
@pdf.text 'Foo'
|
|
83
|
+
@pdf.text 'Blah', :size => 11
|
|
84
|
+
@pdf.text 'Blaz'
|
|
85
|
+
end
|
|
86
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
87
|
+
text.font_settings[0][:size].should == 16
|
|
88
|
+
text.font_settings[1][:size].should == 11
|
|
89
|
+
text.font_settings[2][:size].should == 16
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should allow registering of built-in font_settings on the fly" do
|
|
93
|
+
@pdf.font "Times-Roman"
|
|
94
|
+
@pdf.text "Blah", :at => [100,100]
|
|
95
|
+
@pdf.font "Courier"
|
|
96
|
+
@pdf.text "Blaz", :at => [150,150]
|
|
97
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
98
|
+
text.font_settings[0][:name].should == :"Times-Roman"
|
|
99
|
+
text.font_settings[1][:name].should == :Courier
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should utilise the same default font across multiple pages" do
|
|
103
|
+
@pdf.text "Blah", :at => [100,100]
|
|
104
|
+
@pdf.start_new_page
|
|
105
|
+
@pdf.text "Blaz", :at => [150,150]
|
|
106
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
107
|
+
|
|
108
|
+
text.font_settings.size.should == 2
|
|
109
|
+
text.font_settings[0][:name].should == :Helvetica
|
|
110
|
+
text.font_settings[1][:name].should == :Helvetica
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should raise an exception when an unknown font is used" do
|
|
114
|
+
lambda { @pdf.font "Pao bu" }.should.raise(Prawn::Errors::UnknownFont)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "should correctly render a utf-8 string when using a built-in font" do
|
|
118
|
+
str = "©" # copyright symbol
|
|
119
|
+
@pdf.text str
|
|
120
|
+
|
|
121
|
+
# grab the text from the rendered PDF and ensure it matches
|
|
122
|
+
text = PDF::Inspector::Text.analyze(@pdf.render)
|
|
123
|
+
text.strings.first.should == str
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if "spec".respond_to?(:encode!)
|
|
127
|
+
# Handle non utf-8 string encodings in a sane way on M17N aware VMs
|
|
128
|
+
it "should raise an exception when a utf-8 incompatible string is rendered" do
|
|
129
|
+
str = "Blah \xDD"
|
|
130
|
+
str.force_encoding("ASCII-8BIT")
|
|
131
|
+
lambda { @pdf.text str }.should.raise(ArgumentError)
|
|
132
|
+
end
|
|
133
|
+
it "should not raise an exception when a shift-jis string is rendered" do
|
|
134
|
+
datafile = "#{Prawn::BASEDIR}/data/shift_jis_text.txt"
|
|
135
|
+
sjis_str = File.open(datafile, "r:shift_jis") { |f| f.gets }
|
|
136
|
+
@pdf.font("#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf")
|
|
137
|
+
lambda { @pdf.text sjis_str }.should.not.raise(ArgumentError)
|
|
138
|
+
end
|
|
139
|
+
else
|
|
140
|
+
# Handle non utf-8 string encodings in a sane way on non-M17N aware VMs
|
|
141
|
+
it "should raise an exception when a corrupt utf-8 string is rendered" do
|
|
142
|
+
str = "Blah \xDD"
|
|
143
|
+
lambda { @pdf.text str }.should.raise(ArgumentError)
|
|
144
|
+
end
|
|
145
|
+
it "should raise an exception when a shift-jis string is rendered" do
|
|
146
|
+
sjis_str = File.read("#{Prawn::BASEDIR}/data/shift_jis_text.txt")
|
|
147
|
+
lambda { @pdf.text sjis_str }.should.raise(ArgumentError)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "should wrap text" do
|
|
152
|
+
@pdf = Prawn::Document.new
|
|
153
|
+
@pdf.font "Courier"
|
|
154
|
+
|
|
155
|
+
text = "Please wrap this text about HERE. More text that should be wrapped"
|
|
156
|
+
expect = "Please wrap this text about\nHERE. More text that should be\nwrapped"
|
|
157
|
+
|
|
158
|
+
@pdf.naive_wrap(text, 220, @pdf.font_size).should == expect
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "should respect end of line when wrapping text" do
|
|
162
|
+
@pdf = Prawn::Document.new
|
|
163
|
+
@pdf.font "Courier"
|
|
164
|
+
text = "Please wrap only before\nTHIS word. Don't wrap this"
|
|
165
|
+
@pdf.naive_wrap(text, 220, @pdf.font_size).should == text
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "should respect end of line when wrapping text and mode is set to 'character'" do
|
|
169
|
+
@pdf = Prawn::Document.new
|
|
170
|
+
@pdf.font "Courier"
|
|
171
|
+
|
|
172
|
+
text = "You can wrap this text HERE"
|
|
173
|
+
expect = "You can wrap this text HE\nRE"
|
|
174
|
+
|
|
175
|
+
@pdf.naive_wrap(text, 180, @pdf.font_size, :mode => :character).should == expect
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
PDF::Inspector : A tool for analyzing PDF output
|
|
2
|
+
|
|
3
|
+
This library provides a number of PDF::Reader[0] based tools for use in testing
|
|
4
|
+
PDF output. Presently, the primary purpose of this tool is to support the
|
|
5
|
+
tests found in Prawn[1], a pure Ruby PDF generation library.
|
|
6
|
+
|
|
7
|
+
However, it may be useful to others, so we have made it available on Github[2]
|
|
8
|
+
|
|
9
|
+
Questions can be directed to the Prawn mailing list[3], but please remember
|
|
10
|
+
that this code is not necessarily suitable for production and has no officially
|
|
11
|
+
planned release date.
|
|
12
|
+
|
|
13
|
+
That having been said, patches are welcome!
|
|
14
|
+
|
|
15
|
+
[0] http://github.com/yob/pdf-reader
|
|
16
|
+
[1] http://github.com/sandal/prawn
|
|
17
|
+
[2] http://github.com/sandal/pdf-inspector
|
|
18
|
+
[3] http://groups.google.com/group/prawn-ruby
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "rubygems"
|
|
2
|
+
require "pdf/reader"
|
|
3
|
+
require "pdf/inspector/text"
|
|
4
|
+
require "pdf/inspector/xobject"
|
|
5
|
+
require "pdf/inspector/graphics"
|
|
6
|
+
require "pdf/inspector/page"
|
|
7
|
+
|
|
8
|
+
module PDF
|
|
9
|
+
class Inspector
|
|
10
|
+
def self.analyze(output,*args,&block)
|
|
11
|
+
obs = self.new(*args, &block)
|
|
12
|
+
PDF::Reader.string(output,obs)
|
|
13
|
+
obs
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.analyze_file(filename,*args,&block)
|
|
17
|
+
analyze(File.open(filename, "rb") { |f| f.read },*args,&block)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.parse(obj)
|
|
21
|
+
PDF::Reader::Parser.new(
|
|
22
|
+
PDF::Reader::Buffer.new(StringIO.new(obj)), nil).parse_token
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module PDF
|
|
2
|
+
class Inspector
|
|
3
|
+
module Graphics
|
|
4
|
+
class Line < Inspector
|
|
5
|
+
attr_accessor :points, :widths
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@points = []
|
|
9
|
+
@widths = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def append_line(*params)
|
|
13
|
+
@points << params
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def begin_new_subpath(*params)
|
|
17
|
+
@points << params
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def set_line_width(params)
|
|
21
|
+
@widths << params
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Rectangle < Inspector
|
|
27
|
+
attr_reader :rectangles
|
|
28
|
+
|
|
29
|
+
def initialize
|
|
30
|
+
@rectangles = []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def append_rectangle(*params)
|
|
34
|
+
@rectangles << { :point => params[0..1],
|
|
35
|
+
:width => params[2],
|
|
36
|
+
:height => params[3] }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class Curve < Inspector
|
|
41
|
+
|
|
42
|
+
attr_reader :coords
|
|
43
|
+
|
|
44
|
+
def initialize
|
|
45
|
+
@coords = []
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def begin_new_subpath(*params)
|
|
49
|
+
@coords += params
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def append_curved_segment(*params)
|
|
53
|
+
@coords += params
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Color < Inspector
|
|
59
|
+
attr_reader :stroke_color, :fill_color, :stroke_color_count,
|
|
60
|
+
:fill_color_count
|
|
61
|
+
|
|
62
|
+
def initialize
|
|
63
|
+
@stroke_color_count = 0
|
|
64
|
+
@fill_color_count = 0
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def set_rgb_color_for_stroking(*params)
|
|
68
|
+
@stroke_color_count += 1
|
|
69
|
+
@stroke_color = params
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def set_rgb_color_for_nonstroking(*params)
|
|
73
|
+
@fill_color_count += 1
|
|
74
|
+
@fill_color = params
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|