alphasights-prawn 0.10.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.
- data/COPYING +340 -0
- data/HACKING +50 -0
- data/LICENSE +56 -0
- data/README +141 -0
- data/Rakefile +52 -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/pdfs/complex_template.pdf +0 -0
- data/data/pdfs/contains_ttf_font.pdf +0 -0
- data/data/pdfs/encrypted.pdf +0 -0
- data/data/pdfs/hexagon.pdf +61 -0
- data/data/pdfs/indirect_reference.pdf +86 -0
- data/data/pdfs/nested_pages.pdf +118 -0
- data/data/pdfs/resources_as_indirect_object.pdf +83 -0
- data/data/pdfs/two_hexagons.pdf +90 -0
- data/data/pdfs/version_1_6.pdf +61 -0
- data/data/shift_jis_text.txt +1 -0
- data/examples/bounding_box/bounding_boxes.rb +43 -0
- data/examples/bounding_box/indentation.rb +34 -0
- data/examples/bounding_box/russian_boxes.rb +36 -0
- data/examples/bounding_box/stretched_nesting.rb +67 -0
- data/examples/builder/simple.rb +28 -0
- data/examples/example_helper.rb +4 -0
- data/examples/general/background.rb +23 -0
- data/examples/general/canvas.rb +15 -0
- data/examples/general/context_sensitive_headers.rb +37 -0
- data/examples/general/float.rb +11 -0
- data/examples/general/margin.rb +36 -0
- data/examples/general/measurement_units.rb +51 -0
- data/examples/general/metadata-info.rb +16 -0
- data/examples/general/multi_page_layout.rb +18 -0
- data/examples/general/outlines.rb +50 -0
- data/examples/general/page_geometry.rb +31 -0
- data/examples/general/page_numbering.rb +15 -0
- data/examples/general/repeaters.rb +47 -0
- data/examples/general/stamp.rb +41 -0
- data/examples/general/templates.rb +13 -0
- data/examples/graphics/basic_images.rb +23 -0
- data/examples/graphics/chunkable.rb +38 -0
- data/examples/graphics/cmyk.rb +12 -0
- data/examples/graphics/curves.rb +11 -0
- data/examples/graphics/hexagon.rb +13 -0
- data/examples/graphics/image_fit.rb +15 -0
- data/examples/graphics/image_flow.rb +37 -0
- data/examples/graphics/image_position.rb +17 -0
- data/examples/graphics/line.rb +32 -0
- data/examples/graphics/png_types.rb +22 -0
- data/examples/graphics/polygons.rb +16 -0
- data/examples/graphics/remote_images.rb +12 -0
- data/examples/graphics/rounded_polygons.rb +19 -0
- data/examples/graphics/rounded_rectangle.rb +20 -0
- data/examples/graphics/ruport_style_helpers.rb +19 -0
- data/examples/graphics/stroke_bounds.rb +20 -0
- data/examples/graphics/stroke_cap_and_join.rb +45 -0
- data/examples/graphics/stroke_dash.rb +42 -0
- data/examples/graphics/transformations.rb +52 -0
- data/examples/graphics/transparency.rb +26 -0
- data/examples/m17n/chinese_text_wrapping.rb +17 -0
- data/examples/m17n/euro.rb +15 -0
- data/examples/m17n/sjis.rb +28 -0
- data/examples/m17n/utf8.rb +13 -0
- data/examples/m17n/win_ansi_charset.rb +54 -0
- data/examples/security/hello_foo.rb +8 -0
- data/examples/table/bill.rb +53 -0
- data/examples/table/cell.rb +12 -0
- data/examples/table/checkerboard.rb +22 -0
- data/examples/table/header.rb +14 -0
- data/examples/table/inline_format_table.rb +12 -0
- data/examples/table/multi_page_table.rb +9 -0
- data/examples/table/simple_table.rb +24 -0
- data/examples/table/subtable.rb +12 -0
- data/examples/table/widths.rb +20 -0
- data/examples/text/alignment.rb +18 -0
- data/examples/text/character_spacing.rb +12 -0
- data/examples/text/dfont.rb +48 -0
- data/examples/text/family_based_styling.rb +24 -0
- data/examples/text/font_calculations.rb +91 -0
- data/examples/text/font_size.rb +33 -0
- data/examples/text/hyphenation.rb +45 -0
- data/examples/text/indent_paragraphs.rb +22 -0
- data/examples/text/inline_format.rb +103 -0
- data/examples/text/kerning.rb +30 -0
- data/examples/text/rotated.rb +98 -0
- data/examples/text/shaped_text_box.rb +31 -0
- data/examples/text/simple_text.rb +17 -0
- data/examples/text/simple_text_ttf.rb +17 -0
- data/examples/text/text_box.rb +88 -0
- data/examples/text/text_box_returning_excess.rb +51 -0
- data/examples/text/text_flow.rb +67 -0
- data/lib/prawn.rb +27 -0
- data/lib/prawn/canvas.rb +119 -0
- data/lib/prawn/chunkable.rb +37 -0
- data/lib/prawn/compatibility.rb +51 -0
- data/lib/prawn/core.rb +85 -0
- data/lib/prawn/core/annotations.rb +61 -0
- data/lib/prawn/core/byte_string.rb +9 -0
- data/lib/prawn/core/chunk.rb +36 -0
- data/lib/prawn/core/destinations.rb +90 -0
- data/lib/prawn/core/document_state.rb +78 -0
- data/lib/prawn/core/literal_string.rb +16 -0
- data/lib/prawn/core/name_tree.rb +165 -0
- data/lib/prawn/core/object_store.rb +236 -0
- data/lib/prawn/core/page.rb +179 -0
- data/lib/prawn/core/pdf_object.rb +108 -0
- data/lib/prawn/core/reference.rb +112 -0
- data/lib/prawn/core/text.rb +140 -0
- data/lib/prawn/core/text/formatted/arranger.rb +266 -0
- data/lib/prawn/core/text/formatted/line_wrap.rb +127 -0
- data/lib/prawn/core/text/formatted/wrap.rb +112 -0
- data/lib/prawn/core/text/line_wrap.rb +209 -0
- data/lib/prawn/core/text/wrap.rb +80 -0
- data/lib/prawn/document.rb +573 -0
- data/lib/prawn/document/bounding_box.rb +425 -0
- data/lib/prawn/document/graphics_state.rb +48 -0
- data/lib/prawn/document/internals.rb +170 -0
- data/lib/prawn/document/page_geometry.rb +136 -0
- data/lib/prawn/document/snapshot.rb +87 -0
- data/lib/prawn/document_builder.rb +51 -0
- data/lib/prawn/document_builder/command.rb +38 -0
- data/lib/prawn/document_builder/constructs.rb +2 -0
- data/lib/prawn/document_builder/constructs/flowing_text_construct.rb +18 -0
- data/lib/prawn/document_builder/constructs/path_construct.rb +9 -0
- data/lib/prawn/document_builder/layout.rb +25 -0
- data/lib/prawn/document_builder/modifications.rb +2 -0
- data/lib/prawn/document_builder/modifications/layout_modification.rb +9 -0
- data/lib/prawn/document_builder/modifications/path_modification.rb +9 -0
- data/lib/prawn/encoding.rb +121 -0
- data/lib/prawn/errors.rb +94 -0
- data/lib/prawn/font.rb +341 -0
- data/lib/prawn/font/afm.rb +225 -0
- data/lib/prawn/font/dfont.rb +42 -0
- data/lib/prawn/font/ttf.rb +350 -0
- data/lib/prawn/graphics.rb +325 -0
- data/lib/prawn/graphics/cap_style.rb +38 -0
- data/lib/prawn/graphics/color.rb +205 -0
- data/lib/prawn/graphics/dash.rb +71 -0
- data/lib/prawn/graphics/join_style.rb +38 -0
- data/lib/prawn/graphics/transformation.rb +156 -0
- data/lib/prawn/graphics/transparency.rb +99 -0
- data/lib/prawn/images.rb +348 -0
- data/lib/prawn/images/jpg.rb +46 -0
- data/lib/prawn/images/png.rb +226 -0
- data/lib/prawn/measurement_extensions.rb +46 -0
- data/lib/prawn/measurements.rb +71 -0
- data/lib/prawn/outline.rb +278 -0
- data/lib/prawn/repeater.rb +129 -0
- data/lib/prawn/security.rb +262 -0
- data/lib/prawn/security/arcfour.rb +51 -0
- data/lib/prawn/stamp.rb +126 -0
- data/lib/prawn/table.rb +421 -0
- data/lib/prawn/table/accessors.rb +180 -0
- data/lib/prawn/table/cell.rb +350 -0
- data/lib/prawn/table/cell/in_table.rb +27 -0
- data/lib/prawn/table/cell/subtable.rb +65 -0
- data/lib/prawn/table/cell/text.rb +125 -0
- data/lib/prawn/text.rb +449 -0
- data/lib/prawn/text/box.rb +392 -0
- data/lib/prawn/text/formatted.rb +4 -0
- data/lib/prawn/text/formatted/box.rb +228 -0
- data/lib/prawn/text/formatted/fragment.rb +181 -0
- data/lib/prawn/text/formatted/parser.rb +213 -0
- data/spec/annotations_spec.rb +90 -0
- data/spec/bounding_box_spec.rb +190 -0
- data/spec/cell_spec.rb +348 -0
- data/spec/destinations_spec.rb +15 -0
- data/spec/document_spec.rb +473 -0
- data/spec/font_spec.rb +324 -0
- data/spec/formatted_text_arranger_spec.rb +426 -0
- data/spec/formatted_text_box_spec.rb +756 -0
- data/spec/formatted_text_fragment_spec.rb +211 -0
- data/spec/graphics_spec.rb +446 -0
- data/spec/images_spec.rb +96 -0
- data/spec/inline_formatted_text_parser_spec.rb +502 -0
- data/spec/jpg_spec.rb +25 -0
- data/spec/line_wrap_spec.rb +341 -0
- data/spec/measurement_units_spec.rb +23 -0
- data/spec/name_tree_spec.rb +112 -0
- data/spec/object_store_spec.rb +160 -0
- data/spec/outline_spec.rb +269 -0
- data/spec/pdf_object_spec.rb +170 -0
- data/spec/png_spec.rb +237 -0
- data/spec/reference_spec.rb +82 -0
- data/spec/repeater_spec.rb +96 -0
- data/spec/security_spec.rb +120 -0
- data/spec/snapshot_spec.rb +138 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/stamp_spec.rb +108 -0
- data/spec/stroke_styles_spec.rb +163 -0
- data/spec/table_spec.rb +598 -0
- data/spec/template_spec.rb +158 -0
- data/spec/text_at_spec.rb +119 -0
- data/spec/text_box_spec.rb +742 -0
- data/spec/text_spacing_spec.rb +75 -0
- data/spec/text_spec.rb +333 -0
- data/spec/text_with_inline_formatting_spec.rb +193 -0
- data/spec/transparency_spec.rb +89 -0
- metadata +331 -0
data/spec/png_spec.rb
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# encoding: ASCII-8BIT
|
|
2
|
+
|
|
3
|
+
# Spec'ing the PNG class. Not complete yet - still needs to check the
|
|
4
|
+
# contents of palette and transparency to ensure they're correct.
|
|
5
|
+
# Need to find files that have these sections first.
|
|
6
|
+
#
|
|
7
|
+
# see http://www.w3.org/TR/PNG/ for a detailed description of the PNG spec,
|
|
8
|
+
# particuarly Table 11.1 for the different color types
|
|
9
|
+
|
|
10
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
11
|
+
|
|
12
|
+
describe "When reading a greyscale PNG file (color type 0)" do
|
|
13
|
+
|
|
14
|
+
before(:each) do
|
|
15
|
+
@filename = "#{Prawn::BASEDIR}/data/images/web-links.png"
|
|
16
|
+
@data_filename = "#{Prawn::BASEDIR}/data/images/web-links.dat"
|
|
17
|
+
@img_data = File.binread(@filename)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should read the attributes from the header chunk correctly" do
|
|
21
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
22
|
+
|
|
23
|
+
png.width.should == 21
|
|
24
|
+
png.height.should == 14
|
|
25
|
+
png.bits.should == 8
|
|
26
|
+
png.color_type.should == 0
|
|
27
|
+
png.compression_method.should == 0
|
|
28
|
+
png.filter_method.should == 0
|
|
29
|
+
png.interlace_method.should == 0
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should read the image data chunk correctly" do
|
|
33
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
34
|
+
data = File.binread(@data_filename)
|
|
35
|
+
png.img_data.should == data
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "When reading a greyscale PNG file with transparency (color type 0)" do
|
|
40
|
+
|
|
41
|
+
before(:each) do
|
|
42
|
+
@filename = "#{Prawn::BASEDIR}/data/images/ruport_type0.png"
|
|
43
|
+
@img_data = File.binread(@filename)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# In a greyscale type 0 PNG image, the tRNS chunk should contain a single value
|
|
47
|
+
# that indicates the color that should be interpreted as transparent.
|
|
48
|
+
#
|
|
49
|
+
# http://www.w3.org/TR/PNG/#11tRNS
|
|
50
|
+
it "should read the tRNS chunk correctly" do
|
|
51
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
52
|
+
png.transparency[:grayscale].should == 255
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "When reading an RGB PNG file (color type 2)" do
|
|
57
|
+
|
|
58
|
+
before(:each) do
|
|
59
|
+
@filename = "#{Prawn::BASEDIR}/data/images/ruport.png"
|
|
60
|
+
@data_filename = "#{Prawn::BASEDIR}/data/images/ruport_data.dat"
|
|
61
|
+
@img_data = File.binread(@filename)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should read the attributes from the header chunk correctly" do
|
|
65
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
66
|
+
|
|
67
|
+
png.width.should == 258
|
|
68
|
+
png.height.should == 105
|
|
69
|
+
png.bits.should == 8
|
|
70
|
+
png.color_type.should == 2
|
|
71
|
+
png.compression_method.should == 0
|
|
72
|
+
png.filter_method.should == 0
|
|
73
|
+
png.interlace_method.should == 0
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should read the image data chunk correctly" do
|
|
77
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
78
|
+
data = File.binread(@data_filename)
|
|
79
|
+
png.img_data.should == data
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe "When reading an RGB PNG file with transparency (color type 2)" do
|
|
84
|
+
|
|
85
|
+
before(:each) do
|
|
86
|
+
@filename = "#{Prawn::BASEDIR}/data/images/arrow2.png"
|
|
87
|
+
@img_data = File.binread(@filename)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# In a RGB type 2 PNG image, the tRNS chunk should contain a single RGB value
|
|
91
|
+
# that indicates the color that should be interpreted as transparent. In this
|
|
92
|
+
# case it's green.
|
|
93
|
+
#
|
|
94
|
+
# http://www.w3.org/TR/PNG/#11tRNS
|
|
95
|
+
it "should read the tRNS chunk correctly" do
|
|
96
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
97
|
+
png.transparency[:rgb].should == [0, 255, 0]
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# TODO: describe "When reading an indexed color PNG file wiih transparency (color type 3)"
|
|
102
|
+
|
|
103
|
+
describe "When reading an indexed color PNG file (color type 3)" do
|
|
104
|
+
|
|
105
|
+
before(:each) do
|
|
106
|
+
@filename = "#{Prawn::BASEDIR}/data/images/rails.png"
|
|
107
|
+
@data_filename = "#{Prawn::BASEDIR}/data/images/rails.dat"
|
|
108
|
+
@img_data = File.binread(@filename)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should read the attributes from the header chunk correctly" do
|
|
112
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
113
|
+
|
|
114
|
+
png.width.should == 50
|
|
115
|
+
png.height.should == 64
|
|
116
|
+
png.bits.should == 8
|
|
117
|
+
png.color_type.should == 3
|
|
118
|
+
png.compression_method.should == 0
|
|
119
|
+
png.filter_method.should == 0
|
|
120
|
+
png.interlace_method.should == 0
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should read the image data chunk correctly" do
|
|
124
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
125
|
+
data = File.binread(@data_filename)
|
|
126
|
+
png.img_data.should == data
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe "When reading a greyscale+alpha PNG file (color type 4)" do
|
|
131
|
+
|
|
132
|
+
before(:each) do
|
|
133
|
+
@filename = "#{Prawn::BASEDIR}/data/images/page_white_text.png"
|
|
134
|
+
@data_filename = "#{Prawn::BASEDIR}/data/images/page_white_text.dat"
|
|
135
|
+
@alpha_data_filename = "#{Prawn::BASEDIR}/data/images/page_white_text.alpha"
|
|
136
|
+
@img_data = File.binread(@filename)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should read the attributes from the header chunk correctly" do
|
|
140
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
141
|
+
|
|
142
|
+
png.width.should == 16
|
|
143
|
+
png.height.should == 16
|
|
144
|
+
png.bits.should == 8
|
|
145
|
+
png.color_type.should == 4
|
|
146
|
+
png.compression_method.should == 0
|
|
147
|
+
png.filter_method.should == 0
|
|
148
|
+
png.interlace_method.should == 0
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "should correctly return the raw image data (with no alpha channel) from the image data chunk" do
|
|
152
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
153
|
+
png.split_alpha_channel!
|
|
154
|
+
data = File.binread(@data_filename)
|
|
155
|
+
png.img_data.should == data
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should correctly extract the alpha channel data from the image data chunk" do
|
|
159
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
160
|
+
png.split_alpha_channel!
|
|
161
|
+
data = File.binread(@alpha_data_filename)
|
|
162
|
+
png.alpha_channel.should == data
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe "When reading an RGB+alpha PNG file (color type 6)" do
|
|
167
|
+
|
|
168
|
+
before(:each) do
|
|
169
|
+
@filename = "#{Prawn::BASEDIR}/data/images/dice.png"
|
|
170
|
+
@data_filename = "#{Prawn::BASEDIR}/data/images/dice.dat"
|
|
171
|
+
@alpha_data_filename = "#{Prawn::BASEDIR}/data/images/dice.alpha"
|
|
172
|
+
@img_data = File.binread(@filename)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should read the attributes from the header chunk correctly" do
|
|
176
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
177
|
+
|
|
178
|
+
png.width.should == 320
|
|
179
|
+
png.height.should == 240
|
|
180
|
+
png.bits.should == 8
|
|
181
|
+
png.color_type.should == 6
|
|
182
|
+
png.compression_method.should == 0
|
|
183
|
+
png.filter_method.should == 0
|
|
184
|
+
png.interlace_method.should == 0
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should correctly return the raw image data (with no alpha channel) from the image data chunk" do
|
|
188
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
189
|
+
png.split_alpha_channel!
|
|
190
|
+
data = File.binread(@data_filename)
|
|
191
|
+
png.img_data.should == data
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should correctly extract the alpha channel data from the image data chunk" do
|
|
195
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
196
|
+
png.split_alpha_channel!
|
|
197
|
+
data = File.binread(@alpha_data_filename)
|
|
198
|
+
png.alpha_channel.should == data
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "When reading a 16bit RGB+alpha PNG file (color type 6)" do
|
|
203
|
+
|
|
204
|
+
before(:each) do
|
|
205
|
+
@filename = "#{Prawn::BASEDIR}/data/images/16bit.png"
|
|
206
|
+
@data_filename = "#{Prawn::BASEDIR}/data/images/16bit.dat"
|
|
207
|
+
# alpha channel truncated to 8-bit
|
|
208
|
+
@alpha_data_filename = "#{Prawn::BASEDIR}/data/images/16bit.alpha"
|
|
209
|
+
@img_data = File.binread(@filename)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "should read the attributes from the header chunk correctly" do
|
|
213
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
214
|
+
|
|
215
|
+
png.width.should == 32
|
|
216
|
+
png.height.should == 32
|
|
217
|
+
png.bits.should == 16
|
|
218
|
+
png.color_type.should == 6
|
|
219
|
+
png.compression_method.should == 0
|
|
220
|
+
png.filter_method.should == 0
|
|
221
|
+
png.interlace_method.should == 0
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should correctly return the raw image data (with no alpha channel) from the image data chunk" do
|
|
225
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
226
|
+
png.split_alpha_channel!
|
|
227
|
+
data = File.binread(@data_filename)
|
|
228
|
+
png.img_data.should == data
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "should correctly extract the alpha channel data from the image data chunk" do
|
|
232
|
+
png = Prawn::Images::PNG.new(@img_data)
|
|
233
|
+
png.split_alpha_channel!
|
|
234
|
+
data = File.binread(@alpha_data_filename)
|
|
235
|
+
png.alpha_channel.should == data
|
|
236
|
+
end
|
|
237
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
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::Core::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::Core::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::Core::Reference(2,[1,"foo"])
|
|
19
|
+
ref.object.should == "2 0 obj\n#{Prawn::Core::PdfObject([1,"foo"])}\nendobj\n"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should automatically open a stream when #<< is used" do
|
|
23
|
+
ref = Prawn::Core::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::Core::Reference(2,{})
|
|
32
|
+
ref << "Hi There " * 20
|
|
33
|
+
|
|
34
|
+
cref = Prawn::Core::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
|
+
|
|
43
|
+
it "should copy the data and stream from another ref on #replace" do
|
|
44
|
+
from = Prawn::Core::Reference(3, {:foo => 'bar'})
|
|
45
|
+
from << "has a stream too"
|
|
46
|
+
|
|
47
|
+
to = Prawn::Core::Reference(4, {:foo => 'baz'})
|
|
48
|
+
to.replace from
|
|
49
|
+
|
|
50
|
+
# should preserve identifier but copy data and stream
|
|
51
|
+
to.identifier.should == 4
|
|
52
|
+
to.data.should == from.data
|
|
53
|
+
to.stream.should == from.stream
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should copy a compressed stream from a compressed ref on #replace" do
|
|
57
|
+
from = Prawn::Core::Reference(5, {:foo => 'bar'})
|
|
58
|
+
from << "has a stream too " * 20
|
|
59
|
+
from.compress_stream
|
|
60
|
+
|
|
61
|
+
to = Prawn::Core::Reference(6, {:foo => 'baz'})
|
|
62
|
+
to.replace from
|
|
63
|
+
|
|
64
|
+
to.identifier.should == 6
|
|
65
|
+
to.data.should == from.data
|
|
66
|
+
to.stream.should == from.stream
|
|
67
|
+
to.compressed?.should == true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "generated via Prawn::Document" do
|
|
71
|
+
it "should return a proper reference on ref!" do
|
|
72
|
+
pdf = Prawn::Document.new
|
|
73
|
+
pdf.ref!({}).is_a?(Prawn::Core::Reference).should == true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should return an identifier on ref" do
|
|
77
|
+
pdf = Prawn::Document.new
|
|
78
|
+
r = pdf.ref({})
|
|
79
|
+
r.is_a?(Integer).should == true
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Repeaters" do
|
|
4
|
+
|
|
5
|
+
it "creates a stamp and increments Prawn::Repeater.count on initialize" do
|
|
6
|
+
orig_count = Prawn::Repeater.count
|
|
7
|
+
|
|
8
|
+
doc = sample_document
|
|
9
|
+
doc.expects(:create_stamp).with("prawn_repeater(#{orig_count})")
|
|
10
|
+
|
|
11
|
+
r = repeater(doc, :all) { :do_nothing }
|
|
12
|
+
|
|
13
|
+
assert_equal orig_count + 1, Prawn::Repeater.count
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "must provide an :all filter" do
|
|
17
|
+
doc = sample_document
|
|
18
|
+
r = repeater(doc, :all) { :do_nothing }
|
|
19
|
+
|
|
20
|
+
assert (1..doc.page_count).all? { |i| r.match?(i) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "must provide an :odd filter" do
|
|
24
|
+
doc = sample_document
|
|
25
|
+
r = repeater(doc, :odd) { :do_nothing }
|
|
26
|
+
|
|
27
|
+
odd, even = (1..doc.page_count).partition { |e| e % 2 == 1 }
|
|
28
|
+
|
|
29
|
+
assert odd.all? { |i| r.match?(i) }
|
|
30
|
+
assert ! even.any? { |i| r.match?(i) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "must be able to filter by an array of page numbers" do
|
|
34
|
+
doc = sample_document
|
|
35
|
+
r = repeater(doc, [1,2,7]) { :do_nothing }
|
|
36
|
+
|
|
37
|
+
assert_equal [1,2,7], (1..10).select { |i| r.match?(i) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "must be able to filter by a range of page numbers" do
|
|
41
|
+
doc = sample_document
|
|
42
|
+
r = repeater(doc, 2..4) { :do_nothing }
|
|
43
|
+
|
|
44
|
+
assert_equal [2,3,4], (1..10).select { |i| r.match?(i) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "must be able to filter by an arbitrary proc" do
|
|
48
|
+
doc = sample_document
|
|
49
|
+
r = repeater(doc, lambda { |x| x == 1 or x % 3 == 0 })
|
|
50
|
+
|
|
51
|
+
assert_equal [1,3,6,9], (1..10).select { |i| r.match?(i) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "must try to run a stamp if the page number matches" do
|
|
55
|
+
doc = sample_document
|
|
56
|
+
doc.expects(:stamp)
|
|
57
|
+
|
|
58
|
+
repeater(doc, :odd).run(3)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "must not try to run a stamp if the page number matches" do
|
|
62
|
+
doc = sample_document
|
|
63
|
+
|
|
64
|
+
doc.expects(:stamp).never
|
|
65
|
+
repeater(doc, :odd).run(2)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "must not try to run a stamp if dynamic is selected" do
|
|
69
|
+
doc = sample_document
|
|
70
|
+
|
|
71
|
+
doc.expects(:stamp).never
|
|
72
|
+
(1..10).each { |p| repeater(doc, :all, true){:do_nothing}.run(p) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "must render the block in context of page when dynamic is selected" do
|
|
76
|
+
doc = sample_document
|
|
77
|
+
|
|
78
|
+
doc.repeat(:all, :dynamic => true) do
|
|
79
|
+
draw_text page_number, :at => [500, 0]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
text = PDF::Inspector::Text.analyze(doc.render)
|
|
83
|
+
assert_equal (1..10).to_a.map{|p| p.to_s}, text.strings
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def sample_document
|
|
87
|
+
doc = Prawn::Document.new(:skip_page_creation => true)
|
|
88
|
+
10.times { |e| doc.start_new_page }
|
|
89
|
+
doc
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def repeater(*args, &b)
|
|
93
|
+
Prawn::Repeater.new(*args,&b)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "tempfile"
|
|
3
|
+
|
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
5
|
+
|
|
6
|
+
describe "Document encryption" do
|
|
7
|
+
|
|
8
|
+
describe "Password padding" do
|
|
9
|
+
|
|
10
|
+
include Prawn::Document::Security
|
|
11
|
+
|
|
12
|
+
it "should truncate long passwords" do
|
|
13
|
+
pw = "Long long string" * 30
|
|
14
|
+
padded = pad_password(pw)
|
|
15
|
+
padded.length.should == 32
|
|
16
|
+
padded.should == pw[0, 32]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should pad short passwords" do
|
|
20
|
+
pw = "abcd"
|
|
21
|
+
padded = pad_password(pw)
|
|
22
|
+
padded.length.should == 32
|
|
23
|
+
padded.should == pw + Prawn::Document::Security::PasswordPadding[0, 28]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should fully pad null passwords" do
|
|
27
|
+
pw = ""
|
|
28
|
+
padded = pad_password(pw)
|
|
29
|
+
padded.length.should == 32
|
|
30
|
+
padded.should == Prawn::Document::Security::PasswordPadding
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "Setting permissions" do
|
|
36
|
+
|
|
37
|
+
def doc_with_permissions(permissions)
|
|
38
|
+
pdf = Prawn::Document.new
|
|
39
|
+
|
|
40
|
+
class << pdf
|
|
41
|
+
# Make things easier to test
|
|
42
|
+
public :permissions_value
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
pdf.encrypt_document(:permissions => permissions)
|
|
46
|
+
pdf
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should default to full permissions" do
|
|
50
|
+
doc_with_permissions({}).permissions_value.should == 0xFFFFFFFF
|
|
51
|
+
doc_with_permissions(:print_document => true,
|
|
52
|
+
:modify_contents => true,
|
|
53
|
+
:copy_contents => true,
|
|
54
|
+
:modify_annotations => true).permissions_value.
|
|
55
|
+
should == 0xFFFFFFFF
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should clear the appropriate bits for each permission flag" do
|
|
59
|
+
doc_with_permissions(:print_document => false).permissions_value.
|
|
60
|
+
should == 0b1111_1111_1111_1111_1111_1111_1111_1011
|
|
61
|
+
doc_with_permissions(:modify_contents => false).permissions_value.
|
|
62
|
+
should == 0b1111_1111_1111_1111_1111_1111_1111_0111
|
|
63
|
+
doc_with_permissions(:copy_contents => false).permissions_value.
|
|
64
|
+
should == 0b1111_1111_1111_1111_1111_1111_1110_1111
|
|
65
|
+
doc_with_permissions(:modify_annotations => false).permissions_value.
|
|
66
|
+
should == 0b1111_1111_1111_1111_1111_1111_1101_1111
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe "Encryption keys" do
|
|
72
|
+
# Since PDF::Reader doesn't read encrypted PDF files, we just take the
|
|
73
|
+
# roundabout method of verifying each step of the encryption. This works
|
|
74
|
+
# fine because the encryption method is deterministic.
|
|
75
|
+
|
|
76
|
+
before(:each) do
|
|
77
|
+
@pdf = Prawn::Document.new
|
|
78
|
+
class << @pdf
|
|
79
|
+
public :owner_password_hash, :user_password_hash, :user_encryption_key
|
|
80
|
+
end
|
|
81
|
+
@pdf.encrypt_document :user_password => 'foo', :owner_password => 'bar',
|
|
82
|
+
:permissions => { :print_document => false }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should calculate the correct owner hash" do
|
|
86
|
+
@pdf.owner_password_hash.unpack("H*").first.should.match(/^61CA855012/i)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should calculate the correct user hash" do
|
|
90
|
+
@pdf.user_password_hash.unpack("H*").first.should =~ /^6BC8C51031/i
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should calculate the correct user_encryption_key" do
|
|
94
|
+
@pdf.user_encryption_key.unpack("H*").first.upcase.should == "B100AB6429"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "EncryptedPdfObject" do
|
|
101
|
+
|
|
102
|
+
it "should delegate to PdfObject for simple types" do
|
|
103
|
+
Prawn::Core::EncryptedPdfObject(true, nil, nil, nil).should == "true"
|
|
104
|
+
Prawn::Core::EncryptedPdfObject(42, nil, nil, nil).should == "42"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should encrypt strings properly" do
|
|
108
|
+
Prawn::Core::EncryptedPdfObject("foo", "12345", 123, 0).should == "<4ad6e3>"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should properly handle compound types" do
|
|
112
|
+
Prawn::Core::EncryptedPdfObject({:Bar => "foo"}, "12345", 123, 0).should ==
|
|
113
|
+
"<< /Bar <4ad6e3>\n>>"
|
|
114
|
+
Prawn::Core::EncryptedPdfObject(["foo", "bar"], "12345", 123, 0).should ==
|
|
115
|
+
"[<4ad6e3> <4ed8fe>]"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|