prawn 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -9
- data/Rakefile +12 -22
- data/lib/prawn.rb +29 -48
- data/lib/prawn/document.rb +148 -123
- data/lib/prawn/document/bounding_box.rb +33 -26
- data/lib/prawn/document/column_box.rb +5 -7
- data/lib/prawn/document/internals.rb +6 -6
- data/lib/prawn/document/span.rb +20 -17
- data/lib/prawn/encoding.rb +65 -67
- data/lib/prawn/errors.rb +10 -7
- data/lib/prawn/font.rb +78 -62
- data/lib/prawn/font/afm.rb +93 -66
- data/lib/prawn/font/dfont.rb +2 -10
- data/lib/prawn/font/ttc.rb +34 -0
- data/lib/prawn/font/ttf.rb +73 -65
- data/lib/prawn/font_metric_cache.rb +9 -8
- data/lib/prawn/graphics.rb +110 -70
- data/lib/prawn/graphics/blend_mode.rb +7 -8
- data/lib/prawn/graphics/cap_style.rb +2 -4
- data/lib/prawn/graphics/color.rb +23 -26
- data/lib/prawn/graphics/dash.rb +22 -12
- data/lib/prawn/graphics/join_style.rb +8 -4
- data/lib/prawn/graphics/patterns.rb +185 -96
- data/lib/prawn/graphics/transformation.rb +11 -9
- data/lib/prawn/graphics/transparency.rb +15 -13
- data/lib/prawn/grid.rb +20 -20
- data/lib/prawn/image_handler.rb +4 -6
- data/lib/prawn/images.rb +22 -15
- data/lib/prawn/images/image.rb +0 -1
- data/lib/prawn/images/jpg.rb +26 -22
- data/lib/prawn/images/png.rb +60 -57
- data/lib/prawn/measurement_extensions.rb +8 -9
- data/lib/prawn/measurements.rb +14 -15
- data/lib/prawn/outline.rb +96 -78
- data/lib/prawn/repeater.rb +12 -10
- data/lib/prawn/security.rb +66 -48
- data/lib/prawn/security/arcfour.rb +1 -3
- data/lib/prawn/soft_mask.rb +23 -25
- data/lib/prawn/stamp.rb +16 -12
- data/lib/prawn/text.rb +59 -45
- data/lib/prawn/text/box.rb +9 -8
- data/lib/prawn/text/formatted.rb +4 -6
- data/lib/prawn/text/formatted/arranger.rb +51 -30
- data/lib/prawn/text/formatted/box.rb +112 -88
- data/lib/prawn/text/formatted/fragment.rb +10 -15
- data/lib/prawn/text/formatted/line_wrap.rb +118 -61
- data/lib/prawn/text/formatted/parser.rb +134 -110
- data/lib/prawn/text/formatted/wrap.rb +42 -32
- data/lib/prawn/transformation_stack.rb +3 -4
- data/lib/prawn/utilities.rb +6 -21
- data/lib/prawn/version.rb +1 -3
- data/lib/prawn/view.rb +4 -2
- data/manual/basic_concepts/adding_pages.rb +4 -7
- data/manual/basic_concepts/basic_concepts.rb +29 -22
- data/manual/basic_concepts/creation.rb +8 -11
- data/manual/basic_concepts/cursor.rb +2 -5
- data/manual/basic_concepts/measurement.rb +3 -6
- data/manual/basic_concepts/origin.rb +3 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +9 -12
- data/manual/basic_concepts/view.rb +20 -16
- data/manual/bounding_box/bounding_box.rb +27 -24
- data/manual/bounding_box/bounds.rb +9 -12
- data/manual/bounding_box/canvas.rb +2 -5
- data/manual/bounding_box/creation.rb +4 -7
- data/manual/bounding_box/indentation.rb +12 -15
- data/manual/bounding_box/nesting.rb +22 -17
- data/manual/bounding_box/russian_boxes.rb +8 -9
- data/manual/bounding_box/stretchy.rb +10 -13
- data/manual/contents.rb +26 -22
- data/manual/cover.rb +22 -20
- data/manual/document_and_page_options/background.rb +9 -13
- data/manual/document_and_page_options/document_and_page_options.rb +23 -20
- data/manual/document_and_page_options/metadata.rb +16 -16
- data/manual/document_and_page_options/page_margins.rb +16 -20
- data/manual/document_and_page_options/page_size.rb +11 -12
- data/manual/document_and_page_options/print_scaling.rb +15 -15
- data/manual/example_helper.rb +2 -4
- data/manual/graphics/blend_mode.rb +10 -9
- data/manual/graphics/circle_and_ellipse.rb +2 -5
- data/manual/graphics/color.rb +5 -9
- data/manual/graphics/common_lines.rb +5 -8
- data/manual/graphics/fill_and_stroke.rb +2 -5
- data/manual/graphics/fill_rules.rb +7 -10
- data/manual/graphics/gradients.rb +25 -21
- data/manual/graphics/graphics.rb +49 -43
- data/manual/graphics/helper.rb +10 -9
- data/manual/graphics/line_width.rb +5 -7
- data/manual/graphics/lines_and_curves.rb +5 -8
- data/manual/graphics/polygon.rb +4 -8
- data/manual/graphics/rectangle.rb +2 -5
- data/manual/graphics/rotate.rb +4 -7
- data/manual/graphics/scale.rb +12 -15
- data/manual/graphics/soft_masks.rb +1 -4
- data/manual/graphics/stroke_cap.rb +3 -6
- data/manual/graphics/stroke_dash.rb +9 -12
- data/manual/graphics/stroke_join.rb +2 -5
- data/manual/graphics/translate.rb +7 -10
- data/manual/graphics/transparency.rb +5 -8
- data/manual/how_to_read_this_manual.rb +4 -6
- data/manual/images/absolute_position.rb +4 -7
- data/manual/images/fit.rb +5 -8
- data/manual/images/horizontal.rb +6 -9
- data/manual/images/images.rb +25 -23
- data/manual/images/plain_image.rb +3 -6
- data/manual/images/scale.rb +7 -10
- data/manual/images/vertical.rb +10 -13
- data/manual/images/width_and_height.rb +8 -11
- data/manual/layout/boxes.rb +3 -6
- data/manual/layout/content.rb +5 -8
- data/manual/layout/layout.rb +16 -16
- data/manual/layout/simple_grid.rb +4 -7
- data/manual/outline/add_subsection_to.rb +18 -21
- data/manual/outline/insert_section_after.rb +13 -16
- data/manual/outline/outline.rb +19 -17
- data/manual/outline/sections_and_pages.rb +15 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +19 -17
- data/manual/repeatable_content/page_numbering.rb +15 -16
- data/manual/repeatable_content/repeatable_content.rb +23 -19
- data/manual/repeatable_content/repeater.rb +12 -15
- data/manual/repeatable_content/stamp.rb +12 -15
- data/manual/security/encryption.rb +7 -10
- data/manual/security/permissions.rb +17 -14
- data/manual/security/security.rb +17 -16
- data/manual/table.rb +2 -4
- data/manual/text/alignment.rb +14 -17
- data/manual/text/color.rb +10 -11
- data/manual/text/column_box.rb +5 -8
- data/manual/text/fallback_fonts.rb +23 -21
- data/manual/text/font.rb +9 -12
- data/manual/text/font_size.rb +11 -14
- data/manual/text/font_style.rb +4 -7
- data/manual/text/formatted_callbacks.rb +23 -21
- data/manual/text/formatted_text.rb +31 -25
- data/manual/text/free_flowing_text.rb +18 -21
- data/manual/text/inline.rb +16 -19
- data/manual/text/kerning_and_character_spacing.rb +12 -15
- data/manual/text/leading.rb +5 -8
- data/manual/text/line_wrapping.rb +33 -17
- data/manual/text/paragraph_indentation.rb +11 -14
- data/manual/text/positioned_text.rb +13 -16
- data/manual/text/registering_families.rb +16 -19
- data/manual/text/rendering_and_color.rb +7 -10
- data/manual/text/right_to_left_text.rb +24 -19
- data/manual/text/rotation.rb +26 -23
- data/manual/text/single_usage.rb +6 -9
- data/manual/text/text.rb +56 -52
- data/manual/text/text_box_excess.rb +18 -17
- data/manual/text/text_box_extensions.rb +16 -15
- data/manual/text/text_box_overflow.rb +15 -18
- data/manual/text/utf8.rb +9 -12
- data/manual/text/win_ansi_charset.rb +18 -19
- data/prawn.gemspec +37 -27
- data/spec/extensions/encoding_helpers.rb +0 -2
- data/spec/manual_spec.rb +33 -0
- data/spec/prawn/document/bounding_box_spec.rb +546 -0
- data/spec/prawn/document/column_box_spec.rb +73 -0
- data/spec/prawn/document/security_spec.rb +173 -0
- data/spec/prawn/document_annotations_spec.rb +74 -0
- data/spec/prawn/document_destinations_spec.rb +13 -0
- data/spec/prawn/document_grid_spec.rb +96 -0
- data/spec/prawn/document_reference_spec.rb +25 -0
- data/spec/prawn/document_span_spec.rb +34 -0
- data/spec/prawn/document_spec.rb +751 -0
- data/spec/prawn/font_metric_cache_spec.rb +52 -0
- data/spec/prawn/font_spec.rb +513 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +61 -0
- data/spec/prawn/graphics/transparency_spec.rb +79 -0
- data/spec/prawn/graphics_spec.rb +817 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +227 -0
- data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +13 -15
- data/spec/prawn/images/jpg_spec.rb +18 -0
- data/spec/prawn/images/png_spec.rb +281 -0
- data/spec/prawn/images_spec.rb +170 -0
- data/spec/prawn/measurements_extensions_spec.rb +22 -0
- data/spec/prawn/outline_spec.rb +408 -0
- data/spec/prawn/repeater_spec.rb +163 -0
- data/spec/prawn/soft_mask_spec.rb +72 -0
- data/spec/prawn/stamp_spec.rb +168 -0
- data/spec/prawn/text/box_spec.rb +1113 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +464 -0
- data/spec/prawn/text/formatted/box_spec.rb +825 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +341 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +491 -0
- data/spec/prawn/text/formatted/parser_spec.rb +667 -0
- data/spec/prawn/text_draw_text_spec.rb +147 -0
- data/spec/prawn/text_rendering_mode_spec.rb +42 -0
- data/spec/prawn/text_spacing_spec.rb +93 -0
- data/spec/prawn/text_spec.rb +601 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +33 -0
- data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +21 -20
- data/spec/prawn/view_spec.rb +45 -0
- data/spec/spec_helper.rb +16 -16
- metadata +96 -151
- metadata.gz.sig +1 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +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/blend_modes_bottom_layer.jpg +0 -0
- data/data/images/blend_modes_top_layer.jpg +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +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/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/indexed_transparency.png +0 -0
- data/data/images/indexed_transparency_alpha.dat +0 -0
- data/data/images/indexed_transparency_color.dat +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/prawn.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 +0 -1
- 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/form.pdf +1 -819
- data/data/pdfs/hexagon.pdf +0 -61
- data/data/pdfs/indirect_reference.pdf +0 -86
- data/data/pdfs/multipage_template.pdf +0 -127
- data/data/pdfs/nested_pages.pdf +0 -118
- data/data/pdfs/page_without_mediabox.pdf +0 -193
- data/data/pdfs/resources_as_indirect_object.pdf +0 -83
- data/data/pdfs/two_hexagons.pdf +0 -90
- data/data/pdfs/version_1_6.pdf +0 -61
- data/data/shift_jis_text.txt +0 -1
- data/spec/acceptance/png_spec.rb +0 -35
- data/spec/annotations_spec.rb +0 -67
- data/spec/blend_mode_spec.rb +0 -71
- data/spec/bounding_box_spec.rb +0 -501
- data/spec/column_box_spec.rb +0 -59
- data/spec/destinations_spec.rb +0 -13
- data/spec/document_spec.rb +0 -738
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -475
- data/spec/formatted_text_arranger_spec.rb +0 -452
- data/spec/formatted_text_box_spec.rb +0 -716
- data/spec/formatted_text_fragment_spec.rb +0 -299
- data/spec/graphics_spec.rb +0 -705
- data/spec/grid_spec.rb +0 -95
- data/spec/images_spec.rb +0 -167
- data/spec/inline_formatted_text_parser_spec.rb +0 -568
- data/spec/jpg_spec.rb +0 -23
- data/spec/line_wrap_spec.rb +0 -366
- data/spec/measurement_units_spec.rb +0 -22
- data/spec/outline_spec.rb +0 -409
- data/spec/png_spec.rb +0 -257
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -154
- data/spec/security_spec.rb +0 -151
- data/spec/soft_mask_spec.rb +0 -78
- data/spec/span_spec.rb +0 -43
- data/spec/stamp_spec.rb +0 -179
- data/spec/stroke_styles_spec.rb +0 -208
- data/spec/text_at_spec.rb +0 -142
- data/spec/text_box_spec.rb +0 -1042
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -543
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
- data/spec/view_spec.rb +0 -42
data/lib/prawn/security.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
1
|
# encryption.rb : Implements encrypted PDF and access permissions.
|
4
2
|
#
|
5
3
|
# Copyright August 2008, Brad Ediger. All Rights Reserved.
|
@@ -89,13 +87,13 @@ module Prawn
|
|
89
87
|
#
|
90
88
|
def encrypt_document(options = {})
|
91
89
|
Prawn.verify_options [:user_password, :owner_password, :permissions],
|
92
|
-
|
93
|
-
@user_password = options.delete(:user_password) ||
|
90
|
+
options
|
91
|
+
@user_password = options.delete(:user_password) || ''
|
94
92
|
|
95
93
|
@owner_password = options.delete(:owner_password) || @user_password
|
96
94
|
if @owner_password == :random
|
97
95
|
# Generate a completely ridiculous password
|
98
|
-
@owner_password = (1..32).map{ rand(256) }.pack(
|
96
|
+
@owner_password = (1..32).map { rand(256) }.pack('c*')
|
99
97
|
end
|
100
98
|
|
101
99
|
self.permissions = options.delete(:permissions) || {}
|
@@ -124,28 +122,35 @@ module Prawn
|
|
124
122
|
|
125
123
|
# Provides the values for the trailer encryption dictionary.
|
126
124
|
def encryption_dictionary
|
127
|
-
{
|
128
|
-
:
|
129
|
-
:
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
125
|
+
{
|
126
|
+
Filter: :Standard, # default PDF security handler
|
127
|
+
V: 1, # "Algorithm 3.1", PDF reference 1.3
|
128
|
+
R: 2, # Revision 2 of the algorithm
|
129
|
+
O: PDF::Core::ByteString.new(owner_password_hash),
|
130
|
+
U: PDF::Core::ByteString.new(user_password_hash),
|
131
|
+
P: permissions_value
|
132
|
+
}
|
133
133
|
end
|
134
134
|
|
135
135
|
# Flags in the permissions word, numbered as LSB = 1
|
136
|
-
PermissionsBits = {
|
137
|
-
|
138
|
-
|
139
|
-
|
136
|
+
PermissionsBits = {
|
137
|
+
print_document: 3,
|
138
|
+
modify_contents: 4,
|
139
|
+
copy_contents: 5,
|
140
|
+
modify_annotations: 6
|
141
|
+
}.freeze
|
140
142
|
|
141
|
-
|
143
|
+
FULL_PERMISSIONS = 0b1111_1111_1111_1111_1111_1111_1111_1111
|
142
144
|
|
143
145
|
def permissions=(perms = {})
|
144
|
-
@permissions ||=
|
146
|
+
@permissions ||= FULL_PERMISSIONS
|
145
147
|
perms.each do |key, value|
|
146
148
|
unless PermissionsBits[key]
|
147
|
-
|
148
|
-
|
149
|
+
raise(
|
150
|
+
ArgumentError,
|
151
|
+
"Unknown permission :#{key}. Valid options: " +
|
152
|
+
PermissionsBits.keys.map(&:inspect).join(', ')
|
153
|
+
)
|
149
154
|
end
|
150
155
|
|
151
156
|
# 0-based bit number, from LSB
|
@@ -160,12 +165,12 @@ module Prawn
|
|
160
165
|
end
|
161
166
|
|
162
167
|
def permissions_value
|
163
|
-
@permissions ||
|
168
|
+
@permissions || FULL_PERMISSIONS
|
164
169
|
end
|
165
170
|
|
166
171
|
PasswordPadding =
|
167
|
-
|
168
|
-
|
172
|
+
'28BF4E5E4E758A4164004E56FFFA01082E2E00B6D0683E802F0CA9FE6453697A'
|
173
|
+
.scan(/../).map { |x| x.to_i(16) }.pack('c*')
|
169
174
|
|
170
175
|
# Pads or truncates a password to 32 bytes as per Alg 3.2.
|
171
176
|
def pad_password(password)
|
@@ -178,7 +183,7 @@ module Prawn
|
|
178
183
|
md5 = Digest::MD5.new
|
179
184
|
md5 << pad_password(@user_password)
|
180
185
|
md5 << owner_password_hash
|
181
|
-
md5 << [permissions_value].pack(
|
186
|
+
md5 << [permissions_value].pack('V')
|
182
187
|
md5.digest[0, 5]
|
183
188
|
end
|
184
189
|
end
|
@@ -204,46 +209,53 @@ module PDF
|
|
204
209
|
module Core
|
205
210
|
module_function
|
206
211
|
|
207
|
-
# Like
|
212
|
+
# Like pdf_object, but returns an encrypted result if required.
|
208
213
|
# For direct objects, requires the object identifier and generation number
|
209
214
|
# from the indirect object referencing obj.
|
210
215
|
#
|
211
216
|
# @private
|
212
|
-
def
|
217
|
+
def encrypted_pdf_object(obj, key, id, gen, in_content_stream = false)
|
213
218
|
case obj
|
214
219
|
when Array
|
215
|
-
|
216
|
-
|
217
|
-
|
220
|
+
'[' << obj.map do |e|
|
221
|
+
encrypted_pdf_object(e, key, id, gen, in_content_stream)
|
222
|
+
end.join(' ') << ']'
|
218
223
|
when LiteralString
|
219
|
-
obj = ByteString.new(
|
224
|
+
obj = ByteString.new(
|
225
|
+
Prawn::Document::Security.encrypt_string(obj, key, id, gen)
|
226
|
+
).gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
|
220
227
|
"(#{obj})"
|
221
228
|
when Time
|
222
|
-
obj = obj.strftime(
|
223
|
-
obj = ByteString.new(
|
229
|
+
obj = obj.strftime('D:%Y%m%d%H%M%S%z').chop.chop + "'00'"
|
230
|
+
obj = ByteString.new(
|
231
|
+
Prawn::Document::Security.encrypt_string(obj, key, id, gen)
|
232
|
+
).gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
|
224
233
|
"(#{obj})"
|
225
234
|
when String
|
226
|
-
|
235
|
+
pdf_object(
|
227
236
|
ByteString.new(
|
228
|
-
Prawn::Document::Security.encrypt_string(obj, key, id, gen)
|
229
|
-
|
237
|
+
Prawn::Document::Security.encrypt_string(obj, key, id, gen)
|
238
|
+
),
|
239
|
+
in_content_stream
|
240
|
+
)
|
230
241
|
when ::Hash
|
231
|
-
output =
|
242
|
+
output = '<< '
|
232
243
|
obj.each do |k, v|
|
233
|
-
unless String
|
234
|
-
|
235
|
-
|
244
|
+
unless k.is_a?(String) || k.is_a?(Symbol)
|
245
|
+
raise PDF::Core::Errors::FailedObjectConversion,
|
246
|
+
'A PDF Dictionary must be keyed by names'
|
236
247
|
end
|
237
|
-
output <<
|
248
|
+
output << pdf_object(k.to_sym, in_content_stream) << ' ' <<
|
249
|
+
encrypted_pdf_object(v, key, id, gen, in_content_stream) << "\n"
|
238
250
|
end
|
239
|
-
output <<
|
251
|
+
output << '>>'
|
240
252
|
when NameTree::Value
|
241
|
-
|
242
|
-
|
253
|
+
pdf_object(obj.name) + ' ' +
|
254
|
+
encrypted_pdf_object(obj.value, key, id, gen, in_content_stream)
|
243
255
|
when PDF::Core::OutlineRoot, PDF::Core::OutlineItem
|
244
|
-
|
245
|
-
else # delegate back to
|
246
|
-
|
256
|
+
encrypted_pdf_object(obj.to_hash, key, id, gen, in_content_stream)
|
257
|
+
else # delegate back to pdf_object
|
258
|
+
pdf_object(obj, in_content_stream)
|
247
259
|
end
|
248
260
|
end
|
249
261
|
|
@@ -251,7 +263,10 @@ module PDF
|
|
251
263
|
class Stream
|
252
264
|
def encrypted_object(key, id, gen)
|
253
265
|
if filtered_stream
|
254
|
-
"stream\n
|
266
|
+
"stream\n" +
|
267
|
+
Prawn::Document::Security.encrypt_string(
|
268
|
+
filtered_stream, key, id, gen
|
269
|
+
) + "\nendstream\n"
|
255
270
|
else
|
256
271
|
''
|
257
272
|
end
|
@@ -267,9 +282,12 @@ module PDF
|
|
267
282
|
|
268
283
|
output = "#{@identifier} #{gen} obj\n"
|
269
284
|
if @stream.empty?
|
270
|
-
output <<
|
285
|
+
output <<
|
286
|
+
PDF::Core.encrypted_pdf_object(data, key, @identifier, gen) << "\n"
|
271
287
|
else
|
272
|
-
output << PDF::Core
|
288
|
+
output << PDF::Core.encrypted_pdf_object(
|
289
|
+
data.merge(@stream.data), key, @identifier, gen
|
290
|
+
) << "\n" <<
|
273
291
|
@stream.encrypted_object(key, @identifier, gen)
|
274
292
|
end
|
275
293
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# Implementation of the "ARCFOUR" algorithm ("alleged RC4 (tm)"). Implemented
|
4
2
|
# as described at:
|
5
3
|
# http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt
|
@@ -39,7 +37,7 @@ class Arcfour
|
|
39
37
|
end
|
40
38
|
|
41
39
|
def encrypt(string)
|
42
|
-
string.unpack('c*').map{ |byte| byte ^ key_byte }.pack('c*')
|
40
|
+
string.unpack('c*').map { |byte| byte ^ key_byte }.pack('c*')
|
43
41
|
end
|
44
42
|
|
45
43
|
private
|
data/lib/prawn/soft_mask.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
1
|
# soft_mask.rb : Implements soft-masking
|
4
2
|
#
|
5
3
|
# Copyright September 2012, Alexander Mankuta. All Rights Reserved.
|
@@ -31,44 +29,44 @@ module Prawn
|
|
31
29
|
renderer.min_version(1.4)
|
32
30
|
|
33
31
|
group_attrs = ref!(
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
32
|
+
Type: :Group,
|
33
|
+
S: :Transparency,
|
34
|
+
CS: :DeviceRGB,
|
35
|
+
I: false,
|
36
|
+
K: false
|
39
37
|
)
|
40
38
|
|
41
39
|
group = ref!(
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
40
|
+
Type: :XObject,
|
41
|
+
Subtype: :Form,
|
42
|
+
BBox: state.page.dimensions,
|
43
|
+
Group: group_attrs
|
46
44
|
)
|
47
45
|
|
48
46
|
state.page.stamp_stream(group, &block)
|
49
47
|
|
50
48
|
mask = ref!(
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
49
|
+
Type: :Mask,
|
50
|
+
S: :Luminosity,
|
51
|
+
G: group
|
54
52
|
)
|
55
53
|
|
56
54
|
g_state = ref!(
|
57
|
-
:
|
58
|
-
:
|
55
|
+
Type: :ExtGState,
|
56
|
+
SMask: mask,
|
59
57
|
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
58
|
+
AIS: false,
|
59
|
+
BM: :Normal,
|
60
|
+
OP: false,
|
61
|
+
op: false,
|
62
|
+
OPM: 1,
|
63
|
+
SA: true
|
66
64
|
)
|
67
65
|
|
68
66
|
registry_key = {
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
67
|
+
bbox: state.page.dimensions,
|
68
|
+
mask: [group.stream.filters.normalized, group.stream.filtered_stream],
|
69
|
+
page: state.page_count
|
72
70
|
}.hash
|
73
71
|
|
74
72
|
if soft_mask_registry[registry_key]
|
data/lib/prawn/stamp.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
1
|
# stamp.rb : Implements a repeatable stamp
|
4
2
|
#
|
5
3
|
# Copyright October 2009, Daniel Nelson. All Rights Reserved.
|
@@ -92,9 +90,9 @@ module Prawn
|
|
92
90
|
end
|
93
91
|
|
94
92
|
def stamp_dictionary(name)
|
95
|
-
|
93
|
+
raise Prawn::Errors::InvalidName if name.empty?
|
96
94
|
if stamp_dictionary_registry[name].nil?
|
97
|
-
|
95
|
+
raise Prawn::Errors::UndefinedObjectName
|
98
96
|
end
|
99
97
|
|
100
98
|
dict = stamp_dictionary_registry[name]
|
@@ -105,20 +103,26 @@ module Prawn
|
|
105
103
|
end
|
106
104
|
|
107
105
|
def create_stamp_dictionary(name)
|
108
|
-
|
109
|
-
|
106
|
+
raise Prawn::Errors::InvalidName if name.empty?
|
107
|
+
raise Prawn::Errors::NameTaken unless stamp_dictionary_registry[name].nil?
|
110
108
|
# BBox origin is the lower left margin of the page, so we need
|
111
109
|
# it to be the full dimension of the page, or else things that
|
112
110
|
# should appear near the top or right margin are invisible
|
113
|
-
dictionary = ref!(
|
114
|
-
|
115
|
-
|
116
|
-
|
111
|
+
dictionary = ref!(
|
112
|
+
Type: :XObject,
|
113
|
+
Subtype: :Form,
|
114
|
+
BBox: [
|
115
|
+
0, 0,
|
116
|
+
state.page.dimensions[2], state.page.dimensions[3]
|
117
|
+
]
|
118
|
+
)
|
117
119
|
|
118
120
|
dictionary_name = "Stamp#{next_stamp_dictionary_id}"
|
119
121
|
|
120
|
-
stamp_dictionary_registry[name] = {
|
121
|
-
|
122
|
+
stamp_dictionary_registry[name] = {
|
123
|
+
stamp_dictionary_name: dictionary_name,
|
124
|
+
stamp_dictionary: dictionary
|
125
|
+
}
|
122
126
|
dictionary
|
123
127
|
end
|
124
128
|
|
data/lib/prawn/text.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# text.rb : Implements PDF text primitives
|
4
2
|
#
|
5
3
|
# Copyright May 2008, Gregory Brown. All Rights Reserved.
|
6
4
|
#
|
7
5
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
6
|
|
9
|
-
require
|
7
|
+
require 'zlib'
|
10
8
|
|
11
|
-
require
|
9
|
+
require 'pdf/core/text'
|
12
10
|
|
13
|
-
require_relative
|
14
|
-
require_relative
|
11
|
+
require_relative 'text/formatted'
|
12
|
+
require_relative 'text/box'
|
15
13
|
|
16
14
|
module Prawn
|
17
15
|
module Text
|
@@ -19,11 +17,11 @@ module Prawn
|
|
19
17
|
include Prawn::Text::Formatted
|
20
18
|
|
21
19
|
# No-Break Space
|
22
|
-
|
20
|
+
NBSP = "\u00A0".freeze
|
23
21
|
# Zero Width Space (indicate word boundaries without a space)
|
24
|
-
|
22
|
+
ZWSP = "\u200B".freeze
|
25
23
|
# Soft Hyphen (invisible, except when causing a line break)
|
26
|
-
|
24
|
+
SHY = "\u00AD".freeze
|
27
25
|
|
28
26
|
# @group Stable API
|
29
27
|
|
@@ -139,9 +137,9 @@ module Prawn
|
|
139
137
|
# each line is included below the last line;
|
140
138
|
# otherwise, document.y is placed just below the
|
141
139
|
# descender of the last line printed [true]
|
142
|
-
# <tt>:mode</tt>:: The text rendering mode to use. Use this to specify if
|
143
|
-
# text should render with the fill color, stroke color
|
144
|
-
# both. See the comments to text_rendering_mode() to see
|
140
|
+
# <tt>:mode</tt>:: The text rendering mode to use. Use this to specify if
|
141
|
+
# the text should render with the fill color, stroke color
|
142
|
+
# or both. See the comments to text_rendering_mode() to see
|
145
143
|
# a list of valid options. [0]
|
146
144
|
#
|
147
145
|
# == Exceptions
|
@@ -156,12 +154,13 @@ module Prawn
|
|
156
154
|
# we modify the options. don't change the user's hash
|
157
155
|
options = options.dup
|
158
156
|
|
159
|
-
|
157
|
+
p = options[:inline_format]
|
158
|
+
if p
|
160
159
|
p = [] unless p.is_a?(Array)
|
161
160
|
options.delete(:inline_format)
|
162
|
-
array =
|
161
|
+
array = text_formatter.format(string, *p)
|
163
162
|
else
|
164
|
-
array = [{ :
|
163
|
+
array = [{ text: string }]
|
165
164
|
end
|
166
165
|
|
167
166
|
formatted_text(array, options)
|
@@ -190,14 +189,15 @@ module Prawn
|
|
190
189
|
def formatted_text(array, options = {})
|
191
190
|
options = inspect_options_for_text(options.dup)
|
192
191
|
|
193
|
-
|
192
|
+
color = options.delete(:color)
|
193
|
+
if color
|
194
194
|
array = array.map do |fragment|
|
195
|
-
fragment[:color] ? fragment : fragment.merge(:
|
195
|
+
fragment[:color] ? fragment : fragment.merge(color: color)
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
199
|
if @indent_paragraphs
|
200
|
-
|
200
|
+
text_formatter.array_paragraphs(array).each do |paragraph|
|
201
201
|
remaining_text = draw_indented_formatted_line(paragraph, options)
|
202
202
|
|
203
203
|
if @no_text_printed
|
@@ -208,8 +208,10 @@ module Prawn
|
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
211
|
-
|
212
|
-
|
211
|
+
unless @all_text_printed
|
212
|
+
remaining_text = fill_formatted_text_box(remaining_text, options)
|
213
|
+
draw_remaining_formatted_text_on_new_pages(remaining_text, options)
|
214
|
+
end
|
213
215
|
end
|
214
216
|
else
|
215
217
|
remaining_text = fill_formatted_text_box(array, options)
|
@@ -236,7 +238,8 @@ module Prawn
|
|
236
238
|
# == Rotation
|
237
239
|
#
|
238
240
|
# Text can be rotated before it is placed on the canvas by specifying the
|
239
|
-
# <tt>:rotate</tt> option with a given angle. Rotation occurs
|
241
|
+
# <tt>:rotate</tt> option with a given angle. Rotation occurs
|
242
|
+
# counter-clockwise.
|
240
243
|
#
|
241
244
|
# == Encoding
|
242
245
|
#
|
@@ -253,7 +256,8 @@ module Prawn
|
|
253
256
|
#
|
254
257
|
# == Options (default values marked in [])
|
255
258
|
#
|
256
|
-
# <tt>:at</tt>:: <tt>[x, y]</tt>(required). The position at which to start
|
259
|
+
# <tt>:at</tt>:: <tt>[x, y]</tt>(required). The position at which to start
|
260
|
+
# the text
|
257
261
|
# <tt>:kerning</tt>:: <tt>boolean</tt>. Whether or not to use kerning (if it
|
258
262
|
# is available with the current font)
|
259
263
|
# [value of default_kerning?]
|
@@ -317,7 +321,7 @@ module Prawn
|
|
317
321
|
# any text
|
318
322
|
#
|
319
323
|
def height_of(string, options = {})
|
320
|
-
height_of_formatted([{ :
|
324
|
+
height_of_formatted([{ text: string }], options)
|
321
325
|
end
|
322
326
|
|
323
327
|
# Gets height of formatted text in PDF points.
|
@@ -332,15 +336,15 @@ module Prawn
|
|
332
336
|
#
|
333
337
|
def height_of_formatted(array, options = {})
|
334
338
|
if options[:indent_paragraphs]
|
335
|
-
|
336
|
-
|
339
|
+
raise NotImplementedError, ':indent_paragraphs option not available' \
|
340
|
+
'with height_of'
|
337
341
|
end
|
338
342
|
process_final_gap_option(options)
|
339
343
|
box = Text::Formatted::Box.new(
|
340
344
|
array,
|
341
|
-
options.merge(:
|
345
|
+
options.merge(height: 100_000_000, document: self)
|
342
346
|
)
|
343
|
-
box.render(:
|
347
|
+
box.render(dry_run: true)
|
344
348
|
|
345
349
|
height = box.height
|
346
350
|
height += box.line_gap + box.leading if @final_gap
|
@@ -350,7 +354,7 @@ module Prawn
|
|
350
354
|
private
|
351
355
|
|
352
356
|
def draw_remaining_formatted_text_on_new_pages(remaining_text, options)
|
353
|
-
|
357
|
+
until remaining_text.empty?
|
354
358
|
@bounding_box.move_past_bottom
|
355
359
|
previous_remaining_text = remaining_text
|
356
360
|
remaining_text = fill_formatted_text_box(remaining_text, options)
|
@@ -359,14 +363,14 @@ module Prawn
|
|
359
363
|
end
|
360
364
|
|
361
365
|
def draw_indented_formatted_line(string, options)
|
362
|
-
if options.fetch(:direction, text_direction) == :ltr
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
366
|
+
gap = if options.fetch(:direction, text_direction) == :ltr
|
367
|
+
[@indent_paragraphs, 0]
|
368
|
+
else
|
369
|
+
[0, @indent_paragraphs]
|
370
|
+
end
|
367
371
|
|
368
372
|
indent(*gap) do
|
369
|
-
fill_formatted_text_box(string, options.dup.merge(:
|
373
|
+
fill_formatted_text_box(string, options.dup.merge(single_line: true))
|
370
374
|
end
|
371
375
|
end
|
372
376
|
|
@@ -384,22 +388,28 @@ module Prawn
|
|
384
388
|
end
|
385
389
|
|
386
390
|
def merge_text_box_positioning_options(options)
|
387
|
-
bottom =
|
388
|
-
|
391
|
+
bottom =
|
392
|
+
if @bounding_box.stretchy?
|
393
|
+
@margin_box.absolute_bottom
|
394
|
+
else
|
395
|
+
@bounding_box.absolute_bottom
|
396
|
+
end
|
389
397
|
|
390
398
|
options[:height] = y - bottom
|
391
399
|
options[:width] = bounds.width
|
392
|
-
options[:at] = [
|
393
|
-
|
400
|
+
options[:at] = [
|
401
|
+
@bounding_box.left_side - @bounding_box.absolute_left,
|
402
|
+
y - @bounding_box.absolute_bottom
|
403
|
+
]
|
394
404
|
end
|
395
405
|
|
396
406
|
def inspect_options_for_draw_text(options)
|
397
407
|
if options[:at].nil?
|
398
|
-
|
408
|
+
raise ArgumentError, 'The :at option is required for draw_text'
|
399
409
|
elsif options[:align]
|
400
|
-
|
410
|
+
raise ArgumentError, 'The :align option does not work with draw_text'
|
401
411
|
end
|
402
|
-
if options[:kerning].nil?
|
412
|
+
if options[:kerning].nil?
|
403
413
|
options[:kerning] = default_kerning?
|
404
414
|
end
|
405
415
|
valid_options = PDF::Core::Text::VALID_OPTIONS + [:at, :rotate]
|
@@ -409,8 +419,8 @@ module Prawn
|
|
409
419
|
|
410
420
|
def inspect_options_for_text(options)
|
411
421
|
if options[:at]
|
412
|
-
|
413
|
-
|
422
|
+
raise ArgumentError, ':at is no longer a valid option with text.' \
|
423
|
+
'use draw_text or text_box instead'
|
414
424
|
end
|
415
425
|
process_final_gap_option(options)
|
416
426
|
process_indent_paragraphs_option(options)
|
@@ -429,8 +439,12 @@ module Prawn
|
|
429
439
|
end
|
430
440
|
|
431
441
|
def move_text_position(dy)
|
432
|
-
bottom =
|
433
|
-
|
442
|
+
bottom =
|
443
|
+
if @bounding_box.stretchy?
|
444
|
+
@margin_box.absolute_bottom
|
445
|
+
else
|
446
|
+
@bounding_box.absolute_bottom
|
447
|
+
end
|
434
448
|
|
435
449
|
@bounding_box.move_past_bottom if (y - dy) < bottom
|
436
450
|
|