hexapdf 0.23.0 → 0.24.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
- data/CHANGELOG.md +66 -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 +40 -0
- 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 +2 -2
- 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 +2 -2
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +1 -1
- 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 +45 -126
- 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 +1 -1
- 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 +8 -1
- 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 +247 -0
- data/lib/hexapdf/layout/frame.rb +155 -139
- 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 +5 -1
- data/lib/hexapdf/layout/text_box.rb +20 -9
- data/lib/hexapdf/layout/text_fragment.rb +3 -2
- data/lib/hexapdf/layout/text_layouter.rb +17 -2
- 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 +1 -1
- data/lib/hexapdf/revisions.rb +1 -1
- 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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +1 -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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +9 -7
- 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 +1 -1
- 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 +1 -1
- 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 +99 -38
- 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 +17 -2
- data/test/hexapdf/layout/test_text_fragment.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +42 -17
- data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
- data/test/hexapdf/test_composer.rb +11 -0
- data/test/hexapdf/test_dictionary_fields.rb +9 -9
- data/test/hexapdf/test_document.rb +4 -4
- data/test/hexapdf/test_filter.rb +1 -1
- data/test/hexapdf/test_parser.rb +0 -2
- data/test/hexapdf/test_revisions.rb +2 -2
- data/test/hexapdf/test_serializer.rb +1 -5
- data/test/hexapdf/test_writer.rb +58 -3
- data/test/hexapdf/type/test_page_tree_node.rb +21 -1
- data/test/hexapdf/type/test_trailer.rb +3 -3
- data/test/test_helper.rb +5 -1
- metadata +28 -3
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
|
+
#
|
|
3
|
+
#--
|
|
4
|
+
# This file is part of HexaPDF.
|
|
5
|
+
#
|
|
6
|
+
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
+
# Copyright (C) 2014-2022 Thomas Leitner
|
|
8
|
+
#
|
|
9
|
+
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
|
+
# under the terms of the GNU Affero General Public License version 3 as
|
|
11
|
+
# published by the Free Software Foundation with the addition of the
|
|
12
|
+
# following permission added to Section 15 as permitted in Section 7(a):
|
|
13
|
+
# FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
|
14
|
+
# THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
|
|
15
|
+
# INFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
16
|
+
#
|
|
17
|
+
# HexaPDF is distributed in the hope that it will be useful, but WITHOUT
|
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
20
|
+
# License for more details.
|
|
21
|
+
#
|
|
22
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
23
|
+
# along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
#
|
|
25
|
+
# The interactive user interfaces in modified source and object code
|
|
26
|
+
# versions of HexaPDF must display Appropriate Legal Notices, as required
|
|
27
|
+
# under Section 5 of the GNU Affero General Public License version 3.
|
|
28
|
+
#
|
|
29
|
+
# In accordance with Section 7(b) of the GNU Affero General Public
|
|
30
|
+
# License, a covered work must retain the producer line in every PDF that
|
|
31
|
+
# is created or manipulated using HexaPDF.
|
|
32
|
+
#
|
|
33
|
+
# If the GNU Affero General Public License doesn't fit your need,
|
|
34
|
+
# commercial licenses are available at <https://gettalong.at/hexapdf/>.
|
|
35
|
+
#++
|
|
36
|
+
|
|
37
|
+
require 'hexapdf/layout'
|
|
38
|
+
|
|
39
|
+
module HexaPDF
|
|
40
|
+
class Document
|
|
41
|
+
|
|
42
|
+
# This class provides methods for working with classes in the HexaPDF::Layout module.
|
|
43
|
+
#
|
|
44
|
+
# Often times the layout related classes are used through HexaPDF::Composer which makes it easy
|
|
45
|
+
# to create documents. However, sometimes one wants to have a bit more control or do something
|
|
46
|
+
# special and use the HexaPDF::Layout classes directly. This is possible but it is better to use
|
|
47
|
+
# those classes through an instance of this classs because it makes it more convenient and ties
|
|
48
|
+
# everything together. Incidentally, HexaPDF::Composer relies on this class for a good part of
|
|
49
|
+
# its work.
|
|
50
|
+
#
|
|
51
|
+
#
|
|
52
|
+
# == Boxes
|
|
53
|
+
#
|
|
54
|
+
# The main focus of the class is on providing convenience methods for creating box objects. The
|
|
55
|
+
# most often used box classes like HexaPDF::Layout::TextBox or HexaPDF::Layout::ImagebBox can be
|
|
56
|
+
# created through dedicated methods.
|
|
57
|
+
#
|
|
58
|
+
# Other, more general boxes don't have their own method but can be created through the general
|
|
59
|
+
# #box method.
|
|
60
|
+
#
|
|
61
|
+
#
|
|
62
|
+
# == Box Styles
|
|
63
|
+
#
|
|
64
|
+
# All box creation methods accept HexaPDF::Layout::Style objects or names for style objects
|
|
65
|
+
# (defined via #style). This allows one to predefine certain styles (like first level heading,
|
|
66
|
+
# second level heading, paragraph, ...) and consistently use them throughout the document
|
|
67
|
+
# creation process.
|
|
68
|
+
#
|
|
69
|
+
# One style property, HexaPDF::Layout::Style#font, is handled specially:
|
|
70
|
+
#
|
|
71
|
+
# * If no font is set on a style, the font "Times" is automatically set because otherwise there
|
|
72
|
+
# would be problems with text drawing operations (font is the only style property that has no
|
|
73
|
+
# valid default value).
|
|
74
|
+
#
|
|
75
|
+
# * Standard style objects only allow font wrapper objects to be set via the
|
|
76
|
+
# HexaPDF::Layout::Style#font method. This class makes usage easier by allowing strings or an
|
|
77
|
+
# array [name, options_hash] to be used, like with e.g Content::Canvas#font. So to use
|
|
78
|
+
# Helvetica as font, one could just do:
|
|
79
|
+
#
|
|
80
|
+
# style.font = 'Helvetica'
|
|
81
|
+
#
|
|
82
|
+
# And if Helvetica in its bold variant should be used it would be:
|
|
83
|
+
#
|
|
84
|
+
# style.font = ['Helvetica', variant: :bold]
|
|
85
|
+
#
|
|
86
|
+
class Layout
|
|
87
|
+
|
|
88
|
+
# This class is used when a box can contain child boxes and the creation of such boxes should
|
|
89
|
+
# be seemlessly doable when creating the parent node. It is yieled, for example, by Layout#box
|
|
90
|
+
# to collect the children for the created box.
|
|
91
|
+
#
|
|
92
|
+
# A box can be added to the list of collected children in the following ways:
|
|
93
|
+
#
|
|
94
|
+
# #<<:: This appends the given box to the list.
|
|
95
|
+
#
|
|
96
|
+
# text_box, formatted_text_box, image_box, ...:: Any method accepted by the Layout class.
|
|
97
|
+
#
|
|
98
|
+
# text, formatted_text, image, ...:: Any method accepted by the Layout class without the _box
|
|
99
|
+
# suffix.
|
|
100
|
+
#
|
|
101
|
+
# list, column, ...:: Any name registered for the configuration option +layout.boxes.map+.
|
|
102
|
+
#
|
|
103
|
+
# Example:
|
|
104
|
+
#
|
|
105
|
+
# document.layout.box(:list) do |list|
|
|
106
|
+
# list.text_box("Some text here") # layout method
|
|
107
|
+
# list.image(image_path) # layout method without _box suffix
|
|
108
|
+
# list.column(columns: 3) do |column| # registered box name
|
|
109
|
+
# column.text("Text in column")
|
|
110
|
+
# column << document.layout.lorem_ipsum_box # adding a Box instance
|
|
111
|
+
# end
|
|
112
|
+
# end
|
|
113
|
+
class ChildrenCollector
|
|
114
|
+
|
|
115
|
+
# Creates a children collector, yields it and then returns the collected children.
|
|
116
|
+
def self.collect(layout)
|
|
117
|
+
collector = new(layout)
|
|
118
|
+
yield(collector)
|
|
119
|
+
collector.children
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# The collected children
|
|
123
|
+
attr_reader :children
|
|
124
|
+
|
|
125
|
+
# Create a new ChildrenCollector for the given +layout+ (a HexaPDF::Document::Layout)
|
|
126
|
+
# instance.
|
|
127
|
+
def initialize(layout)
|
|
128
|
+
@layout = layout
|
|
129
|
+
@layout_boxes_map = layout.instance_variable_get(:@document).config['layout.boxes.map']
|
|
130
|
+
@children = []
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# :nodoc:
|
|
134
|
+
def method_missing(name, *args, **kwargs, &block)
|
|
135
|
+
if @layout.respond_to?(name)
|
|
136
|
+
@children << @layout.send(name, *args, **kwargs, &block)
|
|
137
|
+
elsif @layout.respond_to?("#{name}_box")
|
|
138
|
+
@children << @layout.send("#{name}_box", *args, **kwargs, &block)
|
|
139
|
+
elsif @layout_boxes_map.key?(name)
|
|
140
|
+
@children << @layout.box(name, *args, **kwargs, &block)
|
|
141
|
+
else
|
|
142
|
+
super
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# :nodoc:
|
|
147
|
+
def respond_to_missing?(name, _private)
|
|
148
|
+
@layout.respond_to?(name) ||
|
|
149
|
+
@layout.respond_to?("#{name}_box") ||
|
|
150
|
+
@layout_boxes_map.key?(name) ||
|
|
151
|
+
super
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Appends the given box to the list of collected children.
|
|
155
|
+
def <<(box)
|
|
156
|
+
@children << box
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Yields a ChildrenCollector instance and adds the collected children as a single array to
|
|
160
|
+
# the list of collected children.
|
|
161
|
+
def multiple(&block)
|
|
162
|
+
@children << self.class.collect(@layout, &block)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# The mapping of style name (a Symbol) to HexaPDF::Layout::Style instance.
|
|
168
|
+
attr_reader :styles
|
|
169
|
+
|
|
170
|
+
# Creates a new Layout object for the given PDF document.
|
|
171
|
+
def initialize(document)
|
|
172
|
+
@document = document
|
|
173
|
+
@styles = {base: HexaPDF::Layout::Style.new}
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# :call-seq:
|
|
177
|
+
# layout.style(name) -> style
|
|
178
|
+
# layout.style(name, base: :base, **properties) -> style
|
|
179
|
+
#
|
|
180
|
+
# Creates or updates the HexaPDF::Layout::Style object called +name+ with the given property
|
|
181
|
+
# values and returns it.
|
|
182
|
+
#
|
|
183
|
+
# This method allows convenient access to the stored styles and to update them. Such styles
|
|
184
|
+
# can then be used by name in the various box creation methods, e.g. #text_box or #image_box.
|
|
185
|
+
#
|
|
186
|
+
# If neither +base+ nor any style properties are specified, the style +name+ is just returned.
|
|
187
|
+
#
|
|
188
|
+
# If the style +name+ does not exist yet and the argument +base+ specifies the name of another
|
|
189
|
+
# style, that style is duplicated and used as basis for the style. This also means that the
|
|
190
|
+
# referenced +base+ style needs be defined first!
|
|
191
|
+
#
|
|
192
|
+
# The special name :base should be used for setting the base style which is used when no
|
|
193
|
+
# specific style is set.
|
|
194
|
+
#
|
|
195
|
+
# Note that the style property 'font' is handled specially, see the class documentation for
|
|
196
|
+
# details.
|
|
197
|
+
#
|
|
198
|
+
# Example:
|
|
199
|
+
#
|
|
200
|
+
# layout.style(:base, font_size: 12, leading: 1.2)
|
|
201
|
+
# layout.style(:header, font: 'Helvetica', fill_color: "008")
|
|
202
|
+
# layout.style(:header1, base: :header, font_size: 30)
|
|
203
|
+
#
|
|
204
|
+
# See: HexaPDF::Layout::Style
|
|
205
|
+
def style(name, base: :base, **properties)
|
|
206
|
+
style = @styles[name] ||= (@styles.key?(base) ? @styles[base].dup : HexaPDF::Layout::Style.new)
|
|
207
|
+
style.update(**properties) unless properties.empty?
|
|
208
|
+
style
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Creates the named box and returns it.
|
|
212
|
+
#
|
|
213
|
+
# The +name+ argument refers to the registered name of the box class that is looked up in the
|
|
214
|
+
# 'layout.boxes.map' configuration option. The +box_options+ are passed as-is to the
|
|
215
|
+
# initialization method of that box class
|
|
216
|
+
#
|
|
217
|
+
# If a block is provided, a ChildrenCollector is yielded and the collected children are passed
|
|
218
|
+
# to the box initialization method via the :children keyword argument.
|
|
219
|
+
#
|
|
220
|
+
# See #text_box for details on +width+, +height+ and +style+ (note that there is no
|
|
221
|
+
# +style_properties+ argument).
|
|
222
|
+
#
|
|
223
|
+
# Example:
|
|
224
|
+
#
|
|
225
|
+
# doc.layout.box(:column, columns: 2, gap: 15) # => column_box_instance
|
|
226
|
+
# doc.layout.box(:column) do |column| # column box with one child
|
|
227
|
+
# column.lorem_ipsum
|
|
228
|
+
# end
|
|
229
|
+
def box(name, width: 0, height: 0, style: nil, **box_options, &block)
|
|
230
|
+
if block_given? && !box_options.key?(:children)
|
|
231
|
+
box_options[:children] = ChildrenCollector.collect(self, &block)
|
|
232
|
+
end
|
|
233
|
+
box_class_for_name(name).new(width: width, height: height,
|
|
234
|
+
style: retrieve_style(style), **box_options)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Creates a HexaPDF::Layout::TextBox for the given text.
|
|
238
|
+
#
|
|
239
|
+
# This method is of the two main methods for creating text boxes, the other being
|
|
240
|
+
# #formatted_text_box.
|
|
241
|
+
#
|
|
242
|
+
# +width+, +height+::
|
|
243
|
+
# The arguments +width+ and +height+ are used as constraints and are respected when
|
|
244
|
+
# fitting the box. The default value of 0 means that no constraints are set.
|
|
245
|
+
#
|
|
246
|
+
# +style+, +style_properties+::
|
|
247
|
+
# The box and the text are styled using the given +style+. This can either be a style name
|
|
248
|
+
# set via #style or anything HexaPDF::Layout::Style::create accepts. If any additional
|
|
249
|
+
# +style_properties+ are specified, the style is duplicated and the additional styles are
|
|
250
|
+
# applied.
|
|
251
|
+
#
|
|
252
|
+
# +box_style+::
|
|
253
|
+
# Sometimes it is necessary for the box to have a different style than the text, e.g. when
|
|
254
|
+
# using overlays. In such a case use +box_style+ for specifiying the style of the box (a
|
|
255
|
+
# style name set via #style or anything HexaPDF::Layout::Style::create accepts).
|
|
256
|
+
#
|
|
257
|
+
# The +style+ together with the +style_properties+ will be used for the text style.
|
|
258
|
+
#
|
|
259
|
+
# Examples:
|
|
260
|
+
#
|
|
261
|
+
# layout.text("Test " * 15)
|
|
262
|
+
# layout.text("Now " * 7, width: 100)
|
|
263
|
+
# layout.text("Another test", font_size: 15, fill_color: "green")
|
|
264
|
+
# layout.text("Different box style", fill_color: 'white', box_style: {
|
|
265
|
+
# underlays: [->(c, b) { c.rectangle(0, 0, b.content_width, b.content_height).fill }]
|
|
266
|
+
# })
|
|
267
|
+
#
|
|
268
|
+
# See: #formatted_text_box, HexaPDF::Layout::TextBox, HexaPDF::Layout::TextFragment
|
|
269
|
+
def text_box(text, width: 0, height: 0, style: nil, box_style: nil, **style_properties)
|
|
270
|
+
style = retrieve_style(style, style_properties)
|
|
271
|
+
box_style = (box_style ? retrieve_style(box_style) : style)
|
|
272
|
+
box_class_for_name(:text).new(items: [HexaPDF::Layout::TextFragment.create(text, style)],
|
|
273
|
+
width: width, height: height, style: box_style)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Creates a HexaPDF::Layout::TextBox like #text_box but allows parts of the text to be
|
|
277
|
+
# formatted differently.
|
|
278
|
+
#
|
|
279
|
+
# The argument +data+ needs to be an array of String and/or Hash objects:
|
|
280
|
+
#
|
|
281
|
+
# * A String object is treated like {text: data}.
|
|
282
|
+
#
|
|
283
|
+
# * Hashes can contain any style properties and the following special keys:
|
|
284
|
+
#
|
|
285
|
+
# text:: The text to be formatted.
|
|
286
|
+
#
|
|
287
|
+
# link:: A URL that should be linked to. If no text is provided but a link, the link is used
|
|
288
|
+
# as text.
|
|
289
|
+
#
|
|
290
|
+
# style:: The style to be use as base style instead of the style created from the +style+
|
|
291
|
+
# and +style_properties+ arguments. See HexaPDF::Layout::Style::create for allowed
|
|
292
|
+
# values.
|
|
293
|
+
#
|
|
294
|
+
# If any style properties are set, the used style is duplicated and the additional
|
|
295
|
+
# properties applied.
|
|
296
|
+
#
|
|
297
|
+
# See #text_box for details on +width+, +height+, +style+, +style_properties+ and +box_style+.
|
|
298
|
+
#
|
|
299
|
+
# Examples:
|
|
300
|
+
#
|
|
301
|
+
# layout.formatted_text_box(["Some string"])
|
|
302
|
+
# layout.formatted_text_box(["Some ", {text: "string", fill_color: 128}])
|
|
303
|
+
# layout.formatted_text_box(["Some ", {link: "https://example.com",
|
|
304
|
+
# fill_color: 'blue', text: "Example"}])
|
|
305
|
+
# layout.formatted_text_box(["Some ", {text: "string", style: {font_size: 20}}])
|
|
306
|
+
#
|
|
307
|
+
# See: #text_box, HexaPDF::Layout::TextBox, HexaPDF::Layout::TextFragment
|
|
308
|
+
def formatted_text_box(data, width: 0, height: 0, style: nil, box_style: nil, **style_properties)
|
|
309
|
+
style = retrieve_style(style, style_properties)
|
|
310
|
+
box_style = (box_style ? retrieve_style(box_style) : style)
|
|
311
|
+
data.map! do |hash|
|
|
312
|
+
if hash.kind_of?(String)
|
|
313
|
+
HexaPDF::Layout::TextFragment.create(hash, style)
|
|
314
|
+
else
|
|
315
|
+
link = hash.delete(:link)
|
|
316
|
+
(hash[:overlays] ||= []) << [:link, {uri: link}] if link
|
|
317
|
+
text = hash.delete(:text) || link || ""
|
|
318
|
+
HexaPDF::Layout::TextFragment.create(text, retrieve_style(hash.delete(:style) || style, hash))
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
box_class_for_name(:text).new(items: data, width: width, height: height, style: box_style)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Creates a HexaPDF::Layout::ImageBox for the given image.
|
|
325
|
+
#
|
|
326
|
+
# The +file+ argument can be anything that is accepted by HexaPDF::Document::Images#add or a
|
|
327
|
+
# HexaPDF::Type::Form object.
|
|
328
|
+
#
|
|
329
|
+
# See #text_box for details on +width+, +height+, +style+ and +style_properties+.
|
|
330
|
+
#
|
|
331
|
+
# Examples:
|
|
332
|
+
#
|
|
333
|
+
# layout.image_box(machu_picchu, border: {width: 3})
|
|
334
|
+
# layout.image_box(machu_picchu, height: 30)
|
|
335
|
+
#
|
|
336
|
+
# See: HexaPDF::Layout::ImageBox
|
|
337
|
+
def image_box(file, width: 0, height: 0, style: nil, **style_properties)
|
|
338
|
+
style = retrieve_style(style, style_properties)
|
|
339
|
+
image = file.kind_of?(HexaPDF::Stream) ? file : @document.images.add(file)
|
|
340
|
+
box_class_for_name(:image).new(image: image, width: width, height: height, style: style)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# :nodoc:
|
|
344
|
+
LOREM_IPSUM = [
|
|
345
|
+
"Lorem ipsum dolor sit amet, con\u{00AD}sectetur adipis\u{00AD}cing elit, sed " \
|
|
346
|
+
"do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
347
|
+
"Ut enim ad minim veniam, quis nostrud exer\u{00AD}citation ullamco laboris nisi ut " \
|
|
348
|
+
"aliquip ex ea commodo consequat. ",
|
|
349
|
+
"Duis aute irure dolor in reprehen\u{00AD}derit in voluptate velit esse cillum dolore " \
|
|
350
|
+
"eu fugiat nulla pariatur. ",
|
|
351
|
+
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " \
|
|
352
|
+
"mollit anim id est laborum.",
|
|
353
|
+
]
|
|
354
|
+
|
|
355
|
+
# Uses #text_box to create +count+ paragraphs of lorem ipsum text.
|
|
356
|
+
#
|
|
357
|
+
# The +text_box_properties+ arguments are passed as is to #text_box.
|
|
358
|
+
def lorem_ipsum_box(sentences: 4, count: 1, **text_box_properties)
|
|
359
|
+
text_box(([LOREM_IPSUM[0, sentences].join(" ")] * count).join("\n\n"), **text_box_properties)
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
private
|
|
363
|
+
|
|
364
|
+
# Returns the configured box class for the given +name+.
|
|
365
|
+
def box_class_for_name(name)
|
|
366
|
+
@document.config.constantize('layout.boxes.map', name) do
|
|
367
|
+
raise HexaPDF::Error, "Couldn't retrieve box class #{name} from configuration"
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Retrieves the appropriate HexaPDF::Layout::Style object based on the +style+ and +properties+
|
|
372
|
+
# arguments.
|
|
373
|
+
#
|
|
374
|
+
# The +style+ argument specifies the style to retrieve. It can either be a registered style
|
|
375
|
+
# name (see #style), a hash with style properties or +nil+. In the latter case the registered
|
|
376
|
+
# style :base is used
|
|
377
|
+
#
|
|
378
|
+
# If the +properties+ hash is not empty, the retrieved style is duplicated and the properties
|
|
379
|
+
# hash is applied to it.
|
|
380
|
+
#
|
|
381
|
+
# Finally, a default font is set if necessary to ensure that the style object works in all
|
|
382
|
+
# cases.
|
|
383
|
+
def retrieve_style(style, properties = nil)
|
|
384
|
+
style = HexaPDF::Layout::Style.create(@styles[style] || style || @styles[:base])
|
|
385
|
+
style = style.dup.update(**properties) unless properties.nil? || properties.empty?
|
|
386
|
+
style.font('Times') unless style.font?
|
|
387
|
+
unless style.font.respond_to?(:pdf_object)
|
|
388
|
+
name, options = *style.font
|
|
389
|
+
style.font(@document.fonts.add(name, **(options || {})))
|
|
390
|
+
end
|
|
391
|
+
style
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
end
|
|
397
|
+
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
|
|
@@ -101,6 +101,22 @@ module HexaPDF
|
|
|
101
101
|
@document.catalog.pages.insert_page(index, page)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
+
# :call-seq:
|
|
105
|
+
# pages.move(page, to_index)
|
|
106
|
+
# pages.move(index, to_index)
|
|
107
|
+
#
|
|
108
|
+
# Moves the given page or the page at the position specified by the zero-based index to the
|
|
109
|
+
# +to_index+ position.
|
|
110
|
+
#
|
|
111
|
+
# If the page that should be moved, doesn't exist or is invalid, an error is raised.
|
|
112
|
+
#
|
|
113
|
+
# Negative indices count backwards from the end, i.e. -1 is the last page. When using a
|
|
114
|
+
# negative index, the page will be moved after that element. So using an index of -1 will
|
|
115
|
+
# move the page after the last page.
|
|
116
|
+
def move(page, to_index)
|
|
117
|
+
@document.catalog.pages.move_page(page, to_index)
|
|
118
|
+
end
|
|
119
|
+
|
|
104
120
|
# Deletes the given page object from the document's page tree and the document.
|
|
105
121
|
#
|
|
106
122
|
# Also see: HexaPDF::Type::PageTreeNode#delete_page
|
|
@@ -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
|
|
@@ -239,7 +239,7 @@ module HexaPDF
|
|
|
239
239
|
signature[:M] = Time.now
|
|
240
240
|
|
|
241
241
|
io = if file_or_io.kind_of?(String)
|
|
242
|
-
File.open(file_or_io, '
|
|
242
|
+
File.open(file_or_io, 'wb+')
|
|
243
243
|
else
|
|
244
244
|
file_or_io
|
|
245
245
|
end
|
|
@@ -247,8 +247,9 @@ module HexaPDF
|
|
|
247
247
|
# Save the current state so that we can determine the correct /ByteRange value and set the
|
|
248
248
|
# values
|
|
249
249
|
handler.finalize_objects(signature_field, signature)
|
|
250
|
-
section = @document.write(io, incremental: true, **write_options)
|
|
251
|
-
data = section.map {|oid, _gen, entry| [entry.pos, oid] if entry.in_use? }.compact.sort
|
|
250
|
+
start_xref_position, section = @document.write(io, incremental: true, **write_options)
|
|
251
|
+
data = section.map {|oid, _gen, entry| [entry.pos, oid] if entry.in_use? }.compact.sort <<
|
|
252
|
+
[start_xref_position, nil]
|
|
252
253
|
index = data.index {|_pos, oid| oid == signature.oid }
|
|
253
254
|
signature_offset = data[index][0]
|
|
254
255
|
signature_length = data[index + 1][0] - data[index][0]
|
data/lib/hexapdf/document.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
|
|
@@ -107,6 +107,7 @@ module HexaPDF
|
|
|
107
107
|
autoload(:Files, 'hexapdf/document/files')
|
|
108
108
|
autoload(:Signatures, 'hexapdf/document/signatures')
|
|
109
109
|
autoload(:Destinations, 'hexapdf/document/destinations')
|
|
110
|
+
autoload(:Layout, 'hexapdf/document/layout')
|
|
110
111
|
|
|
111
112
|
# :call-seq:
|
|
112
113
|
# Document.open(filename, **docargs) -> doc
|
|
@@ -478,6 +479,12 @@ module HexaPDF
|
|
|
478
479
|
@destinations ||= Destinations.new(self)
|
|
479
480
|
end
|
|
480
481
|
|
|
482
|
+
# Returns the Layout object that provides convenience methods for working with the
|
|
483
|
+
# HexaPDF::Layout classes for document layout.
|
|
484
|
+
def layout
|
|
485
|
+
@layout ||= Layout.new(self)
|
|
486
|
+
end
|
|
487
|
+
|
|
481
488
|
# Returns the main AcroForm object for dealing with interactive forms.
|
|
482
489
|
#
|
|
483
490
|
# See HexaPDF::Type::Catalog#acro_form for details on the arguments.
|
|
@@ -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
|
|
@@ -40,30 +40,39 @@ require 'hexapdf/encryption/arc4'
|
|
|
40
40
|
module HexaPDF
|
|
41
41
|
module Encryption
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# See: PDF1.7 s7.6.2
|
|
46
|
-
class FastARC4
|
|
43
|
+
begin
|
|
44
|
+
OpenSSL::Cipher.new('rc4')
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
# Implementation of the general encryption algorithm ARC4 using OpenSSL as backend.
|
|
47
|
+
#
|
|
48
|
+
# See: PDF1.7 s7.6.2
|
|
49
|
+
class FastARC4
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
def initialize(key)
|
|
52
|
-
@cipher = OpenSSL::Cipher.new('rc4')
|
|
53
|
-
@cipher.key_len = key.length
|
|
54
|
-
@cipher.key = key
|
|
55
|
-
end
|
|
51
|
+
prepend ARC4
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
53
|
+
# Creates a new FastARC4 object using the given encryption key.
|
|
54
|
+
def initialize(key)
|
|
55
|
+
@cipher = OpenSSL::Cipher.new('rc4')
|
|
56
|
+
@cipher.key_len = key.length
|
|
57
|
+
@cipher.key = key
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Processes the given data.
|
|
61
|
+
#
|
|
62
|
+
# Since this is a symmetric algorithm, the same method can be used for encryption and
|
|
63
|
+
# decryption.
|
|
64
|
+
def process(data)
|
|
65
|
+
@cipher.update(data)
|
|
66
|
+
end
|
|
67
|
+
alias decrypt process
|
|
68
|
+
alias encrypt process
|
|
66
69
|
|
|
70
|
+
end
|
|
71
|
+
rescue OpenSSL::Cipher::CipherError
|
|
72
|
+
# Ruby OpenSSL 3.0 needs a special configuration file that enables the legacy provider so that
|
|
73
|
+
# RC4 works. This would need to be done by each user. So we need the fallback.
|
|
74
|
+
require 'hexapdf/encryption/ruby_arc4'
|
|
75
|
+
FastARC4 = RubyARC4
|
|
67
76
|
end
|
|
68
77
|
|
|
69
78
|
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
|
|
@@ -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/encryption.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/error.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
|