hexapdf 0.17.1 → 0.17.2
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 +1024 -0
- data/LICENSE +29 -0
- data/README.md +129 -0
- data/Rakefile +109 -0
- data/agpl-3.0.txt +661 -0
- data/examples/001-hello_world.rb +16 -0
- data/examples/002-graphics.rb +275 -0
- data/examples/003-arcs.rb +50 -0
- data/examples/004-optimizing.rb +23 -0
- data/examples/005-merging.rb +27 -0
- data/examples/006-standard_pdf_fonts.rb +73 -0
- data/examples/007-truetype.rb +42 -0
- data/examples/008-show_char_bboxes.rb +55 -0
- data/examples/009-text_layouter_alignment.rb +47 -0
- data/examples/010-text_layouter_inline_boxes.rb +64 -0
- data/examples/011-text_layouter_line_wrapping.rb +57 -0
- data/examples/012-text_layouter_styling.rb +122 -0
- data/examples/013-text_layouter_shapes.rb +176 -0
- data/examples/014-text_in_polygon.rb +60 -0
- data/examples/015-boxes.rb +76 -0
- data/examples/016-frame_automatic_box_placement.rb +90 -0
- data/examples/017-frame_text_flow.rb +60 -0
- data/examples/018-composer.rb +44 -0
- data/examples/019-acro_form.rb +88 -0
- data/examples/emoji-smile.png +0 -0
- data/examples/emoji-wink.png +0 -0
- data/examples/machupicchu.jpg +0 -0
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -0
- data/lib/hexapdf/content/graphic_object/geom2d.rb +13 -0
- data/lib/hexapdf/version.rb +1 -1
- data/test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz +0 -0
- data/test/data/fonts/Ubuntu-Title.ttf +0 -0
- data/test/data/images/cmyk.jpg +0 -0
- data/test/data/images/fillbytes.jpg +0 -0
- data/test/data/images/gray.jpg +0 -0
- data/test/data/images/greyscale-1bit.png +0 -0
- data/test/data/images/greyscale-2bit.png +0 -0
- data/test/data/images/greyscale-4bit.png +0 -0
- data/test/data/images/greyscale-8bit.png +0 -0
- data/test/data/images/greyscale-alpha-8bit.png +0 -0
- data/test/data/images/greyscale-trns-8bit.png +0 -0
- data/test/data/images/greyscale-with-gamma1.0.png +0 -0
- data/test/data/images/greyscale-with-gamma1.5.png +0 -0
- data/test/data/images/indexed-1bit.png +0 -0
- data/test/data/images/indexed-2bit.png +0 -0
- data/test/data/images/indexed-4bit.png +0 -0
- data/test/data/images/indexed-8bit.png +0 -0
- data/test/data/images/indexed-alpha-4bit.png +0 -0
- data/test/data/images/indexed-alpha-8bit.png +0 -0
- data/test/data/images/rgb.jpg +0 -0
- data/test/data/images/truecolour-8bit.png +0 -0
- data/test/data/images/truecolour-alpha-8bit.png +0 -0
- data/test/data/images/truecolour-gama-chrm-8bit.png +0 -0
- data/test/data/images/truecolour-srgb-8bit.png +0 -0
- data/test/data/images/ycck.jpg +0 -0
- data/test/data/minimal.pdf +44 -0
- data/test/data/standard-security-handler/README +9 -0
- data/test/data/standard-security-handler/bothpwd-aes-128bit-V4.pdf +44 -0
- data/test/data/standard-security-handler/bothpwd-aes-256bit-V5.pdf +0 -0
- data/test/data/standard-security-handler/bothpwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/bothpwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/bothpwd-arc4-40bit-V1.pdf +0 -0
- data/test/data/standard-security-handler/nopwd-aes-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-aes-256bit-V5.pdf +0 -0
- data/test/data/standard-security-handler/nopwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-arc4-40bit-V1.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-aes-128bit-V4.pdf +0 -0
- data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-40bit-V1.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-256bit-V5.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-arc4-128bit-V2.pdf +0 -0
- data/test/data/standard-security-handler/userpwd-arc4-128bit-V4.pdf +0 -0
- data/test/data/standard-security-handler/userpwd-arc4-40bit-V1.pdf +43 -0
- data/test/hexapdf/common_tokenizer_tests.rb +236 -0
- data/test/hexapdf/content/common.rb +39 -0
- data/test/hexapdf/content/graphic_object/test_arc.rb +102 -0
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +90 -0
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +79 -0
- data/test/hexapdf/content/graphic_object/test_solid_arc.rb +86 -0
- data/test/hexapdf/content/test_canvas.rb +1279 -0
- data/test/hexapdf/content/test_color_space.rb +176 -0
- data/test/hexapdf/content/test_graphics_state.rb +151 -0
- data/test/hexapdf/content/test_operator.rb +619 -0
- data/test/hexapdf/content/test_parser.rb +99 -0
- data/test/hexapdf/content/test_processor.rb +163 -0
- data/test/hexapdf/content/test_transformation_matrix.rb +64 -0
- data/test/hexapdf/document/test_files.rb +72 -0
- data/test/hexapdf/document/test_fonts.rb +60 -0
- data/test/hexapdf/document/test_images.rb +72 -0
- data/test/hexapdf/document/test_pages.rb +130 -0
- data/test/hexapdf/encryption/common.rb +87 -0
- data/test/hexapdf/encryption/test_aes.rb +129 -0
- data/test/hexapdf/encryption/test_arc4.rb +39 -0
- data/test/hexapdf/encryption/test_fast_aes.rb +17 -0
- data/test/hexapdf/encryption/test_fast_arc4.rb +12 -0
- data/test/hexapdf/encryption/test_identity.rb +21 -0
- data/test/hexapdf/encryption/test_ruby_aes.rb +23 -0
- data/test/hexapdf/encryption/test_ruby_arc4.rb +20 -0
- data/test/hexapdf/encryption/test_security_handler.rb +380 -0
- data/test/hexapdf/encryption/test_standard_security_handler.rb +322 -0
- data/test/hexapdf/filter/common.rb +53 -0
- data/test/hexapdf/filter/test_ascii85_decode.rb +59 -0
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +38 -0
- data/test/hexapdf/filter/test_crypt.rb +21 -0
- data/test/hexapdf/filter/test_encryption.rb +24 -0
- data/test/hexapdf/filter/test_flate_decode.rb +44 -0
- data/test/hexapdf/filter/test_lzw_decode.rb +52 -0
- data/test/hexapdf/filter/test_predictor.rb +219 -0
- data/test/hexapdf/filter/test_run_length_decode.rb +32 -0
- data/test/hexapdf/font/cmap/test_parser.rb +102 -0
- data/test/hexapdf/font/cmap/test_writer.rb +66 -0
- data/test/hexapdf/font/encoding/test_base.rb +45 -0
- data/test/hexapdf/font/encoding/test_difference_encoding.rb +29 -0
- data/test/hexapdf/font/encoding/test_glyph_list.rb +59 -0
- data/test/hexapdf/font/encoding/test_zapf_dingbats_encoding.rb +16 -0
- data/test/hexapdf/font/test_cmap.rb +104 -0
- data/test/hexapdf/font/test_encoding.rb +27 -0
- data/test/hexapdf/font/test_invalid_glyph.rb +34 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +186 -0
- data/test/hexapdf/font/test_type1_wrapper.rb +107 -0
- data/test/hexapdf/font/true_type/common.rb +17 -0
- data/test/hexapdf/font/true_type/table/common.rb +27 -0
- data/test/hexapdf/font/true_type/table/test_cmap.rb +47 -0
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +141 -0
- data/test/hexapdf/font/true_type/table/test_directory.rb +30 -0
- data/test/hexapdf/font/true_type/table/test_glyf.rb +58 -0
- data/test/hexapdf/font/true_type/table/test_head.rb +56 -0
- data/test/hexapdf/font/true_type/table/test_hhea.rb +26 -0
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +30 -0
- data/test/hexapdf/font/true_type/table/test_kern.rb +61 -0
- data/test/hexapdf/font/true_type/table/test_loca.rb +33 -0
- data/test/hexapdf/font/true_type/table/test_maxp.rb +50 -0
- data/test/hexapdf/font/true_type/table/test_name.rb +76 -0
- data/test/hexapdf/font/true_type/table/test_os2.rb +55 -0
- data/test/hexapdf/font/true_type/table/test_post.rb +78 -0
- data/test/hexapdf/font/true_type/test_builder.rb +42 -0
- data/test/hexapdf/font/true_type/test_font.rb +116 -0
- data/test/hexapdf/font/true_type/test_optimizer.rb +26 -0
- data/test/hexapdf/font/true_type/test_subsetter.rb +73 -0
- data/test/hexapdf/font/true_type/test_table.rb +48 -0
- data/test/hexapdf/font/type1/common.rb +6 -0
- data/test/hexapdf/font/type1/test_afm_parser.rb +65 -0
- data/test/hexapdf/font/type1/test_font.rb +104 -0
- data/test/hexapdf/font/type1/test_font_metrics.rb +22 -0
- data/test/hexapdf/font/type1/test_pfb_parser.rb +37 -0
- data/test/hexapdf/font_loader/test_from_configuration.rb +43 -0
- data/test/hexapdf/font_loader/test_from_file.rb +36 -0
- data/test/hexapdf/font_loader/test_standard14.rb +33 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +93 -0
- data/test/hexapdf/image_loader/test_pdf.rb +47 -0
- data/test/hexapdf/image_loader/test_png.rb +259 -0
- data/test/hexapdf/layout/test_box.rb +154 -0
- data/test/hexapdf/layout/test_frame.rb +350 -0
- data/test/hexapdf/layout/test_image_box.rb +73 -0
- data/test/hexapdf/layout/test_inline_box.rb +71 -0
- data/test/hexapdf/layout/test_line.rb +206 -0
- data/test/hexapdf/layout/test_style.rb +790 -0
- data/test/hexapdf/layout/test_text_box.rb +140 -0
- data/test/hexapdf/layout/test_text_fragment.rb +375 -0
- data/test/hexapdf/layout/test_text_layouter.rb +758 -0
- data/test/hexapdf/layout/test_text_shaper.rb +62 -0
- data/test/hexapdf/layout/test_width_from_polygon.rb +109 -0
- data/test/hexapdf/task/test_dereference.rb +51 -0
- data/test/hexapdf/task/test_optimize.rb +162 -0
- data/test/hexapdf/test_composer.rb +258 -0
- data/test/hexapdf/test_configuration.rb +93 -0
- data/test/hexapdf/test_data_dir.rb +32 -0
- data/test/hexapdf/test_dictionary.rb +340 -0
- data/test/hexapdf/test_dictionary_fields.rb +269 -0
- data/test/hexapdf/test_document.rb +641 -0
- data/test/hexapdf/test_filter.rb +100 -0
- data/test/hexapdf/test_importer.rb +106 -0
- data/test/hexapdf/test_object.rb +258 -0
- data/test/hexapdf/test_parser.rb +645 -0
- data/test/hexapdf/test_pdf_array.rb +169 -0
- data/test/hexapdf/test_rectangle.rb +73 -0
- data/test/hexapdf/test_reference.rb +50 -0
- data/test/hexapdf/test_revision.rb +188 -0
- data/test/hexapdf/test_revisions.rb +196 -0
- data/test/hexapdf/test_serializer.rb +195 -0
- data/test/hexapdf/test_stream.rb +274 -0
- data/test/hexapdf/test_tokenizer.rb +80 -0
- data/test/hexapdf/test_type.rb +18 -0
- data/test/hexapdf/test_writer.rb +140 -0
- data/test/hexapdf/test_xref_section.rb +61 -0
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +795 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +308 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +220 -0
- data/test/hexapdf/type/acro_form/test_field.rb +259 -0
- data/test/hexapdf/type/acro_form/test_form.rb +357 -0
- data/test/hexapdf/type/acro_form/test_signature_field.rb +38 -0
- data/test/hexapdf/type/acro_form/test_text_field.rb +201 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +88 -0
- data/test/hexapdf/type/actions/test_launch.rb +24 -0
- data/test/hexapdf/type/actions/test_uri.rb +23 -0
- data/test/hexapdf/type/annotations/test_markup_annotation.rb +22 -0
- data/test/hexapdf/type/annotations/test_text.rb +34 -0
- data/test/hexapdf/type/annotations/test_widget.rb +225 -0
- data/test/hexapdf/type/test_annotation.rb +97 -0
- data/test/hexapdf/type/test_catalog.rb +48 -0
- data/test/hexapdf/type/test_cid_font.rb +61 -0
- data/test/hexapdf/type/test_file_specification.rb +141 -0
- data/test/hexapdf/type/test_font.rb +67 -0
- data/test/hexapdf/type/test_font_descriptor.rb +61 -0
- data/test/hexapdf/type/test_font_simple.rb +176 -0
- data/test/hexapdf/type/test_font_true_type.rb +31 -0
- data/test/hexapdf/type/test_font_type0.rb +120 -0
- data/test/hexapdf/type/test_font_type1.rb +142 -0
- data/test/hexapdf/type/test_font_type3.rb +26 -0
- data/test/hexapdf/type/test_form.rb +120 -0
- data/test/hexapdf/type/test_image.rb +261 -0
- data/test/hexapdf/type/test_info.rb +9 -0
- data/test/hexapdf/type/test_object_stream.rb +117 -0
- data/test/hexapdf/type/test_page.rb +598 -0
- data/test/hexapdf/type/test_page_tree_node.rb +315 -0
- data/test/hexapdf/type/test_resources.rb +209 -0
- data/test/hexapdf/type/test_trailer.rb +116 -0
- data/test/hexapdf/type/test_xref_stream.rb +143 -0
- data/test/hexapdf/utils/test_bit_field.rb +63 -0
- data/test/hexapdf/utils/test_bit_stream.rb +69 -0
- data/test/hexapdf/utils/test_graphics_helpers.rb +37 -0
- data/test/hexapdf/utils/test_lru_cache.rb +22 -0
- data/test/hexapdf/utils/test_object_hash.rb +120 -0
- data/test/hexapdf/utils/test_pdf_doc_encoding.rb +18 -0
- data/test/hexapdf/utils/test_sorted_tree_node.rb +239 -0
- data/test/test_helper.rb +58 -0
- metadata +263 -3
data/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
2
|
+
Copyright (C) 2014-2021 Thomas Leitner
|
|
3
|
+
|
|
4
|
+
HexaPDF is free software: you can redistribute it and/or modify it
|
|
5
|
+
under the terms of the GNU Affero General Public License version 3 as
|
|
6
|
+
published by the Free Software Foundation with the addition of the
|
|
7
|
+
following permission added to Section 15 as permitted in Section 7(a):
|
|
8
|
+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
|
9
|
+
THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
|
|
10
|
+
INFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
11
|
+
|
|
12
|
+
HexaPDF is distributed in the hope that it will be useful, but WITHOUT
|
|
13
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14
|
+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
15
|
+
License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU Affero General Public License
|
|
18
|
+
along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
|
|
20
|
+
The interactive user interfaces in modified source and object code
|
|
21
|
+
versions of HexaPDF must display Appropriate Legal Notices, as required
|
|
22
|
+
under Section 5 of the GNU Affero General Public License version 3.
|
|
23
|
+
|
|
24
|
+
In accordance with Section 7(b) of the GNU Affero General Public
|
|
25
|
+
License, a covered work must retain the producer line in every PDF that
|
|
26
|
+
is created or manipulated using HexaPDF.
|
|
27
|
+
|
|
28
|
+
If the GNU Affero General Public License doesn't fit your need,
|
|
29
|
+
commercial licenses are available at <https://gettalong.at/hexapdf/>.
|
data/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
2
|
+
|
|
3
|
+
HexaPDF is a pure Ruby library with an accompanying application for working with PDF files. In
|
|
4
|
+
short, it allows
|
|
5
|
+
|
|
6
|
+
* **creating** new PDF files,
|
|
7
|
+
* **manipulating** existing PDF files,
|
|
8
|
+
* **merging** multiple PDF files into one,
|
|
9
|
+
* **extracting** meta information, text, images and files from PDF files,
|
|
10
|
+
* **securing** PDF files by encrypting them and
|
|
11
|
+
* **optimizing** PDF files for smaller file size or other criteria.
|
|
12
|
+
|
|
13
|
+
HexaPDF was designed with ease of use and performance in mind. It uses lazy loading and lazy
|
|
14
|
+
computing when possible and tries to produce small PDF files by default.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
The HexaPDF distribution provides the library as well as the `hexapdf` application. The application
|
|
20
|
+
can be used to perform common tasks like merging PDF files, decrypting or encrypting PDF files and
|
|
21
|
+
so on.
|
|
22
|
+
|
|
23
|
+
When HexaPDF is used as a library, it can be used to do all the task that the command line
|
|
24
|
+
application does and much more. Here is a "Hello World" example that shows how to create a simple
|
|
25
|
+
PDF file:
|
|
26
|
+
|
|
27
|
+
~~~ ruby
|
|
28
|
+
require 'hexapdf'
|
|
29
|
+
|
|
30
|
+
doc = HexaPDF::Document.new
|
|
31
|
+
canvas = doc.pages.add.canvas
|
|
32
|
+
canvas.font('Helvetica', size: 100)
|
|
33
|
+
canvas.text("Hello World!", at: [20, 400])
|
|
34
|
+
doc.write("hello-world.pdf")
|
|
35
|
+
~~~
|
|
36
|
+
|
|
37
|
+
For detailed information have a look at the [HexaPDF website][website] where you will the API
|
|
38
|
+
documentation, example code and more.
|
|
39
|
+
|
|
40
|
+
It is recommend to use the HTML API documentation provided by the HexaPDF website as it is enhanced
|
|
41
|
+
with example graphics and PDF files and tightly integrated into the rest of the website.
|
|
42
|
+
|
|
43
|
+
[website]: http://hexapdf.gettalong.org
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## Requirements and Installation
|
|
47
|
+
|
|
48
|
+
Since HexaPDF is written in Ruby, a working Ruby installation is needed - see the
|
|
49
|
+
[official installation documentation][rbinstall] for details. Note that you need Ruby version 2.4 or
|
|
50
|
+
higher as prior versions are not supported!
|
|
51
|
+
|
|
52
|
+
Apart from Ruby itself the HexaPDF library has only one external dependency `geom2d` which is
|
|
53
|
+
written and provided by the HexaPDF authors. The `hexapdf` application has an additional dependency
|
|
54
|
+
on `cmdparse`, a command line parsing library.
|
|
55
|
+
|
|
56
|
+
HexaPDF itself is distributed via Rubygems and therefore easily installable via `gem install
|
|
57
|
+
hexapdf`.
|
|
58
|
+
|
|
59
|
+
[rbinstall]: https://www.ruby-lang.org/en/documentation/installation/
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Difference to Prawn
|
|
63
|
+
|
|
64
|
+
The main difference between HexaPDF and [Prawn] is that HexaPDF is a **full PDF library** whereas
|
|
65
|
+
Prawn is a **library for generating content**.
|
|
66
|
+
|
|
67
|
+
To be more specific, it is easily possible to read an existing PDF with HexaPDF and modify parts of
|
|
68
|
+
it before writing it out again. The modifications can be to the PDF object structure like removing
|
|
69
|
+
superfluous annotations or the the content itself.
|
|
70
|
+
|
|
71
|
+
Prawn has no such functionality. There is basic support for using a PDF as a template using the
|
|
72
|
+
`pdf-reader` and `prawn-template` gems but support is very limited. However, Prawn has a very
|
|
73
|
+
featureful API when it comes to creating content, for individual pages as well as across pages.
|
|
74
|
+
|
|
75
|
+
Such functionality will be incorporated into HexaPDF in the near future. The main functionality for
|
|
76
|
+
providing such a feature is already available in HexaPDF (the [page canvas API]). Additionally,
|
|
77
|
+
laying out text inside a box with line wrapping and such is also supported. What's missing (and this
|
|
78
|
+
is still quite a big chunk) is support for advanced features like tables, page breaking and so on.
|
|
79
|
+
|
|
80
|
+
So why use HexaPDF?
|
|
81
|
+
|
|
82
|
+
* The architecture of HexaPDF is based on the object model of the PDF standard. This makes extending
|
|
83
|
+
HexaPDF very easy and allows for **reading PDF files for templating purposes**.
|
|
84
|
+
|
|
85
|
+
* HexaPDF will provide a high level layer for **composing a document of individual elements** that
|
|
86
|
+
are automatically layouted. Such elements can be headers, paragraphs, code blocks, ... or links,
|
|
87
|
+
emphasized text and so on. These elements can be customized and additional element types easily
|
|
88
|
+
added.
|
|
89
|
+
|
|
90
|
+
* In addition to being usable as a library, HexaPDF also comes with a command line tool for
|
|
91
|
+
manipulating PDFs. This tool is intended to be a replacement for tools like `pdftk` and the
|
|
92
|
+
various Poppler-based tools like `pdfinfo`, `pdfimages`, ...
|
|
93
|
+
|
|
94
|
+
[Prawn]: http://prawnpdf.org
|
|
95
|
+
[page canvas API]: https://hexapdf.gettalong.org/api/HexaPDF/Content/Canvas.html
|
|
96
|
+
|
|
97
|
+
## Development
|
|
98
|
+
|
|
99
|
+
Clone the repository and then run `rake dev:setup`. This will install the needed Rubygem
|
|
100
|
+
dependencies as well as make sure that all applications needed for the tests are available.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
AGPL - see the LICENSE file for licensing details. Commercial licenses are available at
|
|
106
|
+
<https://gettalong.at/hexapdf/>.
|
|
107
|
+
|
|
108
|
+
Some included files have a different license:
|
|
109
|
+
|
|
110
|
+
* For the license of the included AFM files in the `data/hexapdf/afm` directory, see the file
|
|
111
|
+
`data/hexapdf/afm/MustRead.html`.
|
|
112
|
+
|
|
113
|
+
* The files `test/data/encoding/{glyphlist.txt,zapfdingbats.txt}` are licensed under the Apache
|
|
114
|
+
License V2.0.
|
|
115
|
+
|
|
116
|
+
* The file `test/data/fonts/Ubuntu-Title.ttf` is licensed under the SIL Open Font License.
|
|
117
|
+
|
|
118
|
+
* The AES test vector files in `test/data/aes-test-vectors` have been created using the test vector
|
|
119
|
+
file available from <http://csrc.nist.gov/groups/STM/cavp/block-ciphers.html#test-vectors>.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## Contributing
|
|
123
|
+
|
|
124
|
+
See <http://hexapdf.gettalong.org/contributing.html> for more information.
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
## Author
|
|
128
|
+
|
|
129
|
+
Thomas Leitner, <http://gettalong.org>
|
data/Rakefile
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
require 'rake/clean'
|
|
4
|
+
require 'rubygems/package_task'
|
|
5
|
+
|
|
6
|
+
require_relative 'lib/hexapdf/version'
|
|
7
|
+
|
|
8
|
+
Rake::TestTask.new do |t|
|
|
9
|
+
t.libs << 'test'
|
|
10
|
+
t.test_files = FileList['test/**/*.rb']
|
|
11
|
+
t.verbose = false
|
|
12
|
+
t.warning = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
namespace :dev do
|
|
16
|
+
CLOBBER << "man/man1/hexapdf.1"
|
|
17
|
+
file 'man/man1/hexapdf.1' => ['man/man1/hexapdf.1.md'] do
|
|
18
|
+
puts "Generating hexapdf man page"
|
|
19
|
+
system "kramdown -o man man/man1/hexapdf.1.md > man/man1/hexapdf.1"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
CLOBBER << "VERSION"
|
|
23
|
+
file 'VERSION' do
|
|
24
|
+
puts "Generating VERSION file"
|
|
25
|
+
File.open('VERSION', 'w+') {|file| file.write(HexaPDF::VERSION + "\n") }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
CLOBBER << 'CONTRIBUTERS'
|
|
29
|
+
file 'CONTRIBUTERS' do
|
|
30
|
+
puts "Generating CONTRIBUTERS file"
|
|
31
|
+
`echo " Count Name" > CONTRIBUTERS`
|
|
32
|
+
`echo "======= ====" >> CONTRIBUTERS`
|
|
33
|
+
`git log | grep ^Author: | sed 's/^Author: //' | sort | uniq -c | sort -nr >> CONTRIBUTERS`
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
ENV['REAL_GEM'] = "true"
|
|
37
|
+
spec = eval(File.read('hexapdf.gemspec'), binding, 'hexapdf.gemspec')
|
|
38
|
+
Gem::PackageTask.new(spec) do |pkg|
|
|
39
|
+
pkg.need_zip = true
|
|
40
|
+
pkg.need_tar = true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc "Upload the release to Rubygems"
|
|
44
|
+
task publish_files: [:package] do
|
|
45
|
+
sh "gem push pkg/hexapdf-#{HexaPDF::VERSION}.gem"
|
|
46
|
+
puts 'done'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
desc 'Release HexaPDF version ' + HexaPDF::VERSION
|
|
50
|
+
task release: [:clobber, :package, :publish_files]
|
|
51
|
+
|
|
52
|
+
desc "Set-up everything for development"
|
|
53
|
+
task :setup do
|
|
54
|
+
puts "Installing required runtime and development gems:"
|
|
55
|
+
resolver = Gem::Resolver.for_current_gems(spec.dependencies)
|
|
56
|
+
resolver.ignore_dependencies = true
|
|
57
|
+
resolver.soft_missing = true
|
|
58
|
+
resolver.resolve
|
|
59
|
+
spec.dependencies.each do |dependency|
|
|
60
|
+
if resolver.missing.find {|dep_request| dep_request.dependency == dependency }
|
|
61
|
+
print "✗ #{dependency.name} - installing it..."
|
|
62
|
+
Gem.install(dependency.name, dependency.requirement, prerelease: true)
|
|
63
|
+
puts " done"
|
|
64
|
+
else
|
|
65
|
+
puts "✓ #{dependency.name}"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
puts
|
|
70
|
+
puts "The following binaries are needed for the tests:"
|
|
71
|
+
{
|
|
72
|
+
'pngtopnm' => 'sudo apt install netpbm',
|
|
73
|
+
'pngcheck' => 'sudo apt install pngcheck',
|
|
74
|
+
}.each do |name, install_command|
|
|
75
|
+
`which #{name} 2>&1`
|
|
76
|
+
if $?.exitstatus == 0
|
|
77
|
+
puts "✓ #{name}"
|
|
78
|
+
else
|
|
79
|
+
puts "✗ #{name} (#{install_command})"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
CODING_LINE = "# -*- encoding: utf-8; frozen_string_literal: true -*-\n"
|
|
85
|
+
|
|
86
|
+
desc "Insert/Update copyright notice"
|
|
87
|
+
task :update_copyright do
|
|
88
|
+
license = File.readlines(File.join(__dir__, 'LICENSE')).map do |l|
|
|
89
|
+
l.strip.empty? ? "#\n" : "# #{l}"
|
|
90
|
+
end.join
|
|
91
|
+
statement = CODING_LINE + "#\n#--\n# This file is part of HexaPDF.\n#\n" + license + "#++\n"
|
|
92
|
+
inserted = false
|
|
93
|
+
Dir["lib/**/*.rb"].each do |file|
|
|
94
|
+
unless File.read(file).start_with?(statement)
|
|
95
|
+
inserted = true
|
|
96
|
+
puts "Updating file #{file}"
|
|
97
|
+
old = File.read(file)
|
|
98
|
+
unless old.gsub!(/\A#{Regexp.escape(CODING_LINE)}#\n#--.*?\n#\+\+\n/m, statement)
|
|
99
|
+
old.gsub!(/\A(#{Regexp.escape(CODING_LINE)})?/, statement)
|
|
100
|
+
end
|
|
101
|
+
File.write(file, old)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
puts "Look through the above mentioned files and correct all problems" if inserted
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
task clobber: 'dev:clobber'
|
|
109
|
+
task default: 'test'
|