hexapdf 0.45.0 → 0.47.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +120 -47
- data/examples/019-acro_form.rb +5 -0
- data/lib/hexapdf/cli/inspect.rb +5 -0
- data/lib/hexapdf/composer.rb +1 -1
- data/lib/hexapdf/configuration.rb +19 -0
- data/lib/hexapdf/digital_signature/cms_handler.rb +31 -3
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +9 -1
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +5 -1
- data/lib/hexapdf/document/layout.rb +48 -27
- data/lib/hexapdf/document.rb +24 -2
- data/lib/hexapdf/encryption/standard_security_handler.rb +32 -26
- data/lib/hexapdf/importer.rb +15 -5
- data/lib/hexapdf/layout/box.rb +25 -28
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +17 -23
- data/lib/hexapdf/layout/list_box.rb +24 -29
- data/lib/hexapdf/layout/page_style.rb +23 -16
- data/lib/hexapdf/layout/style.rb +2 -2
- data/lib/hexapdf/layout/table_box.rb +57 -10
- data/lib/hexapdf/layout/text_box.rb +2 -6
- data/lib/hexapdf/parser.rb +5 -1
- data/lib/hexapdf/revisions.rb +1 -1
- data/lib/hexapdf/stream.rb +3 -3
- data/lib/hexapdf/task/optimize.rb +4 -4
- data/lib/hexapdf/tokenizer.rb +3 -2
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +8 -4
- data/lib/hexapdf/type/acro_form/button_field.rb +2 -0
- data/lib/hexapdf/type/acro_form/choice_field.rb +2 -0
- data/lib/hexapdf/type/acro_form/field.rb +8 -0
- data/lib/hexapdf/type/acro_form/form.rb +10 -6
- data/lib/hexapdf/type/acro_form/signature_field.rb +2 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +2 -0
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +11 -3
- data/lib/hexapdf/type/annotations/widget.rb +4 -2
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +1 -0
- data/test/data/standard-security-handler/bothpwd-aes-256bit-V5-R5.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-aes-256bit-V5-R5.pdf +44 -0
- data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5-R5.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-256bit-V5-R5.pdf +0 -0
- data/test/hexapdf/digital_signature/common.rb +66 -84
- data/test/hexapdf/digital_signature/signing/test_default_handler.rb +7 -0
- data/test/hexapdf/digital_signature/signing/test_signed_data_creator.rb +9 -0
- data/test/hexapdf/digital_signature/test_cms_handler.rb +41 -1
- data/test/hexapdf/digital_signature/test_handler.rb +2 -1
- data/test/hexapdf/digital_signature/test_signatures.rb +4 -4
- data/test/hexapdf/document/test_layout.rb +28 -5
- data/test/hexapdf/encryption/test_standard_security_handler.rb +5 -2
- data/test/hexapdf/layout/test_box.rb +12 -5
- data/test/hexapdf/layout/test_frame.rb +12 -2
- data/test/hexapdf/layout/test_inline_box.rb +17 -28
- data/test/hexapdf/layout/test_list_box.rb +5 -5
- data/test/hexapdf/layout/test_page_style.rb +7 -2
- data/test/hexapdf/layout/test_table_box.rb +52 -0
- data/test/hexapdf/layout/test_text_box.rb +3 -9
- data/test/hexapdf/layout/test_text_layouter.rb +0 -3
- data/test/hexapdf/task/test_optimize.rb +2 -0
- data/test/hexapdf/test_document.rb +30 -3
- data/test/hexapdf/test_importer.rb +24 -0
- data/test/hexapdf/test_revisions.rb +54 -41
- data/test/hexapdf/test_writer.rb +11 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +22 -5
- data/test/hexapdf/type/acro_form/test_form.rb +9 -5
- data/test/hexapdf/type/acro_form/test_signature_field.rb +3 -1
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +14 -1
- data/test/hexapdf/type/annotations/test_widget.rb +4 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15f4c7590b5f2ce321519ac0b4871971c12073a9d4b0df36ab2f2e3c156f09ab
|
4
|
+
data.tar.gz: 76dac6196e06e80fd88dade3f831b7744c2b763f004d3c389d3efebcace3be82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ea19ed17370cad1a1fa48a7e0cb85c16e3ff62b344d2a9a90c42d2ac98d5ce5f75c356facf6bb8276822db460e2d9f912f523783c82b3539200e33f9de9f383
|
7
|
+
data.tar.gz: bdf2d93feade9f0654366bbf89711b670cbd03ee88b81f197f756c2032305f9ee7b9265973f31c5a4e18e7afd3e4f9dfd08b46a0483502b896774494294c111a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,76 @@
|
|
1
|
+
## 0.47.0 - 2024-09-07
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Configuration option 'acro_form.fallback_default_appearance' to allow setting
|
6
|
+
a standard default appearance string for a variable text field if none is
|
7
|
+
found
|
8
|
+
* Support for decrypting files with the proprietary algorithm /R 5
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
|
12
|
+
* [HexaPDF::Task::Optimize] to not remove optional /Type entries containing
|
13
|
+
default values
|
14
|
+
* Validation of [HexaPDF::Type::AcroForm::Form] to not add a /DA entry
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
|
18
|
+
* [HexaPDF::Layout::TableBox] to correctly calculcate and distribute row
|
19
|
+
heights when row spans are involved
|
20
|
+
* [HexaPDF::Type::AcroForm::AppearanceGenerator] to work for files where check
|
21
|
+
boxes don't define the name of the on state
|
22
|
+
* [HexaPDF::Importer#import] to handle null values in all cases
|
23
|
+
* [HexaPDF::Type::AcroForm::VariableTextField] to handle parsing of invalid PDFs
|
24
|
+
with symbolic appearance strings
|
25
|
+
* [HexaPDF::Type::Annotations::Widget#marker_style] to handle invalid /DA values
|
26
|
+
with missing font size or color information
|
27
|
+
* [HexaPDF::Type::AcroForm::SignatureField#field_value] to always return a
|
28
|
+
correctly wrapped object
|
29
|
+
* [HexaPDF::Writer] to remove /Type entry from trailer
|
30
|
+
* [HexaPDF::Type::AcroForm::AppearanceGenerator#create_text_appearances] to
|
31
|
+
handle invalid appearance streams that are not correct Form XObjects
|
32
|
+
|
33
|
+
|
34
|
+
## 0.46.0 - 2024-08-11
|
35
|
+
|
36
|
+
### Added
|
37
|
+
|
38
|
+
* [HexaPDF::DigitalSignature::CMSHandler#embedded_tsa_signature] to return the
|
39
|
+
embedded timestamp authority signature if any
|
40
|
+
* [HexaPDF::DigitalSignature::Signing::DefaultHandler#signing_time] for setting
|
41
|
+
a custom signing time
|
42
|
+
* [HexaPDF::Document#duplicate] for making an in-memory copy of a PDF document
|
43
|
+
* Configuration option 'font.default' for setting the default font for the
|
44
|
+
document layout engine
|
45
|
+
|
46
|
+
### Changed
|
47
|
+
|
48
|
+
* [HexaPDF::Document::Layout::CellArgumentCollector#[]=] to allow stepped ranges
|
49
|
+
* [HexaPDF::Document::Layout::ChildrenCollector] to also return the box when
|
50
|
+
creating and adding one to the list
|
51
|
+
* [HexaPDF::Layout::InlineBox] to allow usage without predefined width
|
52
|
+
* [HexaPDF::DigitalSignature::CMSHandler#verify] to recognize non-repudiation
|
53
|
+
signatures
|
54
|
+
* [HexaPDF::DigitalSignature::CMSHandler#signing_time] to use time from an
|
55
|
+
embedded timestamp authority signature if possible
|
56
|
+
* [HexaPDF::Layout::Box#fit] to return success for boxes with content
|
57
|
+
width/height of zero
|
58
|
+
* [HexaPDF::Importer::copy] to optionally allow copying the catalog and page
|
59
|
+
tree nodes
|
60
|
+
|
61
|
+
### Fixed
|
62
|
+
|
63
|
+
* Setting of correct x-position in fit result for boxes with flow positioning
|
64
|
+
* [HexaPDF::Layout::ListBox#fit] to respect the set height
|
65
|
+
* CLI command `hexapdf inspect` to work in case of missing Unicde mappings
|
66
|
+
* [HexaPDF::Type::AcroForm::Form#delete_field] to correctly work for fields with
|
67
|
+
an embedded widget
|
68
|
+
* Parsing of "linearized" PDF files where the first cross-reference section
|
69
|
+
isn't actually used
|
70
|
+
* [HexaPDF::Layout::PageStyle#create_page] to return new frame objects on each
|
71
|
+
invocation
|
72
|
+
|
73
|
+
|
1
74
|
## 0.45.0 - 2024-06-18
|
2
75
|
|
3
76
|
### Added
|
@@ -375,8 +448,8 @@
|
|
375
448
|
|
376
449
|
### Fixed
|
377
450
|
|
378
|
-
* [HexaPDF::Document::Pages#add_labelling_range] to add a correct entry for
|
379
|
-
|
451
|
+
* [HexaPDF::Document::Pages#add_labelling_range] to add a correct entry for the
|
452
|
+
default range starting at page 1
|
380
453
|
* [HexaPDF::Type::Page#flatten_annotations] to correctly handle scaled
|
381
454
|
appearances
|
382
455
|
* Using an unknown style name in [HexaPDF:Document::Layout] method by providing
|
@@ -387,6 +460,8 @@
|
|
387
460
|
than the item content height
|
388
461
|
* [HexaPDF::Dictionary] setting default values on wrong classes in certain
|
389
462
|
situations
|
463
|
+
* [HexaPDF::Importer#import] to correctly import stream objects backed by a
|
464
|
+
[HexaPDF::FiberDoubleForString]
|
390
465
|
|
391
466
|
|
392
467
|
## 0.33.0 - 2023-08-02
|
@@ -439,8 +514,8 @@
|
|
439
514
|
* [HexaPDF::Content::Canvas#text] to set the leading only when multiple lines
|
440
515
|
are drawn
|
441
516
|
* [HexaPDF::Layout::TextBox#split] to use float comparison
|
442
|
-
* Validation of standard encryption dictionary to auto-correct invalid /U and
|
443
|
-
|
517
|
+
* Validation of standard encryption dictionary to auto-correct invalid /U and /O
|
518
|
+
fields in case they are padded with zeros
|
444
519
|
* [HexaPDF::Document#wrap] handling of sub-type mapping in case of missing type
|
445
520
|
* [HexaPDF::Type::AcroForm::AppearanceGenerator] to also take a text field
|
446
521
|
widget's width into account when auto-sizing
|
@@ -761,8 +836,8 @@
|
|
761
836
|
* Support for the document outline
|
762
837
|
* [HexaPDF::Layout::Style#line_height] for setting a custom line height
|
763
838
|
independent of the font size
|
764
|
-
* [HexaPDF::Document::Destinations#use_or_create] as unified interface for
|
765
|
-
|
839
|
+
* [HexaPDF::Document::Destinations#use_or_create] as unified interface for using
|
840
|
+
or creating destinations
|
766
841
|
* [HexaPDF::Document::Destinations::Destination#valid?] and class method for
|
767
842
|
checking whether a destination array is valid
|
768
843
|
|
@@ -771,8 +846,8 @@
|
|
771
846
|
* Calculation of text related [HexaPDF::Layout::Style] values for Type3 fonts
|
772
847
|
* [HexaPDF::Encryption::SecurityHandler#encrypt_string] to either return a
|
773
848
|
dupped or encrypted string
|
774
|
-
* [HexaPDF::Layout::TextLayouter#fit] to avoid infinite loop when encountering
|
775
|
-
|
849
|
+
* [HexaPDF::Layout::TextLayouter#fit] to avoid infinite loop when encountering a
|
850
|
+
non-zero width breakpoint penalty
|
776
851
|
* [HexaPDF::Type::ObjectStream] to parse the initial stream data right after
|
777
852
|
initialization to avoid access errors
|
778
853
|
* [HexaPDF::Revisions::from_io] to merge a completely empty revision with just a
|
@@ -854,8 +929,7 @@
|
|
854
929
|
fragment if there would not be enough height left anyway
|
855
930
|
* [HexaPDF::Layout::WidthFromPolygon] to work correctly in case of very small
|
856
931
|
floating point errors
|
857
|
-
* HexaPDF::Layout::TextFragment#inspect to work in case of interspersed
|
858
|
-
numbers
|
932
|
+
* HexaPDF::Layout::TextFragment#inspect to work in case of interspersed numbers
|
859
933
|
* [HexaPDF::Layout::TextBox#split] to work for position :flow when box is wider
|
860
934
|
than the initial available width
|
861
935
|
* [HexaPDF::Layout::Frame#fit] to create minimally sized mask rectangles
|
@@ -1137,8 +1211,8 @@
|
|
1137
1211
|
dictionary are indirect objects
|
1138
1212
|
* [HexaPDF::Content::GraphicObject::EndpointArc] to correctly determine the
|
1139
1213
|
start and end points
|
1140
|
-
* HexaPDF::Dictionary#perform_validation to correctly handle objects that
|
1141
|
-
|
1214
|
+
* HexaPDF::Dictionary#perform_validation to correctly handle objects that should
|
1215
|
+
not be indirect objects
|
1142
1216
|
|
1143
1217
|
|
1144
1218
|
## 0.17.3 - 2021-10-31
|
@@ -1260,8 +1334,8 @@
|
|
1260
1334
|
|
1261
1335
|
### Fixed
|
1262
1336
|
|
1263
|
-
* [HexaPDF::Type::Annotation#appearance] to handle cases where there is
|
1264
|
-
|
1337
|
+
* [HexaPDF::Type::Annotation#appearance] to handle cases where there is no valid
|
1338
|
+
appearance stream
|
1265
1339
|
|
1266
1340
|
|
1267
1341
|
## 0.15.3 - 2021-05-01
|
@@ -1316,8 +1390,8 @@
|
|
1316
1390
|
empty background color arrays
|
1317
1391
|
* [HexaPDF::Type::AcroForm::Field#delete_widget] to update the wrapper object
|
1318
1392
|
stored in the document in case the widget is embedded
|
1319
|
-
* Processing of invalid PDF files containing a space,CR,LF combination after
|
1320
|
-
|
1393
|
+
* Processing of invalid PDF files containing a space,CR,LF combination after the
|
1394
|
+
'stream' keyword
|
1321
1395
|
* Cross-reference stream reconstruction with respect to detection of linearized
|
1322
1396
|
files
|
1323
1397
|
* Detection of existing appearances for AcroForm push button fields when
|
@@ -1412,8 +1486,8 @@
|
|
1412
1486
|
|
1413
1487
|
* [HexaPDF::Utils::ObjectHash#oids] to be public instead of private
|
1414
1488
|
* Cross-reference table parsing to handle invalidly numbered main sections
|
1415
|
-
* [HexaPDF::Document#cache] and [HexaPDF::Object#cache] to allow updating
|
1416
|
-
|
1489
|
+
* [HexaPDF::Document#cache] and [HexaPDF::Object#cache] to allow updating values
|
1490
|
+
for existing keys
|
1417
1491
|
* Appearance creation methods of AcroForm objects to allow forcing the creation
|
1418
1492
|
of new appearances
|
1419
1493
|
* [HexaPDF::Type::AcroForm::AppearanceGenerator#create_text_appearances] to
|
@@ -1451,8 +1525,8 @@
|
|
1451
1525
|
new 'parser.try_xref_reconstruction' option
|
1452
1526
|
* Two new `hexapdf inspect` commands for showing page objects and page content
|
1453
1527
|
streams by page number
|
1454
|
-
* Flag `--check` to the CLI command `hexapdf info` for checking a file for
|
1455
|
-
|
1528
|
+
* Flag `--check` to the CLI command `hexapdf info` for checking a file for parse
|
1529
|
+
and validation errors
|
1456
1530
|
* [HexaPDF::Type::AcroForm::Field#embedded_widget?] for checking if a widget is
|
1457
1531
|
embedded in the field object
|
1458
1532
|
* [HexaPDF::Type::AcroForm::Field#delete_widget] for deleting a widget
|
@@ -1509,8 +1583,8 @@
|
|
1509
1583
|
|
1510
1584
|
### Added
|
1511
1585
|
|
1512
|
-
* [HexaPDF::Font::Encoding::Base#code] for retrieving the code for a given
|
1513
|
-
|
1586
|
+
* [HexaPDF::Font::Encoding::Base#code] for retrieving the code for a given glyph
|
1587
|
+
name
|
1514
1588
|
|
1515
1589
|
### Fixed
|
1516
1590
|
|
@@ -1526,11 +1600,11 @@
|
|
1526
1600
|
[HexaPDF::Type::AcroForm::Field]
|
1527
1601
|
* [HexaPDF::Type::AcroForm::TextField] and
|
1528
1602
|
[HexaPDF::Type::AcroForm::VariableTextField] for basic text field support
|
1529
|
-
* [HexaPDF::Type::AcroForm::ButtonField] for push button, radio button and
|
1530
|
-
|
1603
|
+
* [HexaPDF::Type::AcroForm::ButtonField] for push button, radio button and check
|
1604
|
+
box support
|
1531
1605
|
* [HexaPDF::Type::AcroForm::ChoiceField] for combo box and list box support
|
1532
|
-
* [HexaPDF::Type::AcroForm::AppearanceGenerator] as central class for
|
1533
|
-
|
1606
|
+
* [HexaPDF::Type::AcroForm::AppearanceGenerator] as central class for generating
|
1607
|
+
appearance streams for form fields
|
1534
1608
|
* Various convenience methods for [HexaPDF::Type::AcroForm::Form]
|
1535
1609
|
* Various convenience methods for [HexaPDF::Type::AcroForm::Field]
|
1536
1610
|
* Various convenience methods for [HexaPDF::Type::Annotations::Widget]
|
@@ -1549,8 +1623,8 @@
|
|
1549
1623
|
* [HexaPDF::Type::Annotation::Border] class
|
1550
1624
|
* [HexaPDF::Content::ColorSpace::device_color_from_specification] for easily
|
1551
1625
|
getting a device color object
|
1552
|
-
* [HexaPDF::Content::ColorSpace::prenormalized_device_color] for getting a
|
1553
|
-
color object without normalizing values
|
1626
|
+
* [HexaPDF::Content::ColorSpace::prenormalized_device_color] for getting a
|
1627
|
+
device color object without normalizing values
|
1554
1628
|
* [HexaPDF::Type::Annotation#appearance] for returning the associated appearance
|
1555
1629
|
dictionary
|
1556
1630
|
* [HexaPDF::Type::Annotation#appearance?] for checking whether an appearance for
|
@@ -1669,8 +1743,8 @@
|
|
1669
1743
|
|
1670
1744
|
### Fixed
|
1671
1745
|
|
1672
|
-
* Conversion of [HexaPDF::Rectangle] type when the original is not a plain
|
1673
|
-
|
1746
|
+
* Conversion of [HexaPDF::Rectangle] type when the original is not a plain Array
|
1747
|
+
but a [HexaPDF::PDFArray]
|
1674
1748
|
|
1675
1749
|
|
1676
1750
|
## 0.11.1 - 2019-11-19
|
@@ -1831,12 +1905,12 @@
|
|
1831
1905
|
|
1832
1906
|
### Added
|
1833
1907
|
|
1834
|
-
* [HexaPDF::Layout::Frame] for box positioning and easier text layouting
|
1835
|
-
|
1908
|
+
* [HexaPDF::Layout::Frame] for box positioning and easier text layouting inside
|
1909
|
+
an arbitrary polygon
|
1836
1910
|
* [HexaPDF::Layout::TextBox] for displaying text in a rectangular and for
|
1837
1911
|
flowing text inside a frame
|
1838
|
-
* [HexaPDF::Layout::WidthFromPolygon] for getting a width specification from
|
1839
|
-
|
1912
|
+
* [HexaPDF::Layout::WidthFromPolygon] for getting a width specification from a
|
1913
|
+
polygon for use with the text layouting engine
|
1840
1914
|
* [HexaPDF::Type::Image#width] and [HexaPDF::Type::Image#height] convenience
|
1841
1915
|
methods
|
1842
1916
|
* [HexaPDF::Type::FontType3] for Type 3 font support
|
@@ -1888,12 +1962,12 @@
|
|
1888
1962
|
character in a text fragment is \r
|
1889
1963
|
* [HexaPDF::Layout::TextLayouter] to work if an optional break point (think
|
1890
1964
|
soft-hyphen) is followed by whitespace
|
1891
|
-
* [HexaPDF::Font::TrueType::Builder] to correctly order the entries in the
|
1892
|
-
|
1965
|
+
* [HexaPDF::Font::TrueType::Builder] to correctly order the entries in the table
|
1966
|
+
directory
|
1893
1967
|
* [HexaPDF::Font::TrueType::Builder] to pad the table data to achieve the
|
1894
1968
|
correct alignment
|
1895
|
-
* [HexaPDF::Filter::FlateDecode] by removing the Zlib pools since they were
|
1896
|
-
|
1969
|
+
* [HexaPDF::Filter::FlateDecode] by removing the Zlib pools since they were not
|
1970
|
+
thread safe
|
1897
1971
|
* All color space classes to accept the color space definition as argument to
|
1898
1972
|
`::new`
|
1899
1973
|
|
@@ -1925,9 +1999,8 @@
|
|
1925
1999
|
* Cross-reference subsection parsing can handle missing whitespace
|
1926
2000
|
* Renamed HexaPDF::Layout::LineFragment to [HexaPDF::Layout::Line]
|
1927
2001
|
* Renamed HexaPDF::Layout::TextBox to [HexaPDF::Layout::TextLayouter]
|
1928
|
-
* [HexaPDF::Layout::TextFragment::new] and
|
1929
|
-
|
1930
|
-
style options
|
2002
|
+
* [HexaPDF::Layout::TextFragment::new] and [HexaPDF::Layout::TextLayouter::new]
|
2003
|
+
to either take a Style object or style options
|
1931
2004
|
* [HexaPDF::Layout::TextLayouter#fit] method signature
|
1932
2005
|
* [HexaPDF::Layout::InlineBox] to wrap a generic box
|
1933
2006
|
* HexaPDF::Document::Fonts#load to [HexaPDF::Document::Fonts#add] for
|
@@ -1989,8 +2062,8 @@
|
|
1989
2062
|
|
1990
2063
|
* Handling of invalid glyphs is done using the special
|
1991
2064
|
[HexaPDF::Font::InvalidGlyph] class
|
1992
|
-
* Configuration option 'font.on_missing_glyph'; returns an invalid glyph
|
1993
|
-
|
2065
|
+
* Configuration option 'font.on_missing_glyph'; returns an invalid glyph instead
|
2066
|
+
of raising an error
|
1994
2067
|
* Bounding box of TrueType glyphs without contours is set to `[0, 0, 0, 0]`
|
1995
2068
|
* Ligature pairs for AFM fonts are stored like kerning pairs
|
1996
2069
|
* Use TrueType configuration option 'font.true_type.unknown_format' in all
|
@@ -2007,8 +2080,8 @@
|
|
2007
2080
|
|
2008
2081
|
* [HexaPDF::Task::Dereference] to work correctly when encountering invalid
|
2009
2082
|
references
|
2010
|
-
* [HexaPDF::Tokenizer] and HexaPDF::Content::Tokenizer to parse a solitary
|
2011
|
-
|
2083
|
+
* [HexaPDF::Tokenizer] and HexaPDF::Content::Tokenizer to parse a solitary plus
|
2084
|
+
sign
|
2012
2085
|
* Usage of Strings instead of Symbols for AFM font kerning and ligature pairs
|
2013
2086
|
* Processing the contents of form XObjects in case they don't have a resources
|
2014
2087
|
dictionary
|
@@ -2031,8 +2104,8 @@
|
|
2031
2104
|
* CLI option `--verbose` for more verbose output; also changed the default
|
2032
2105
|
verbosity level to only display warnings and not informational messages
|
2033
2106
|
* CLI option `--quiet` for suppressing additional and diagnostic output
|
2034
|
-
* CLI option `--strict` for enabling strict parsing and validation; also
|
2035
|
-
|
2107
|
+
* CLI option `--strict` for enabling strict parsing and validation; also changed
|
2108
|
+
the default from strict to non-strict parsing/validation
|
2036
2109
|
* CLI optimization option `--optimize-fonts` for optimizing embedded fonts
|
2037
2110
|
* Method `#word_spacing_applicable?` to font types
|
2038
2111
|
* Support for marked-content points and sequences in [HexaPDF::Content::Canvas]
|
data/examples/019-acro_form.rb
CHANGED
@@ -6,6 +6,11 @@
|
|
6
6
|
# This example show-cases how to create the various form field types and their
|
7
7
|
# possible standard appearances.
|
8
8
|
#
|
9
|
+
# The [HexaPDF::Type::AcroForm::Form] and [HexaPDF::Type::AcroForm::Field]
|
10
|
+
# classes provide a plethora of convenience methods for working with forms, like
|
11
|
+
# for creating fields and their widgets, getting field properties like the full
|
12
|
+
# hierarchical field name or for setting the field value.
|
13
|
+
#
|
9
14
|
# Usage:
|
10
15
|
# : `ruby acro_form.rb`
|
11
16
|
#
|
data/lib/hexapdf/cli/inspect.rb
CHANGED
@@ -117,6 +117,11 @@ module HexaPDF
|
|
117
117
|
|
118
118
|
def execute(file, *commands) #:nodoc:
|
119
119
|
with_document(file, password: @password) do |doc|
|
120
|
+
doc.config['font.on_missing_unicode_mapping'] = lambda do |code, font|
|
121
|
+
$stderr.puts("No Unicode mapping for code point #{code} in font #{font[:BaseFont]}, " \
|
122
|
+
"using the Unicode replacement character")
|
123
|
+
"\u{FFFD}"
|
124
|
+
end
|
120
125
|
@doc = doc
|
121
126
|
if commands.empty?
|
122
127
|
begin
|
data/lib/hexapdf/composer.rb
CHANGED
@@ -450,7 +450,7 @@ module HexaPDF
|
|
450
450
|
(box = draw_box; break) unless box
|
451
451
|
elsif !@frame.find_next_region
|
452
452
|
unless drawn_on_page
|
453
|
-
raise HexaPDF::Error, "Box
|
453
|
+
raise HexaPDF::Error, "Box didn't fit multiple times, even on empty page"
|
454
454
|
end
|
455
455
|
new_page
|
456
456
|
drawn_on_page = false
|
@@ -182,6 +182,16 @@ module HexaPDF
|
|
182
182
|
# acro_form.default_font_size::
|
183
183
|
# A number specifying the default font size of AcroForm text fields which should be auto-sized.
|
184
184
|
#
|
185
|
+
# acro_form.fallback_default_appearance::
|
186
|
+
# A hash containging arguments for
|
187
|
+
# HexaPDF::Type::AcroForm::VariableTextField#set_defaut_appearance_string which is used as
|
188
|
+
# fallback for fields without a default appearance.
|
189
|
+
#
|
190
|
+
# If this value is set to +nil+, an error is raised in case a variable text field cannot
|
191
|
+
# resolve a default appearance string.
|
192
|
+
#
|
193
|
+
# The default is the empty hash meaning the defaults from the method are used.
|
194
|
+
#
|
185
195
|
# acro_form.fallback_font::
|
186
196
|
# The font that should be used when a variable text field references a font that cannot be used.
|
187
197
|
#
|
@@ -277,6 +287,13 @@ module HexaPDF
|
|
277
287
|
#
|
278
288
|
# See PDF2.0 s7.4.1, ADB sH.3 3.3
|
279
289
|
#
|
290
|
+
# font.default::
|
291
|
+
# This font is used by the layout engine when no font is specified but one is needed.
|
292
|
+
#
|
293
|
+
# This is used, for example, for the font set on styles that don't have a font set.
|
294
|
+
#
|
295
|
+
# The default value is 'Times'.
|
296
|
+
#
|
280
297
|
# font.fallback::
|
281
298
|
# An array of fallback font names to be used when replacing invalid glyphs.
|
282
299
|
#
|
@@ -478,6 +495,7 @@ module HexaPDF
|
|
478
495
|
Configuration.new('acro_form.appearance_generator' => 'HexaPDF::Type::AcroForm::AppearanceGenerator',
|
479
496
|
'acro_form.create_appearances' => true,
|
480
497
|
'acro_form.default_font_size' => 10,
|
498
|
+
'acro_form.fallback_default_appearance' => {},
|
481
499
|
'acro_form.fallback_font' => 'Helvetica',
|
482
500
|
'acro_form.on_invalid_value' => proc do |field, value|
|
483
501
|
raise HexaPDF::Error, "Invalid value #{value.inspect} for " \
|
@@ -518,6 +536,7 @@ module HexaPDF
|
|
518
536
|
Crypt: 'HexaPDF::Filter::Crypt',
|
519
537
|
Encryption: 'HexaPDF::Filter::Encryption',
|
520
538
|
},
|
539
|
+
'font.default' => 'Times',
|
521
540
|
'font.fallback' => ['ZapfDingbats', 'Symbol'],
|
522
541
|
'font.map' => {},
|
523
542
|
'font.on_invalid_glyph' => method(:font_on_invalid_glyph),
|
@@ -59,7 +59,11 @@ module HexaPDF
|
|
59
59
|
|
60
60
|
# Returns the time of signing.
|
61
61
|
def signing_time
|
62
|
-
|
62
|
+
if embedded_tsa_signature
|
63
|
+
embedded_tsa_signature.signers.first.signed_time
|
64
|
+
else
|
65
|
+
signer_info.signed_time rescue super
|
66
|
+
end
|
63
67
|
end
|
64
68
|
|
65
69
|
# Returns the certificate chain.
|
@@ -78,6 +82,23 @@ module HexaPDF
|
|
78
82
|
@pkcs7.signers.first
|
79
83
|
end
|
80
84
|
|
85
|
+
# Returns the OpenSSL::PKCS7 object for the embedded TSA signature if there is one or +nil+
|
86
|
+
# otherwise.
|
87
|
+
def embedded_tsa_signature
|
88
|
+
return @embedded_tsa_signature if defined?(@embedded_tsa_signature)
|
89
|
+
|
90
|
+
@embedded_tsa_signature = nil
|
91
|
+
p7 = OpenSSL::ASN1.decode(signature_dict.contents.sub(/\x00*\z/, ''))
|
92
|
+
signed_data = p7.value[1].value[0]
|
93
|
+
signer_info = signed_data.value[-1].value[0] # first (and only) signer info
|
94
|
+
return unless signer_info.value[-1].tag == 1 # check for unsigned attributes
|
95
|
+
timestamp_token = signer_info.value[-1].value.find do |unsigned_attr|
|
96
|
+
unsigned_attr.value[0].value == "id-smime-aa-timeStampToken"
|
97
|
+
end
|
98
|
+
return unless timestamp_token
|
99
|
+
@embedded_tsa_signature = OpenSSL::PKCS7.new(timestamp_token.value[1].value[0])
|
100
|
+
end
|
101
|
+
|
81
102
|
# Verifies the signature using the provided OpenSSL::X509::Store object.
|
82
103
|
def verify(store, allow_self_signed: false)
|
83
104
|
result = super
|
@@ -101,9 +122,16 @@ module HexaPDF
|
|
101
122
|
return result
|
102
123
|
end
|
103
124
|
|
125
|
+
if embedded_tsa_signature
|
126
|
+
result.log(:info, 'Signing time comes from timestamp authority')
|
127
|
+
end
|
128
|
+
|
104
129
|
key_usage = signer_certificate.extensions.find {|ext| ext.oid == 'keyUsage' }
|
105
|
-
|
106
|
-
|
130
|
+
key_usage = key_usage&.value&.split(', ')
|
131
|
+
if key_usage&.include?("Non Repudiation") && !key_usage.include?("Digital Signature")
|
132
|
+
result.log(:info, 'Certificate used for non-repudiation')
|
133
|
+
elsif !key_usage || !key_usage.include?("Digital Signature")
|
134
|
+
result.log(:error, "Certificate key usage is missing 'Digital Signature' or 'Non Repudiation'")
|
107
135
|
end
|
108
136
|
|
109
137
|
if signature_dict.signature_type == 'ETSI.RFC3161'
|
@@ -211,6 +211,13 @@ module HexaPDF
|
|
211
211
|
# The contact information. If used, will be set on the signature dictionary.
|
212
212
|
attr_accessor :contact_info
|
213
213
|
|
214
|
+
# The custom signing time.
|
215
|
+
#
|
216
|
+
# The signing time is usually the time when signing actually happens. This is also what
|
217
|
+
# HexaPDF uses. If it is known that signing happened at a different point in time, that time
|
218
|
+
# can be provided using this accessor.
|
219
|
+
attr_accessor :signing_time
|
220
|
+
|
214
221
|
# The size of the serialized signature that should be reserved.
|
215
222
|
#
|
216
223
|
# If this attribute is not set, an empty string will be signed using #sign to determine the
|
@@ -277,7 +284,7 @@ module HexaPDF
|
|
277
284
|
def finalize_objects(_signature_field, signature)
|
278
285
|
signature[:Filter] = :'Adobe.PPKLite'
|
279
286
|
signature[:SubFilter] = (signature_type == :pades ? :'ETSI.CAdES.detached' : :'adbe.pkcs7.detached')
|
280
|
-
signature[:M] = Time.now
|
287
|
+
signature[:M] = self.signing_time ||= Time.now
|
281
288
|
signature[:Reason] = reason if reason
|
282
289
|
signature[:Location] = location if location
|
283
290
|
signature[:ContactInfo] = contact_info if contact_info
|
@@ -312,6 +319,7 @@ module HexaPDF
|
|
312
319
|
type: signature_type,
|
313
320
|
certificate: certificate, key: key,
|
314
321
|
digest_algorithm: digest_algorithm,
|
322
|
+
signing_time: signing_time,
|
315
323
|
timestamp_handler: timestamp_handler,
|
316
324
|
certificates: certificate_chain, &external_signing).to_der
|
317
325
|
else
|
@@ -84,6 +84,9 @@ module HexaPDF
|
|
84
84
|
# Allowed values: sha256, sha384, sha512.
|
85
85
|
attr_accessor :digest_algorithm
|
86
86
|
|
87
|
+
# The signing time to use instead of Time.now.
|
88
|
+
attr_accessor :signing_time
|
89
|
+
|
87
90
|
# The timestamp handler instance that should be used for timestamping.
|
88
91
|
attr_accessor :timestamp_handler
|
89
92
|
|
@@ -119,9 +122,10 @@ module HexaPDF
|
|
119
122
|
|
120
123
|
# Creates the set of signed attributes for the signer information structure.
|
121
124
|
def create_signed_attrs(data, signing_time: true)
|
125
|
+
signing_time = (self.signing_time || Time.now).utc if signing_time
|
122
126
|
set(
|
123
127
|
attribute('content-type', oid('id-data')),
|
124
|
-
(attribute('id-signingTime', utc_time(
|
128
|
+
(attribute('id-signingTime', utc_time(signing_time)) if signing_time),
|
125
129
|
attribute(
|
126
130
|
'message-digest',
|
127
131
|
binary(OpenSSL::Digest.digest(@digest_algorithm, data))
|