hexapdf 0.21.1 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +137 -0
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/examples/016-frame_automatic_box_placement.rb +7 -2
- data/examples/017-frame_text_flow.rb +10 -18
- data/examples/020-column_box.rb +20 -37
- data/examples/021-list_box.rb +26 -0
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +31 -4
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +2 -2
- data/lib/hexapdf/cli/inspect.rb +19 -6
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +24 -4
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +66 -125
- data/lib/hexapdf/configuration.rb +17 -1
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/content/color_space.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +2 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/content/parser.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +2 -2
- data/lib/hexapdf/document/destinations.rb +396 -0
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/layout.rb +397 -0
- data/lib/hexapdf/document/pages.rb +17 -1
- data/lib/hexapdf/document/signatures.rb +5 -4
- data/lib/hexapdf/document.rb +46 -90
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +30 -21
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +1 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/crypt.rb +1 -1
- data/lib/hexapdf/filter/encryption.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +1 -1
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +1 -1
- data/lib/hexapdf/layout/box.rb +121 -22
- data/lib/hexapdf/layout/box_fitter.rb +136 -0
- data/lib/hexapdf/layout/column_box.rb +168 -89
- data/lib/hexapdf/layout/frame.rb +155 -140
- data/lib/hexapdf/layout/image_box.rb +19 -4
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +355 -0
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +285 -8
- data/lib/hexapdf/layout/text_box.rb +30 -11
- data/lib/hexapdf/layout/text_fragment.rb +3 -2
- data/lib/hexapdf/layout/text_layouter.rb +23 -3
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +12 -7
- data/lib/hexapdf/layout.rb +4 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +1 -1
- data/lib/hexapdf/parser.rb +1 -8
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +9 -2
- data/lib/hexapdf/revisions.rb +152 -51
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +22 -12
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/field.rb +1 -1
- data/lib/hexapdf/type/acro_form/form.rb +12 -6
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +9 -1
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +1 -1
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +10 -2
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +1 -1
- data/lib/hexapdf/type/font.rb +1 -1
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_true_type.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type1.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +1 -1
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +48 -4
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +14 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +19 -2
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +1 -1
- data/lib/hexapdf/type/signature/handler.rb +1 -1
- data/lib/hexapdf/type/signature/verification_result.rb +1 -1
- data/lib/hexapdf/type/signature.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +2 -2
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +3 -2
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +1 -1
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +4 -2
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +23 -8
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +1 -1
- data/test/hexapdf/document/test_destinations.rb +338 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +264 -0
- data/test/hexapdf/document/test_pages.rb +9 -0
- data/test/hexapdf/document/test_signatures.rb +10 -3
- data/test/hexapdf/encryption/test_security_handler.rb +3 -3
- data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
- data/test/hexapdf/layout/test_box.rb +53 -3
- data/test/hexapdf/layout/test_box_fitter.rb +62 -0
- data/test/hexapdf/layout/test_column_box.rb +159 -0
- data/test/hexapdf/layout/test_frame.rb +114 -39
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_list_box.rb +249 -0
- data/test/hexapdf/layout/test_text_box.rb +33 -2
- data/test/hexapdf/layout/test_text_fragment.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +49 -17
- data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
- data/test/hexapdf/task/test_optimize.rb +17 -4
- data/test/hexapdf/test_composer.rb +35 -1
- data/test/hexapdf/test_dictionary_fields.rb +10 -10
- data/test/hexapdf/test_document.rb +33 -136
- data/test/hexapdf/test_filter.rb +1 -1
- data/test/hexapdf/test_parser.rb +1 -3
- data/test/hexapdf/test_revision.rb +14 -0
- data/test/hexapdf/test_revisions.rb +137 -29
- data/test/hexapdf/test_serializer.rb +1 -5
- data/test/hexapdf/test_writer.rb +99 -15
- data/test/hexapdf/type/acro_form/test_form.rb +2 -1
- data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
- data/test/hexapdf/type/test_catalog.rb +8 -0
- data/test/hexapdf/type/test_image.rb +45 -9
- data/test/hexapdf/type/test_names.rb +20 -0
- data/test/hexapdf/type/test_page_tree_node.rb +21 -1
- data/test/hexapdf/type/test_trailer.rb +3 -3
- data/test/hexapdf/type/test_xref_stream.rb +2 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
- data/test/test_helper.rb +5 -1
- metadata +29 -3
data/lib/hexapdf/type/image.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -163,13 +163,23 @@ module HexaPDF
|
|
163
163
|
result.color_space = :cmyk
|
164
164
|
result.components = 4
|
165
165
|
result.writable = false if result.type == :png
|
166
|
+
when :ICCBased
|
167
|
+
result.color_space = :icc
|
168
|
+
result.components = self[:ColorSpace][1][:N]
|
169
|
+
result.writable = false if result.type == :png && result.components == 4
|
166
170
|
else
|
167
171
|
result.color_space = :other
|
168
172
|
result.components = -1
|
169
173
|
result.writable = false if result.type == :png
|
170
174
|
end
|
171
175
|
|
172
|
-
|
176
|
+
smask = self[:SMask]
|
177
|
+
if smask && (result.type != :png ||
|
178
|
+
!(result.bits_per_component == 8 || result.bits_per_component == 16) ||
|
179
|
+
result.bits_per_component != smask[:BitsPerComponent] ||
|
180
|
+
result.width != smask[:Width] || result.height != smask[:Height])
|
181
|
+
result.writable = false
|
182
|
+
end
|
173
183
|
|
174
184
|
result
|
175
185
|
end
|
@@ -224,10 +234,18 @@ module HexaPDF
|
|
224
234
|
ImageLoader::PNG::INDEXED
|
225
235
|
elsif info.color_space == :rgb
|
226
236
|
ImageLoader::PNG::TRUECOLOR
|
237
|
+
elsif info.color_space == :icc
|
238
|
+
info.components == 3 ? ImageLoader::PNG::TRUECOLOR : ImageLoader::PNG::GREYSCALE
|
227
239
|
else
|
228
240
|
ImageLoader::PNG::GREYSCALE
|
229
241
|
end
|
230
242
|
|
243
|
+
if self[:SMask] && color_type != ImageLoader::PNG::INDEXED
|
244
|
+
color_type += 4 # change it to TrueColor/Greyscale with Alpha
|
245
|
+
end
|
246
|
+
|
247
|
+
flate_decode = config.constantize('filter.map', :FlateDecode)
|
248
|
+
|
231
249
|
io << png_chunk('IHDR', [info.width, info.height, info.bits_per_component,
|
232
250
|
color_type, 0, 0, 0].pack('N2C5'))
|
233
251
|
|
@@ -239,6 +257,12 @@ module HexaPDF
|
|
239
257
|
png_chunk('cHRM', [31270, 32900, 64000, 33000, 30000, 60000, 15000, 6000].pack('N8'))
|
240
258
|
end
|
241
259
|
|
260
|
+
if info.color_space == :icc
|
261
|
+
_, stream = *self[:ColorSpace]
|
262
|
+
data = flate_decode.encoder(stream.stream_decoder)
|
263
|
+
io << png_chunk('iCCP', "ICCProfile\x00\x00".b << Filter.string_from_source(data))
|
264
|
+
end
|
265
|
+
|
242
266
|
if color_type == ImageLoader::PNG::INDEXED
|
243
267
|
palette_data = self[:ColorSpace][3]
|
244
268
|
palette_data = palette_data.stream unless palette_data.kind_of?(String)
|
@@ -258,11 +282,14 @@ module HexaPDF
|
|
258
282
|
|
259
283
|
filter, = *self[:Filter]
|
260
284
|
decode_parms, = *self[:DecodeParms]
|
261
|
-
if
|
285
|
+
if self[:SMask]
|
286
|
+
data = flate_decode.encoder(Fiber.new { png_combine_image_and_soft_mask(info) }, Predictor: 15,
|
287
|
+
Colors: info.components + 1, Columns: info.width,
|
288
|
+
BitsPerComponent: info.bits_per_component)
|
289
|
+
elsif filter == :FlateDecode && decode_parms && decode_parms[:Predictor].to_i >= 10
|
262
290
|
data = stream_source
|
263
291
|
else
|
264
292
|
colors = (color_type == ImageLoader::PNG::INDEXED ? 1 : info.components)
|
265
|
-
flate_decode = config.constantize('filter.map', :FlateDecode)
|
266
293
|
data = flate_decode.encoder(stream_decoder, Predictor: 15,
|
267
294
|
Colors: colors, Columns: info.width,
|
268
295
|
BitsPerComponent: info.bits_per_component)
|
@@ -277,6 +304,23 @@ module HexaPDF
|
|
277
304
|
[data.length].pack("N") << type << data << [Zlib.crc32(data, Zlib.crc32(type))].pack("N")
|
278
305
|
end
|
279
306
|
|
307
|
+
# Combines the image data with the soft mask data as needed for a PNG data stream.
|
308
|
+
def png_combine_image_and_soft_mask(info)
|
309
|
+
bytes_per_colors = info.bits_per_component * info.components / 8
|
310
|
+
bytes_per_alpha = info.bits_per_component / 8
|
311
|
+
image_data = stream
|
312
|
+
mask_data = self[:SMask].stream
|
313
|
+
|
314
|
+
data = ''.b
|
315
|
+
ii = im = 0
|
316
|
+
while ii < image_data.length
|
317
|
+
data << image_data[ii, bytes_per_colors] << mask_data[im, bytes_per_alpha]
|
318
|
+
ii += bytes_per_colors
|
319
|
+
im += bytes_per_alpha
|
320
|
+
end
|
321
|
+
data
|
322
|
+
end
|
323
|
+
|
280
324
|
end
|
281
325
|
|
282
326
|
end
|
data/lib/hexapdf/type/info.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/type/names.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -63,6 +63,19 @@ module HexaPDF
|
|
63
63
|
define_field :AlternatePresentations, type: NameTreeNode, version: '1.4'
|
64
64
|
define_field :Renditions, type: NameTreeNode, version: '1.5'
|
65
65
|
|
66
|
+
# Returns the destinations name tree containing a mapping from names to destination objects.
|
67
|
+
#
|
68
|
+
# The name tree will be created if needed.
|
69
|
+
#
|
70
|
+
# Note: It is possible to use this name tree directly, but HexaPDF::Document::Destinations
|
71
|
+
# provides a much easier to work with convenience interface for working with destination
|
72
|
+
# objects.
|
73
|
+
#
|
74
|
+
# See: PDF1.7 s12.3.2
|
75
|
+
def destinations
|
76
|
+
self[:Dests] ||= document.add({}, type: NameTreeNode)
|
77
|
+
end
|
78
|
+
|
66
79
|
end
|
67
80
|
|
68
81
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/type/page.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -207,9 +207,26 @@ module HexaPDF
|
|
207
207
|
end
|
208
208
|
|
209
209
|
parent = page[:Parent]
|
210
|
+
prev_index = page.index
|
211
|
+
prev_kid_index = parent[:Kids].index(page)
|
212
|
+
if to_index < 0
|
213
|
+
to_index = self[:Count] + to_index + 1
|
214
|
+
elsif prev_index < to_index
|
215
|
+
to_index += 1
|
216
|
+
end
|
217
|
+
|
210
218
|
insert_page(to_index, page)
|
219
|
+
|
211
220
|
ancestors.each {|node| node[:Count] -= 1 }
|
212
|
-
|
221
|
+
if page[:Parent] == parent
|
222
|
+
if prev_index < to_index
|
223
|
+
parent[:Kids].delete_at(prev_kid_index)
|
224
|
+
else
|
225
|
+
parent[:Kids].delete_at(prev_kid_index + 1)
|
226
|
+
end
|
227
|
+
else
|
228
|
+
parent[:Kids].delete(page)
|
229
|
+
end
|
213
230
|
end
|
214
231
|
|
215
232
|
# :call-seq:
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/type/trailer.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -69,7 +69,7 @@ module HexaPDF
|
|
69
69
|
|
70
70
|
# Returns the document's Catalog (see Type::Catalog), creating it if needed.
|
71
71
|
def catalog
|
72
|
-
self[:Root] ||= document.add({Type: :Catalog})
|
72
|
+
self[:Root] ||= document.add({Type: :Catalog}, type: :Catalog)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Returns the document's information dictionary (see Type::Info), creating it if needed.
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -93,7 +93,8 @@ module HexaPDF
|
|
93
93
|
#
|
94
94
|
# See: Type::Trailer
|
95
95
|
def trailer
|
96
|
-
|
96
|
+
trailer = {Type: :XRef}
|
97
|
+
Trailer.each_field.with_object(trailer) do |(name, _data), hash|
|
97
98
|
hash[name] = value[name] if key?(name)
|
98
99
|
end
|
99
100
|
end
|
data/lib/hexapdf/type.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -168,11 +168,13 @@ module HexaPDF
|
|
168
168
|
index = find_in_leaf_node(node[container_name], key)
|
169
169
|
if node[container_name][index] == key
|
170
170
|
result = node[container_name][index + 1]
|
171
|
+
else
|
172
|
+
break
|
171
173
|
end
|
172
174
|
elsif node.key?(:Kids)
|
173
175
|
index = find_in_intermediate_node(node[:Kids], key)
|
174
176
|
node = node[:Kids][index]
|
175
|
-
break unless key >= node[:Limits][0] && key <= node[:Limits][1]
|
177
|
+
break unless node && key >= node[:Limits][0] && key <= node[:Limits][1]
|
176
178
|
else
|
177
179
|
break
|
178
180
|
end
|
data/lib/hexapdf/version.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -37,6 +37,6 @@
|
|
37
37
|
module HexaPDF
|
38
38
|
|
39
39
|
# The version of HexaPDF.
|
40
|
-
VERSION = '0.
|
40
|
+
VERSION = '0.24.0'
|
41
41
|
|
42
42
|
end
|
data/lib/hexapdf/writer.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -72,8 +72,10 @@ module HexaPDF
|
|
72
72
|
@use_xref_streams = false
|
73
73
|
end
|
74
74
|
|
75
|
-
# Writes the document to the IO object and returns the
|
75
|
+
# Writes the document to the IO object and returns the file position of the start of the last
|
76
|
+
# cross-reference section and the last XRefSection written.
|
76
77
|
def write
|
78
|
+
move_modified_objects_into_current_revision
|
77
79
|
write_file_header
|
78
80
|
|
79
81
|
pos = xref_section = nil
|
@@ -82,11 +84,12 @@ module HexaPDF
|
|
82
84
|
pos, xref_section = write_revision(rev, pos)
|
83
85
|
end
|
84
86
|
|
85
|
-
xref_section
|
87
|
+
[pos, xref_section]
|
86
88
|
end
|
87
89
|
|
88
90
|
# Writes the complete source document unmodified to the IO and then one revision containing all
|
89
|
-
# changes. Returns the
|
91
|
+
# changes. Returns the file position of the start of the cross-reference section and the
|
92
|
+
# XRefSection object of that one revision.
|
90
93
|
#
|
91
94
|
# For this method to work the document must have been created from an existing file.
|
92
95
|
def write_incremental
|
@@ -103,15 +106,15 @@ module HexaPDF
|
|
103
106
|
@io << "\n"
|
104
107
|
|
105
108
|
@rev_size = @document.revisions.current.next_free_oid
|
106
|
-
@use_xref_streams =
|
109
|
+
@use_xref_streams = @document.revisions.any? {|rev| rev.trailer[:Type] == :XRef }
|
107
110
|
|
108
111
|
revision = Revision.new(@document.revisions.current.trailer)
|
112
|
+
@document.trailer.info[:Producer] = "HexaPDF version #{HexaPDF::VERSION}"
|
109
113
|
@document.revisions.each do |rev|
|
110
114
|
rev.each_modified_object {|obj| revision.send(:add_without_check, obj) }
|
111
115
|
end
|
112
|
-
_pos, xref_section = write_revision(revision, @document.revisions.parser.startxref_offset)
|
113
116
|
|
114
|
-
|
117
|
+
write_revision(revision, parser.startxref_offset)
|
115
118
|
end
|
116
119
|
|
117
120
|
private
|
@@ -123,6 +126,18 @@ module HexaPDF
|
|
123
126
|
@io << "%PDF-#{@document.version}\n%\xCF\xEC\xFF\xE8\xD7\xCB\xCD\n"
|
124
127
|
end
|
125
128
|
|
129
|
+
# Moves all modified objects into the current revision to avoid invalid references and such.
|
130
|
+
def move_modified_objects_into_current_revision
|
131
|
+
return if @document.revisions.count == 1
|
132
|
+
|
133
|
+
revision = @document.revisions.add
|
134
|
+
@document.revisions.all[0..-2].each do |rev|
|
135
|
+
rev.each_modified_object {|obj| revision.send(:add_without_check, obj) }
|
136
|
+
rev.reset_objects
|
137
|
+
end
|
138
|
+
@document.revisions.merge(-2..-1)
|
139
|
+
end
|
140
|
+
|
126
141
|
# Writes the given revision.
|
127
142
|
#
|
128
143
|
# The optional +previous_xref_pos+ argument needs to contain the byte position of the previous
|
@@ -190,7 +205,7 @@ module HexaPDF
|
|
190
205
|
end
|
191
206
|
|
192
207
|
if (!object_streams.empty? || @use_xref_streams) && xref_stream.nil?
|
193
|
-
xref_stream = @document.wrap({Type: :XRef}, oid:
|
208
|
+
xref_stream = @document.wrap({Type: :XRef}, oid: @document.revisions.next_oid)
|
194
209
|
rev.add(xref_stream)
|
195
210
|
end
|
196
211
|
|
data/lib/hexapdf/xref_section.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# This file is part of HexaPDF.
|
5
5
|
#
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
-
# Copyright (C) 2014-
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
8
8
|
#
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
@@ -57,7 +57,7 @@ describe HexaPDF::Content::GraphicObject::Geom2D do
|
|
57
57
|
@obj.draw(@canvas)
|
58
58
|
assert_operators(@canvas.contents,
|
59
59
|
[[:move_to, [5, 6]], [:line_to, [10, 11]], [:line_to, [7, 9]],
|
60
|
-
[:stroke_path]])
|
60
|
+
[:close_subpath], [:stroke_path]])
|
61
61
|
end
|
62
62
|
|
63
63
|
it "draws a Geom2D::PolygonSet onto the canvas" do
|