hexapdf 0.30.0 → 0.32.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 +54 -1
- data/LICENSE +1 -1
- data/examples/020-column_box.rb +10 -11
- data/examples/021-list_box.rb +5 -5
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +17 -2
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +1 -1
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +10 -2
- data/lib/hexapdf/cli/inspect.rb +3 -3
- 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 +97 -29
- data/lib/hexapdf/configuration.rb +18 -5
- 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 +1 -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/digital_signature/cms_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signature.rb +1 -1
- data/lib/hexapdf/digital_signature/signatures.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing.rb +1 -1
- data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
- data/lib/hexapdf/digital_signature.rb +1 -1
- data/lib/hexapdf/document/destinations.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 +122 -39
- data/lib/hexapdf/document/pages.rb +2 -6
- data/lib/hexapdf/document.rb +9 -2
- data/lib/hexapdf/encryption/aes.rb +3 -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 +1 -1
- 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 +4 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +12 -2
- 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 +21 -9
- 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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/layout/box_fitter.rb +1 -1
- data/lib/hexapdf/layout/column_box.rb +1 -1
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +17 -3
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +1 -1
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/page_style.rb +144 -0
- data/lib/hexapdf/layout/style.rb +1 -1
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +4 -7
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/layout.rb +2 -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 -1
- 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 +9 -7
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/test_utils.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +2 -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/mark_information.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -1
- data/lib/hexapdf/type/object_stream.rb +8 -3
- data/lib/hexapdf/type/outline.rb +2 -2
- data/lib/hexapdf/type/outline_item.rb +11 -2
- data/lib/hexapdf/type/page.rb +36 -9
- data/lib/hexapdf/type/page_label.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +1 -1
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +1 -1
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +12 -5
- 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 +2 -2
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +80 -17
- data/test/hexapdf/encryption/common.rb +4 -0
- data/test/hexapdf/encryption/test_aes.rb +8 -0
- data/test/hexapdf/encryption/test_security_handler.rb +6 -0
- data/test/hexapdf/filter/test_flate_decode.rb +19 -5
- data/test/hexapdf/layout/test_inline_box.rb +35 -15
- data/test/hexapdf/layout/test_page_style.rb +70 -0
- data/test/hexapdf/layout/test_text_box.rb +5 -2
- data/test/hexapdf/layout/test_text_layouter.rb +6 -11
- data/test/hexapdf/task/test_optimize.rb +11 -9
- data/test/hexapdf/test_composer.rb +49 -11
- data/test/hexapdf/test_tokenizer.rb +5 -0
- data/test/hexapdf/test_writer.rb +5 -5
- data/test/hexapdf/type/test_object_stream.rb +16 -7
- data/test/hexapdf/type/test_outline.rb +3 -1
- data/test/hexapdf/type/test_outline_item.rb +21 -1
- data/test/hexapdf/type/test_page.rb +58 -11
- data/test/hexapdf/type/test_xref_stream.rb +6 -1
- metadata +4 -2
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-2023 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
|
|
@@ -104,8 +104,16 @@ module HexaPDF
|
|
|
104
104
|
Executive: [0, 0, 522, 756].freeze,
|
|
105
105
|
}.freeze
|
|
106
106
|
|
|
107
|
-
# Returns the media box for the given paper size
|
|
107
|
+
# Returns the media box for the given paper size or array.
|
|
108
|
+
#
|
|
109
|
+
# If an array is specified, it needs to contain exactly four numbers. The +orientation+
|
|
110
|
+
# argument is not used in this case.
|
|
111
|
+
#
|
|
112
|
+
# See PAPER_SIZE for the defined paper sizes.
|
|
108
113
|
def self.media_box(paper_size, orientation: :portrait)
|
|
114
|
+
return paper_size if paper_size.kind_of?(Array) && paper_size.size == 4 &&
|
|
115
|
+
paper_size.all?(Numeric)
|
|
116
|
+
|
|
109
117
|
unless PAPER_SIZE.key?(paper_size)
|
|
110
118
|
raise HexaPDF::Error, "Invalid paper size specified: #{paper_size}"
|
|
111
119
|
end
|
|
@@ -118,9 +126,6 @@ module HexaPDF
|
|
|
118
126
|
# The inheritable fields.
|
|
119
127
|
INHERITABLE_FIELDS = [:Resources, :MediaBox, :CropBox, :Rotate].freeze
|
|
120
128
|
|
|
121
|
-
# The required inheritable fields.
|
|
122
|
-
REQUIRED_INHERITABLE_FIELDS = [:Resources, :MediaBox].freeze
|
|
123
|
-
|
|
124
129
|
define_type :Page
|
|
125
130
|
|
|
126
131
|
define_field :Type, type: Symbol, required: true, default: type
|
|
@@ -571,6 +576,12 @@ module HexaPDF
|
|
|
571
576
|
left, right = [llx, ulx, lrx, lrx + (ulx - llx)].minmax
|
|
572
577
|
bottom, top = [lly, uly, lry, lry + (uly - lly)].minmax
|
|
573
578
|
|
|
579
|
+
# Handle degenerate case of the transformed bounding box being a line or point
|
|
580
|
+
if right - left == 0 || top - bottom == 0
|
|
581
|
+
to_delete << annotation
|
|
582
|
+
next
|
|
583
|
+
end
|
|
584
|
+
|
|
574
585
|
# Step b) Fit calculated rectangle to annotation rectangle by translating/scaling
|
|
575
586
|
a = HexaPDF::Content::TransformationMatrix.new
|
|
576
587
|
a.translate(rect.left - left, rect.bottom - bottom)
|
|
@@ -609,10 +620,26 @@ module HexaPDF
|
|
|
609
620
|
return unless parent_node
|
|
610
621
|
|
|
611
622
|
super
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
yield("
|
|
615
|
-
resources.validate(&block)
|
|
623
|
+
|
|
624
|
+
unless self[:Resources]
|
|
625
|
+
yield("Required inheritable page field Resources not set", true)
|
|
626
|
+
resources.validate(&block)
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
unless self[:MediaBox]
|
|
630
|
+
yield("Required inheritable page field MediaBox not set", true)
|
|
631
|
+
index = self.index
|
|
632
|
+
box_before = index == 0 ? nil : document.pages[index - 1][:MediaBox]
|
|
633
|
+
box_after = index == document.pages.count - 1 ? nil : document.pages[index + 1]&.[](:MediaBox)
|
|
634
|
+
self[:MediaBox] =
|
|
635
|
+
if box_before && (box_before&.value == box_after&.value || box_after.nil?)
|
|
636
|
+
box_before.dup
|
|
637
|
+
elsif box_after && box_before.nil?
|
|
638
|
+
box_after
|
|
639
|
+
else
|
|
640
|
+
self.class.media_box(document.config['page.default_media_box'],
|
|
641
|
+
orientation: document.config['page.default_media_orientation'])
|
|
642
|
+
end
|
|
616
643
|
end
|
|
617
644
|
end
|
|
618
645
|
|
|
@@ -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-2023 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-2023 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-2023 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-2023 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-2023 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-2023 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,12 +72,10 @@ module HexaPDF
|
|
|
72
72
|
|
|
73
73
|
define_field :Type, type: Symbol, default: type, required: true, indirect: false,
|
|
74
74
|
version: '1.5'
|
|
75
|
-
|
|
76
|
-
define_field :Size, type: Integer, indirect: false
|
|
75
|
+
define_field :Size, type: Integer, indirect: false, required: true
|
|
77
76
|
define_field :Index, type: PDFArray, indirect: false
|
|
78
77
|
define_field :Prev, type: Integer, indirect: false
|
|
79
|
-
|
|
80
|
-
define_field :W, type: PDFArray, indirect: false
|
|
78
|
+
define_field :W, type: PDFArray, indirect: false, required: true
|
|
81
79
|
|
|
82
80
|
# Returns an XRefSection that represents the content of this cross-reference stream.
|
|
83
81
|
#
|
|
@@ -219,6 +217,15 @@ module HexaPDF
|
|
|
219
217
|
[[1, middle, 2], pack_string]
|
|
220
218
|
end
|
|
221
219
|
|
|
220
|
+
def perform_validation #:nodoc
|
|
221
|
+
# Size is not required because it will be auto-filled before the object is written
|
|
222
|
+
# W is not required because it will be auto-filled on #update_with_xref_section_and_trailer
|
|
223
|
+
# Set both here to dummy values to make validation work for the required values
|
|
224
|
+
self[:Size] ||= 1
|
|
225
|
+
self[:W] ||= [1, 1, 1]
|
|
226
|
+
super
|
|
227
|
+
end
|
|
228
|
+
|
|
222
229
|
end
|
|
223
230
|
|
|
224
231
|
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-2023 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-2023 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-2023 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-2023 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-2023 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-2023 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-2023 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-2023 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-2023 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/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-2023 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.32.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-2023 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,7 +207,7 @@ module HexaPDF
|
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
if (!object_streams.empty? || @use_xref_streams) && xref_stream.nil?
|
|
210
|
-
xref_stream = @document.wrap({
|
|
210
|
+
xref_stream = @document.wrap({}, type: Type::XRefStream, oid: @document.revisions.next_oid)
|
|
211
211
|
rev.add(xref_stream)
|
|
212
212
|
end
|
|
213
213
|
|
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-2023 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-2023 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
|
|
@@ -34,29 +34,24 @@ describe HexaPDF::Document::Layout::ChildrenCollector do
|
|
|
34
34
|
assert_equal(2, @collector.children[0].size)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
it "allows appending boxes
|
|
38
|
-
@collector.lorem_ipsum_box
|
|
39
|
-
assert_equal(1, @collector.children.size)
|
|
40
|
-
assert_kind_of(HexaPDF::Layout::TextBox, @collector.children[0])
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it "allows appending boxes through method names without the _box suffix of the Layout class" do
|
|
37
|
+
it "allows appending boxes created by the Layout class" do
|
|
44
38
|
@collector.lorem_ipsum
|
|
45
|
-
|
|
39
|
+
@collector.lorem_ipsum_box
|
|
40
|
+
@collector.column
|
|
41
|
+
@collector.column_box
|
|
42
|
+
assert_equal(4, @collector.children.size)
|
|
46
43
|
assert_kind_of(HexaPDF::Layout::TextBox, @collector.children[0])
|
|
44
|
+
assert_kind_of(HexaPDF::Layout::TextBox, @collector.children[1])
|
|
45
|
+
assert_kind_of(HexaPDF::Layout::ColumnBox, @collector.children[2])
|
|
46
|
+
assert_kind_of(HexaPDF::Layout::ColumnBox, @collector.children[3])
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
it "
|
|
50
|
-
@collector.
|
|
51
|
-
assert_equal(1, @collector.children.size)
|
|
52
|
-
assert_kind_of(HexaPDF::Layout::ColumnBox, @collector.children[0])
|
|
49
|
+
it "can be asked which methods it supports" do
|
|
50
|
+
assert(@collector.respond_to?(:lorem_ipsum))
|
|
53
51
|
end
|
|
54
52
|
|
|
55
|
-
it "
|
|
56
|
-
|
|
57
|
-
assert(@collector.respond_to?(:text))
|
|
58
|
-
assert(@collector.respond_to?(:column))
|
|
59
|
-
refute(@collector.respond_to?(:unknown))
|
|
53
|
+
it "only allows using box creation methods from the Layout class" do
|
|
54
|
+
assert_raises(NameError) { @collector.style }
|
|
60
55
|
end
|
|
61
56
|
|
|
62
57
|
it "raises an error on an unknown method name" do
|
|
@@ -88,6 +83,27 @@ describe HexaPDF::Document::Layout do
|
|
|
88
83
|
end
|
|
89
84
|
end
|
|
90
85
|
|
|
86
|
+
describe "inline_box" do
|
|
87
|
+
it "takes a box as argument" do
|
|
88
|
+
box = HexaPDF::Layout::Box.create(width: 10, height: 10)
|
|
89
|
+
ibox = @layout.inline_box(box)
|
|
90
|
+
assert_same(box, ibox.box)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "correctly passes on the valign argument" do
|
|
94
|
+
box = HexaPDF::Layout::Box.create(width: 10, height: 10)
|
|
95
|
+
ibox = @layout.inline_box(box, valign: :top)
|
|
96
|
+
assert_equal(:top, ibox.valign)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "can create a box using any box creation method of the Layout class" do
|
|
100
|
+
ibox = @layout.inline_box(:text, "Some text", valign: :bottom, width: 10, background_color: "red")
|
|
101
|
+
assert_equal(:bottom, ibox.valign)
|
|
102
|
+
assert_equal(10, ibox.width)
|
|
103
|
+
assert_equal("red", ibox.box.style.background_color)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
91
107
|
describe "box" do
|
|
92
108
|
it "creates the request box" do
|
|
93
109
|
box = @layout.box(:column, columns: 3, gaps: 20, width: 15, height: 30, style: {font_size: 10},
|
|
@@ -232,6 +248,24 @@ describe HexaPDF::Document::Layout do
|
|
|
232
248
|
items = box.instance_variable_get(:@items)
|
|
233
249
|
assert_equal({named_dest: 'test'}, items[0].properties)
|
|
234
250
|
end
|
|
251
|
+
|
|
252
|
+
it "allows adding an inline box" do
|
|
253
|
+
ibox = @layout.inline_box(:base, width: 10, height: 10)
|
|
254
|
+
box = @layout.formatted_text_box([ibox])
|
|
255
|
+
assert_equal(ibox, box.instance_variable_get(:@items).first)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "allows creating an inline box through a hash with a :box key" do
|
|
259
|
+
block = lambda {|item| item.box(:base, width: 5, height: 15) }
|
|
260
|
+
box = @layout.formatted_text_box([{box: :list, width: 10, block: block}])
|
|
261
|
+
ibox = box.instance_variable_get(:@items).first
|
|
262
|
+
assert_equal(10, ibox.width)
|
|
263
|
+
assert_equal(15, ibox.height)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it "fails if the data array contains unsupported items" do
|
|
267
|
+
assert_raises(ArgumentError) { @layout.formatted_text_box([5]) }
|
|
268
|
+
end
|
|
235
269
|
end
|
|
236
270
|
|
|
237
271
|
describe "image_box" do
|
|
@@ -277,4 +311,33 @@ describe HexaPDF::Document::Layout do
|
|
|
277
311
|
assert_equal(HexaPDF::Document::Layout::LOREM_IPSUM[0, 2].join(" ").size * 2 + 2, items[0].items.length)
|
|
278
312
|
end
|
|
279
313
|
end
|
|
314
|
+
|
|
315
|
+
describe "method_missing" do
|
|
316
|
+
it "resolves to internal methods with the _box suffix, e.g. text_box" do
|
|
317
|
+
box = @layout.text("Test", width: 10, height: 15, properties: {key: :value})
|
|
318
|
+
assert_kind_of(HexaPDF::Layout::TextBox, box)
|
|
319
|
+
assert_equal(10, box.width)
|
|
320
|
+
assert_equal(15, box.height)
|
|
321
|
+
assert_equal({key: :value}, box.properties)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "resolves to the box method when a configured name is used" do
|
|
325
|
+
box = @layout.column
|
|
326
|
+
assert_kind_of(HexaPDF::Layout::ColumnBox, box)
|
|
327
|
+
box = @layout.column_box
|
|
328
|
+
assert_kind_of(HexaPDF::Layout::ColumnBox, box)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it "fails if nothing could be resolved" do
|
|
332
|
+
assert_raises(NameError) { @layout.unknown }
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
describe "respond_to_missing?" do
|
|
337
|
+
it "can be asked which methods it supports" do
|
|
338
|
+
assert(@layout.respond_to?(:text))
|
|
339
|
+
assert(@layout.respond_to?(:column))
|
|
340
|
+
refute(@layout.respond_to?(:unknown))
|
|
341
|
+
end
|
|
342
|
+
end
|
|
280
343
|
end
|
|
@@ -48,6 +48,10 @@ describe HexaPDF::Encryption::AES do
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
it "handles invalid files with empty strings" do
|
|
52
|
+
assert_equal('', @algorithm_class.decrypt('key', ''))
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
it "handles invalid files with missing 16 byte padding" do
|
|
52
56
|
assert_equal('', @algorithm_class.decrypt('some key' * 2, 'iv' * 8))
|
|
53
57
|
end
|
|
@@ -118,6 +122,10 @@ describe HexaPDF::Encryption::AES do
|
|
|
118
122
|
assert_equal('a' * 13 << "\x00\x01\x03", result)
|
|
119
123
|
end
|
|
120
124
|
|
|
125
|
+
it "handles invalid files with empty streams" do
|
|
126
|
+
assert_equal('', collector(@algorithm_class.decryption_fiber('key', Fiber.new { '' })))
|
|
127
|
+
end
|
|
128
|
+
|
|
121
129
|
it "fails on decryption if not enough bytes are provided" do
|
|
122
130
|
[4, 20, 40].each do |length|
|
|
123
131
|
assert_raises(HexaPDF::EncryptionError) do
|
|
@@ -325,6 +325,12 @@ describe HexaPDF::Encryption::SecurityHandler do
|
|
|
325
325
|
assert_equal("test", @handler.decrypt(@obj)[:Contents])
|
|
326
326
|
end
|
|
327
327
|
|
|
328
|
+
it "enhances a thrown EncryptionError by setting the PDF object" do
|
|
329
|
+
@handler.set_up_encryption(key_length: 256)
|
|
330
|
+
error = assert_raises(HexaPDF::EncryptionError) { @handler.decrypt(@obj) }
|
|
331
|
+
assert_match(/Object \(1,0\):/, error.message)
|
|
332
|
+
end
|
|
333
|
+
|
|
328
334
|
it "fails if V < 5 and the object number changes" do
|
|
329
335
|
@obj.oid = 55
|
|
330
336
|
@handler.decrypt(@obj)
|
|
@@ -26,12 +26,26 @@ describe HexaPDF::Filter::FlateDecode do
|
|
|
26
26
|
assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor), @predictor_opts)))
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
describe "invalid input is handled as good as possible" do
|
|
30
|
+
def strict_mode
|
|
31
|
+
HexaPDF::GlobalConfiguration['filter.flate.on_error'] = proc { true }
|
|
32
|
+
yield
|
|
33
|
+
ensure
|
|
34
|
+
HexaPDF::GlobalConfiguration['filter.flate.on_error'] = proc { false }
|
|
32
35
|
end
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
|
|
37
|
+
it "handles completely invalid data" do
|
|
38
|
+
assert_equal('', collector(@obj.decoder(feeder("some data"))))
|
|
39
|
+
assert_raises(HexaPDF::FilterError) do
|
|
40
|
+
strict_mode { collector(@obj.decoder(feeder("some data"))) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "handles missing data" do
|
|
45
|
+
assert_equal('abcdefg', collector(@obj.decoder(feeder(@encoded[0..-2]))))
|
|
46
|
+
assert_raises(HexaPDF::FilterError) do
|
|
47
|
+
strict_mode { collector(@obj.decoder(feeder(@encoded[0..-2]))) }
|
|
48
|
+
end
|
|
35
49
|
end
|
|
36
50
|
end
|
|
37
51
|
end
|
|
@@ -2,31 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
require 'test_helper'
|
|
4
4
|
require 'hexapdf/layout/inline_box'
|
|
5
|
+
require 'hexapdf/document'
|
|
5
6
|
|
|
6
7
|
describe HexaPDF::Layout::InlineBox do
|
|
8
|
+
def inline_box(box, valign: :baseline)
|
|
9
|
+
HexaPDF::Layout::InlineBox.new(box, valign: valign)
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
before do
|
|
8
13
|
@box = HexaPDF::Layout::InlineBox.create(width: 10, height: 15, margin: [15, 10])
|
|
9
14
|
end
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
describe "initialize" do
|
|
17
|
+
it "needs a box to wrap and an optional alignment on initialization" do
|
|
18
|
+
box = HexaPDF::Layout::Box.create(width: 10, height: 15)
|
|
19
|
+
ibox = inline_box(box)
|
|
20
|
+
assert_equal(box, ibox.box)
|
|
21
|
+
assert_equal(:baseline, ibox.valign)
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
ibox = inline_box(box, valign: :top)
|
|
24
|
+
assert_equal(:top, ibox.valign)
|
|
25
|
+
end
|
|
19
26
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
assert_equal(
|
|
24
|
-
assert_equal(10, x)
|
|
25
|
-
assert_equal(15, y)
|
|
27
|
+
it "automatically fits the provided box into a frame" do
|
|
28
|
+
ibox = inline_box(HexaPDF::Document.new.layout.text("test is going good", width: 20))
|
|
29
|
+
assert_equal(20, ibox.width)
|
|
30
|
+
assert_equal(45, ibox.height)
|
|
26
31
|
end
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
|
|
33
|
+
it "fails if the wrapped box could not be fit" do
|
|
34
|
+
box = HexaPDF::Document.new.layout.text("test is not going good", width: 1)
|
|
35
|
+
assert_raises(HexaPDF::Error) { inline_box(box) }
|
|
29
36
|
end
|
|
37
|
+
|
|
38
|
+
it "fails if the height is not set explicitly and during fitting" do
|
|
39
|
+
assert_raises(HexaPDF::Error) do
|
|
40
|
+
inline_box(HexaPDF::Layout::Box.create(width: 10))
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "draws the wrapped box at the correct position" do
|
|
46
|
+
doc = HexaPDF::Document.new
|
|
47
|
+
canvas = doc.pages.add.canvas
|
|
48
|
+
inline_box(doc.layout.text("", width: 20, margin: [15, 10])).draw(canvas, 100, 200)
|
|
49
|
+
assert_equal("q\n1 0 0 1 110 -99785 cm\nQ\n", canvas.contents)
|
|
30
50
|
end
|
|
31
51
|
|
|
32
52
|
it "returns true if the inline box is empty with no drawing operations" do
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'test_helper'
|
|
4
|
+
require 'hexapdf/layout/page_style'
|
|
5
|
+
require 'hexapdf/document'
|
|
6
|
+
|
|
7
|
+
describe HexaPDF::Layout::PageStyle do
|
|
8
|
+
it "allows assigning the page size, orientation and template on initialization" do
|
|
9
|
+
block = lambda {}
|
|
10
|
+
style = HexaPDF::Layout::PageStyle.new(page_size: :A3, orientation: :landscape, &block)
|
|
11
|
+
assert_equal(:A3, style.page_size)
|
|
12
|
+
assert_equal(:landscape, style.orientation)
|
|
13
|
+
assert_same(block, style.template)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "uses defaults for all values" do
|
|
17
|
+
style = HexaPDF::Layout::PageStyle.new
|
|
18
|
+
assert_equal(:A4, style.page_size)
|
|
19
|
+
assert_equal(:portrait, style.orientation)
|
|
20
|
+
assert_nil(style.template)
|
|
21
|
+
assert_nil(style.frame)
|
|
22
|
+
assert_nil(style.next_style)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "create_page" do
|
|
26
|
+
before do
|
|
27
|
+
@doc = HexaPDF::Document.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "creates a new page object" do
|
|
31
|
+
style = HexaPDF::Layout::PageStyle.new do |canvas, istyle|
|
|
32
|
+
canvas.rectangle(0, 0, 10, 10).stroke
|
|
33
|
+
istyle.frame = :frame
|
|
34
|
+
istyle.next_style = :other
|
|
35
|
+
end
|
|
36
|
+
page = style.create_page(@doc)
|
|
37
|
+
assert_equal([0, 0, 595, 842], page.box(:media))
|
|
38
|
+
assert_equal("0 0 10 10 re\nS\n", page.contents)
|
|
39
|
+
assert_equal(:frame, style.frame)
|
|
40
|
+
assert_equal(:other, style.next_style)
|
|
41
|
+
assert_equal(0, @doc.pages.count)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "works when no template is set" do
|
|
45
|
+
style = HexaPDF::Layout::PageStyle.new
|
|
46
|
+
page = style.create_page(@doc)
|
|
47
|
+
assert_equal("", page.contents)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "creates a default frame if none is set beforehand or during template execution" do
|
|
51
|
+
style = HexaPDF::Layout::PageStyle.new
|
|
52
|
+
style.create_page(@doc)
|
|
53
|
+
assert_kind_of(HexaPDF::Layout::Frame, style.frame)
|
|
54
|
+
assert_equal(36, style.frame.left)
|
|
55
|
+
assert_equal(36, style.frame.bottom)
|
|
56
|
+
assert_equal(523, style.frame.width)
|
|
57
|
+
assert_equal(770, style.frame.height)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "creates new frame objects given a page and a margin specification" do
|
|
62
|
+
doc = HexaPDF::Document.new
|
|
63
|
+
style = HexaPDF::Layout::PageStyle.new
|
|
64
|
+
frame = style.create_frame(style.create_page(doc), [15, 10])
|
|
65
|
+
assert_equal(10, frame.left)
|
|
66
|
+
assert_equal(15, frame.bottom)
|
|
67
|
+
assert_equal(575, frame.width)
|
|
68
|
+
assert_equal(812, frame.height)
|
|
69
|
+
end
|
|
70
|
+
end
|