Codebase list libpdf-builder-perl / upstream/3.023+git20220405.1.ca65269
Import upstream version 3.023+git20220405.1.ca65269 Debian Janitor 2 years ago
152 changed file(s) with 1683 addition(s) and 1521 deletion(s). Raw diff Collapse all Expand all
0 See also INFO/Changes-ver_2 for changes released for PDF::API2, and
1 incorporated into PDF::Builder.
2 See also INFO/Changes_2020 for earlier version 3 release logs.
3
4 3.023 2021-07-15
5
6 lib/PDF/Builder.pm, INFO/DEPRECATED
7 FUTURE: Builder.pm's "default()" method may need to be renamed.
8 Some time after Perl 5.26, Perl::Critic started flagging "default" as a
9 reserved keyword. This needs to be further investigated.
10
11 .github/workflows/test.yml Update PATH for new ImageMagick level.
12
13 lib/PDF/Builder/Resource/XObject/Image/TIFF_GT.pm, t/tiff.t
14 Fix for ticket #154 by @carygravel, and add a test for bilevel+alpha
15 where rows are not filling out a full array of bytes.
16
17 version (for distribution build), README.md, lib/PDF/Builder.pm,
18 t/00-all-usable.t, .gitignore
19 Modified to prereq Perl 5.22 instead of 5.20 (is 6 years old now). Also
20 Graphics::TIFF minimum upped to 16 and Image::PNG::Libpng to 0.57 due
21 to changes. Keep files up to date on GitHub so can successfully run
22 without full build. Put "version" in GitHub as it's now fairly involved
23 and I don't want to accidentally lose it!
24
25 Makefile.PL, MANIFEST, META.json (add), META.yml (add), .perl-version
26 (deleted), optional_update.pl (add), README.md
27 Modify build process to have optional prereqs properly installed. Also
28 ensure that mandatory and optional prereqs are consistently updated and
29 handled. Since the vast majority of users will use the default of
30 installing all optional prereqs, the selection process has been moved
31 from Makefile.PL to optional_update.pl (for those manually running
32 Makefile.PL). optional_update.pl updates Makefile.PL, META.json, and
33 META.yml upon selection of which (if any) optional prerequisites are to
34 be installed on a manual run of Makefile.PL. I don't want to risk
35 getting META.json and META.yml (needed for properly installing the
36 "recommends" optionals) out of sync by failing to update them at install
37 from Makefile.PL, so all are now shipped with all optionals selected.
38
39 .gitattributes, .github/workflows/test.yml
40 Added .gitattributes to stop certain line-end changes that were causing
41 CI tests to fail, add Windows tests to CI. From @carygravel.
42
43 lib/PDF/Builder/Content.pm
44 Problem with use of "pi" constant caused a warning on compile in one
45 CPAN smoke test (Perl 5.20 for one tester). Changed "-pi" in one
46 expression to "-1*pi" and hopefully that will silence the messages.
47
48 lib/PDF/Builder.pm, lib/PDF/Builder/Page.pm, INFO/DEPRECATED,
49 t/annotate-deprecations.t
50 Per PDF::API2, simplify Builder's ' fixed' to ' opened'. Rename
51 'openpage()' to 'open_page()' and deprecate old name.
52
53 INFO/Changes-ver_2, t/pdf.t
54 Per changes in PDF::API2, sync up with 2.040 release. There are still
55 a small number of changes not implemented (yet) in PDF::Builder, which
56 either appear to be unnecessary, or the underlying code has changed too
57 much to cleanly port the changes without a massive rewrite.
58
59 t/deprecations.t
60 Update for new PDF::API2 t-tests and a number of other deprecated items.
61 Test both deprecated interfaces and their replacements.
62
63 lib/PDF/Builder/Content/Text.pm, examples/BarCode-Boxes-Content-
64 ContentText-Rotated.pl, examples/021_synfonts-022_truefonts-
65 022_truefonts_diacrits_utf8-023_cjkfonts-024_bdffonts-040_annotation
66 Per 3.022 change of lead() to leading(), update examples to use leading()
67 instead of lead().
68
69 In releases 3.020 through 3.022, INFO/DEPRECATED erroneously listed
70 PDFStr() and PDFUtf() as being scheduled for removal after October 2022.
71 These two routines ARE deprecated (use PDFString() instead), but there
72 are currently no plans to REMOVE them.
73
74 .gitignore, lib/PDF/Builder.pm, lib/PDF/Builder/Basic/PDF/File.pm, t/tiff.t
75 Some minor cleanup, fix TIFF tests because grouped skips don't seem to
76 work properly on Strawberry Perl, initialize $xmin in File.pm to prevent
77 error message.
78
79 lib/PDF/Builder/Basic/PDF/Filter/LZWDecode.pm, lib/PDF/Builder.pm,
80 lib/PDF/Builder/Resource/XObject/Image/TIFF-TIFF_GT.pm,
81 lib/PDF/Builder/Resource/XObject/Image/TIFF/File-File_GT.pm,
82 t/filter-lzwdecode.t, t/tiff.t, t/00-all-usable.t, Makefile.PL
83 Further improvements to TIFF LZW file handling [ref GH 151 and PR 156] for
84 single and multi-strip, and horizontal predictor. Continuation of work
85 to stop converting LZW-compressed TIFF to Flate. Code by @carygravel.
86 Increase required Graphics::TIFF version to 10 due to fix in GT.
87
88 examples/README, examples/examples.output
89 Discuss the issue of close, heavy lines in the example bar codes appearing
90 to merge or "blot" together. This is at least partially a consequence of
91 lower resolution display screens (rounding errors), and although the bars
92 separate when printed, I'm still concerned that they will not be reliably
93 scannable.
94
95 All files (.pm and .pl) containing $LAST_UPDATE can now access this
96 string from outside the file, in the same manner as $VERSION. The
97 variable declarator has been changed from 'my' to 'our' during package
98 build.
99
100 INFO/Changes-ver_2, /lib/PDF/Builder/Basic/PDF/String.pm, t/string.t
101 Per PDF::API2 changes related to [RT 134957], change some regex flags
102 to fix encoding of \n in a PDF string.
103
104 t/tiff.t add version check (not just if installed) for ImageMagick and
105 Ghostscript. Some smoke tests apparently blew up for using too low
106 level versions. If too low version, or any problems determining the
107 version, tiff.t fails gracefully by skipping those tests. From
108 @carygravel.
109
110 t/tiff.t use a temporary directory for various test files, enabling use
111 from a Read-Only directory and/or running tests in parallel (from
112 @ppisar, #153).
113
114 3.022 2021-03-27
115
116 docs/buildDoc.pl add "end of page" (###) marker to make it clear that
117 you're seeing the bottom of the HTML page.
118
119 Update build process to ensure consistent "unix" formatting of most
120 human-readable files (#150). Some non-CPAN builds were complaining
121 about MS-DOS format (CRLF line ends) on some files.
122
123 t/tiff.t, lib/PDF/Builder/Resource/XObject/Image/TIFF-TIFF_GT.pm
124 Per #148, update by carygravel to stop converting LZW-compressed TIFFs
125 to Flate compression (unnecessary, as PDF directly supports LZW, and
126 there were supposedly some edge-case bugs in the code).
127 == REMOVED == still problems, development under way
128
129 t/tiff.t per #143, update by carygravel to enable proper TIFF testing
130 on all platforms including Windows.
131
132 lib/PDF/Builder/Content-Lite.pm, INFO/DEPRECATED, t/content.t
133 Per PDF::API2, deprecated lead() and replace by leading(). Lite's
134 textlead() deprecated and replaced by textleading().
135
136 t/text.t
137 Per PDF::API2 add two tests for charspace and wordspace override, and
138 18 more tests for basic text calls.
139
140 lib/PDF/Builder/Content/Text.pm, INFO/KNOWN_INCOMP
141 Per PDF::API2, add paragraphs() as an alias for section(). Document some
142 minor inconsistencies in option names and behavior introduced with
143 these changes.
144
145 lib/PDF/Builder/Annotation.pm, lib/PDF/Builder/Basic/PDF/Dict-File.pm,
146 lib/PDF/Builder/Resource/Font/SynFont.pm, examples/041_annot_fileattach,
147 examples/060_transparency, examples/resources/sample_55.pdf,
148 examples/resources/HarfBuzz_example.pdf
149 Output 'endobj' starting its own line. Some PDF validators raise a
150 stink if endobj continues a line with other commands on it.
151 While we're at it, put 'stream' starting its own line, too.
152 Fix two examples that failed to validate. There is a third failure, but
153 it appears to be an issue with PDF/A disallowed content (embedded files),
154 not a bug in PDF production here.
155
156 lib/PDF/Builder/Resource/Font/SynFont.pm, INFO/DEPRECATED,
157 examples/025_unifonts, lib/PDF/Builder/Docs.pm
158 Fix uninitialized value (missingwidth), remove -slant (deprecated).
159
160 lib/PDF/Builder/Resource/XObject/Image/TIFF.pm
161 Corrected some bilevel color inverts.
162
163 lib/PDF/Builder/Resource/XObject/Image/TIFF/File_GT.pm,
164 lib/PDF/Builder/Resource/XObject/Image/TIFF_GT.pm
165 Some improvements to deal with inverted colors (black/white) on certain
166 TIFF images. Now G3 and G4 (CCITT Fax) get flipped to the correct
167 colors, as does uncompressed bilevel. There are still some TIFF cases
168 which are not fully properly dealt with; we are still working on them.
169
170 lib/PDF/Builder/Annotation.pm, examples/040_annotation,
171 examples/041_annot_fileattach
172 Add "-opacity" option to control the opacity (opaqueness) of the icon,
173 where the default of 1.0 is fully opaque, and 0.0 is fully transparent.
174 Add "markup" method to implement "highlighted" text annotations, per
175 [GitHub #142]. These include "Highlight" (in the manner of a highlighter
176 marker), "Squiggly" (squiggly underline), "Underline", and "StrikeOut".
177 These behave like a "text" annotation, but instead of an icon, the
178 document text is highlighted.
179
180 lib/PDF/Builder/Content.pm improve -strikethru placement
181
182 INFO/LICENSE, README.md, lib/PDF/Builder/Basic/PDF/Array-Bool-Dict-
183 File-Filter-Name-Null-Number-Objind-Page-Pages-String-Utils.pm
184 Update file headers on code originally written by Martin Hosken to
185 reflect that he has granted permission to use the MIT license instead
186 of the Perl Artistic License on his code. This change was made so
187 that Red Hat could have licensing compatible with LGPL for releasing
188 PDF::Builder as part of Fedora.
189
190 INFO/Changes_2020, Changes, MANIFEST, lib/PDF/Builder.pm, README.md,
191 INFO/LICENSE
192 2021 copyright, archive 2020 changes.
193
194 (see INFO/Changes_2020 for earlier changes)
195 (see INFO/Changes-ver_2 for changes to PDF::API2 up through 2.033)
0 See also INFO/Changes-ver_2 for changes released for PDF::API2, and
1 incorporated into PDF::Builder.
2 See also INFO/Changes_2021 for earlier version 3 release logs.
3
4 3.024 2022-04-05 UNRELEASED
5
6 * lib/PDF/Builder/Basic/PDF/File.pm
7 Per RT 136648, PDF::API2 fix to avoid unnecessary extra trailers.
8
9 META.json, META.yml, MANIFEST add "provides" entry to make package
10 sites happier.
11
12 INFO/RoadMap add comments on PCF-format bitmapped fonts.
13
14 INFO/LICENSE moved to top level, to make package sites happier.
15
16 examples/HarfBuzz.pl, examples/resources/HarfBuzz_example.pdf
17 Add 'fj' and 'ij' ligatures, although Times doesn't appear to include
18 them.
19
20 examples/020_textrise add baselines and additional examples
21
22 examples/HarfBuzz.pl
23 Adobe Acrobat DC has changed its installed fonts location, so several
24 non-Latin entries had to be updated.
25
26 lib/PDF/Builder/Resource/CIDFont.pm
27 Per PDF::API2 code style changes and uninitialized variable fix.
28
29 INFO/Changes_2021, MANIFEST, README.md, lib/PDF/Builder.pm, INFO/LICENSE
30 2022 copyright.
31
32 lib/PDF/Builder/Annotation.pm, t/annotate.t, examples/040_annotation,
33 examples/041_annot_fileattach, examples/042_links
34 Annotations revert to "no border" [#176] to match up with PDF::API2
35 behavior.
36
37 lib/PDF/Builder.pm per #171, allow blank or prefix-only page label (on
38 Reader's thumb slider) with -style => 'nocounter'.
39
40 lib/PDF/Builder/Basic/PDF/Filter/ASCIIHexDecode.pm
41 Per RT 136648, PDF::API2 fix when writing xref streams.
42
43 lib/PDF/Builder/Resource/XObject/Image/GD-GIF-JPEG-PNG-PNM-TIFF.pm
44 Add -name option to name the image object if desired.
45 In sync with PDF::API2, add -compress option for PNM.
46
47 lib/PDF/Builder/Resource/XObject/Image/GIF-PNM.pm minor changes to sync
48 with PDF::API2 changes.
49
50 examples/HarfBuzz.pl, examples/resources/HarfBuzz_example.pdf
51 show a better Chinese (CJK) example in vertical mode, which demonstrates
52 rotation of punctuation such as ( ). Continuation of #144.
53
54 INFO/RoadMap comments on page labeling (slider thumb) enhancements per
55 #171, including possibly integrating with header() and footer() calls
56 that place a page number on the paper, and any outline/bookmarks, so
57 that they all give a consistent page label (number).
58
59 optional_update.pl, MANIFEST, README.md
60 optional_update moved to tools/, otherwise it
61 was being placed in the PDF/ directory by the installer. Note that you
62 should be in your PDF::Builder root (parent of tools/) and run
63 tools/optional_update.pl.
64
65 (see INFO/Changes_2021 for earlier changes)
66 (see INFO/Changes-ver_2 for changes to PDF::API2 up through 2.034)
0 See also INFO/Changes-ver_2 for changes released for PDF::API2, and
1 incorporated into PDF::Builder.
2 See also INFO/Changes_2020 for earlier version 3 release logs.
3
4 3.023 2021-07-15
5
6 lib/PDF/Builder.pm, INFO/DEPRECATED
7 FUTURE: Builder.pm's "default()" method may need to be renamed.
8 Some time after Perl 5.26, Perl::Critic started flagging "default" as a
9 reserved keyword. This needs to be further investigated.
10
11 .github/workflows/test.yml Update PATH for new ImageMagick level.
12
13 lib/PDF/Builder/Resource/XObject/Image/TIFF_GT.pm, t/tiff.t
14 Fix for ticket #154 by @carygravel, and add a test for bilevel+alpha
15 where rows are not filling out a full array of bytes.
16
17 version (for distribution build), README.md, lib/PDF/Builder.pm,
18 t/00-all-usable.t, .gitignore
19 Modified to prereq Perl 5.22 instead of 5.20 (is 6 years old now). Also
20 Graphics::TIFF minimum upped to 16 and Image::PNG::Libpng to 0.57 due
21 to changes. Keep files up to date on GitHub so can successfully run
22 without full build. Put "version" in GitHub as it's now fairly involved
23 and I don't want to accidentally lose it!
24
25 Makefile.PL, MANIFEST, META.json (add), META.yml (add), .perl-version
26 (deleted), optional_update.pl (add), README.md
27 Modify build process to have optional prereqs properly installed. Also
28 ensure that mandatory and optional prereqs are consistently updated and
29 handled. Since the vast majority of users will use the default of
30 installing all optional prereqs, the selection process has been moved
31 from Makefile.PL to optional_update.pl (for those manually running
32 Makefile.PL). optional_update.pl updates Makefile.PL, META.json, and
33 META.yml upon selection of which (if any) optional prerequisites are to
34 be installed on a manual run of Makefile.PL. I don't want to risk
35 getting META.json and META.yml (needed for properly installing the
36 "recommends" optionals) out of sync by failing to update them at install
37 from Makefile.PL, so all are now shipped with all optionals selected.
38
39 .gitattributes, .github/workflows/test.yml
40 Added .gitattributes to stop certain line-end changes that were causing
41 CI tests to fail, add Windows tests to CI. From @carygravel.
42
43 lib/PDF/Builder/Content.pm
44 Problem with use of "pi" constant caused a warning on compile in one
45 CPAN smoke test (Perl 5.20 for one tester). Changed "-pi" in one
46 expression to "-1*pi" and hopefully that will silence the messages.
47
48 lib/PDF/Builder.pm, lib/PDF/Builder/Page.pm, INFO/DEPRECATED,
49 t/annotate-deprecations.t
50 Per PDF::API2, simplify Builder's ' fixed' to ' opened'. Rename
51 'openpage()' to 'open_page()' and deprecate old name.
52
53 INFO/Changes-ver_2, t/pdf.t
54 Per changes in PDF::API2, sync up with 2.040 release. There are still
55 a small number of changes not implemented (yet) in PDF::Builder, which
56 either appear to be unnecessary, or the underlying code has changed too
57 much to cleanly port the changes without a massive rewrite.
58
59 t/deprecations.t
60 Update for new PDF::API2 t-tests and a number of other deprecated items.
61 Test both deprecated interfaces and their replacements.
62
63 lib/PDF/Builder/Content/Text.pm, examples/BarCode-Boxes-Content-
64 ContentText-Rotated.pl, examples/021_synfonts-022_truefonts-
65 022_truefonts_diacrits_utf8-023_cjkfonts-024_bdffonts-040_annotation
66 Per 3.022 change of lead() to leading(), update examples to use leading()
67 instead of lead().
68
69 In releases 3.020 through 3.022, INFO/DEPRECATED erroneously listed
70 PDFStr() and PDFUtf() as being scheduled for removal after October 2022.
71 These two routines ARE deprecated (use PDFString() instead), but there
72 are currently no plans to REMOVE them.
73
74 .gitignore, lib/PDF/Builder.pm, lib/PDF/Builder/Basic/PDF/File.pm, t/tiff.t
75 Some minor cleanup, fix TIFF tests because grouped skips don't seem to
76 work properly on Strawberry Perl, initialize $xmin in File.pm to prevent
77 error message.
78
79 lib/PDF/Builder/Basic/PDF/Filter/LZWDecode.pm, lib/PDF/Builder.pm,
80 lib/PDF/Builder/Resource/XObject/Image/TIFF-TIFF_GT.pm,
81 lib/PDF/Builder/Resource/XObject/Image/TIFF/File-File_GT.pm,
82 t/filter-lzwdecode.t, t/tiff.t, t/00-all-usable.t, Makefile.PL
83 Further improvements to TIFF LZW file handling [ref GH 151 and PR 156] for
84 single and multi-strip, and horizontal predictor. Continuation of work
85 to stop converting LZW-compressed TIFF to Flate. Code by @carygravel.
86 Increase required Graphics::TIFF version to 10 due to fix in GT.
87
88 examples/README, examples/examples.output
89 Discuss the issue of close, heavy lines in the example bar codes appearing
90 to merge or "blot" together. This is at least partially a consequence of
91 lower resolution display screens (rounding errors), and although the bars
92 separate when printed, I'm still concerned that they will not be reliably
93 scannable.
94
95 All files (.pm and .pl) containing $LAST_UPDATE can now access this
96 string from outside the file, in the same manner as $VERSION. The
97 variable declarator has been changed from 'my' to 'our' during package
98 build.
99
100 INFO/Changes-ver_2, /lib/PDF/Builder/Basic/PDF/String.pm, t/string.t
101 Per PDF::API2 changes related to [RT 134957], change some regex flags
102 to fix encoding of \n in a PDF string.
103
104 t/tiff.t add version check (not just if installed) for ImageMagick and
105 Ghostscript. Some smoke tests apparently blew up for using too low
106 level versions. If too low version, or any problems determining the
107 version, tiff.t fails gracefully by skipping those tests. From
108 @carygravel.
109
110 t/tiff.t use a temporary directory for various test files, enabling use
111 from a Read-Only directory and/or running tests in parallel (from
112 @ppisar, #153).
113
114 3.022 2021-03-27
115
116 docs/buildDoc.pl add "end of page" (###) marker to make it clear that
117 you're seeing the bottom of the HTML page.
118
119 Update build process to ensure consistent "unix" formatting of most
120 human-readable files (#150). Some non-CPAN builds were complaining
121 about MS-DOS format (CRLF line ends) on some files.
122
123 t/tiff.t, lib/PDF/Builder/Resource/XObject/Image/TIFF-TIFF_GT.pm
124 Per #148, update by carygravel to stop converting LZW-compressed TIFFs
125 to Flate compression (unnecessary, as PDF directly supports LZW, and
126 there were supposedly some edge-case bugs in the code).
127 == REMOVED == still problems, development under way
128
129 t/tiff.t per #143, update by carygravel to enable proper TIFF testing
130 on all platforms including Windows.
131
132 lib/PDF/Builder/Content-Lite.pm, INFO/DEPRECATED, t/content.t
133 Per PDF::API2, deprecated lead() and replace by leading(). Lite's
134 textlead() deprecated and replaced by textleading().
135
136 t/text.t
137 Per PDF::API2 add two tests for charspace and wordspace override, and
138 18 more tests for basic text calls.
139
140 lib/PDF/Builder/Content/Text.pm, INFO/KNOWN_INCOMP
141 Per PDF::API2, add paragraphs() as an alias for section(). Document some
142 minor inconsistencies in option names and behavior introduced with
143 these changes.
144
145 lib/PDF/Builder/Annotation.pm, lib/PDF/Builder/Basic/PDF/Dict-File.pm,
146 lib/PDF/Builder/Resource/Font/SynFont.pm, examples/041_annot_fileattach,
147 examples/060_transparency, examples/resources/sample_55.pdf,
148 examples/resources/HarfBuzz_example.pdf
149 Output 'endobj' starting its own line. Some PDF validators raise a
150 stink if endobj continues a line with other commands on it.
151 While we're at it, put 'stream' starting its own line, too.
152 Fix two examples that failed to validate. There is a third failure, but
153 it appears to be an issue with PDF/A disallowed content (embedded files),
154 not a bug in PDF production here.
155
156 lib/PDF/Builder/Resource/Font/SynFont.pm, INFO/DEPRECATED,
157 examples/025_unifonts, lib/PDF/Builder/Docs.pm
158 Fix uninitialized value (missingwidth), remove -slant (deprecated).
159
160 lib/PDF/Builder/Resource/XObject/Image/TIFF.pm
161 Corrected some bilevel color inverts.
162
163 lib/PDF/Builder/Resource/XObject/Image/TIFF/File_GT.pm,
164 lib/PDF/Builder/Resource/XObject/Image/TIFF_GT.pm
165 Some improvements to deal with inverted colors (black/white) on certain
166 TIFF images. Now G3 and G4 (CCITT Fax) get flipped to the correct
167 colors, as does uncompressed bilevel. There are still some TIFF cases
168 which are not fully properly dealt with; we are still working on them.
169
170 lib/PDF/Builder/Annotation.pm, examples/040_annotation,
171 examples/041_annot_fileattach
172 Add "-opacity" option to control the opacity (opaqueness) of the icon,
173 where the default of 1.0 is fully opaque, and 0.0 is fully transparent.
174 Add "markup" method to implement "highlighted" text annotations, per
175 [GitHub #142]. These include "Highlight" (in the manner of a highlighter
176 marker), "Squiggly" (squiggly underline), "Underline", and "StrikeOut".
177 These behave like a "text" annotation, but instead of an icon, the
178 document text is highlighted.
179
180 lib/PDF/Builder/Content.pm improve -strikethru placement
181
182 INFO/LICENSE, README.md, lib/PDF/Builder/Basic/PDF/Array-Bool-Dict-
183 File-Filter-Name-Null-Number-Objind-Page-Pages-String-Utils.pm
184 Update file headers on code originally written by Martin Hosken to
185 reflect that he has granted permission to use the MIT license instead
186 of the Perl Artistic License on his code. This change was made so
187 that Red Hat could have licensing compatible with LGPL for releasing
188 PDF::Builder as part of Fedora.
189
190 INFO/Changes_2020, Changes, MANIFEST, lib/PDF/Builder.pm, README.md,
191 INFO/LICENSE
192 2021 copyright, archive 2020 changes.
193
194 (see INFO/Changes_2020 for earlier changes)
195 (see INFO/Changes-ver_2 for changes to PDF::API2 up through 2.033)
55 Bug fixes to PDF::API2 (in PDF::Builder) are not mentioned if they correct
66 an error (that produces an error message and/or incorrect output) and do not
77 affect the operation or results of otherwise correct code.
8
9 3.024 2021-09-27
10
11 PDF::API2 allows a GIF version of 00 to 99, a to z, while PDF::Builder
12 permits 00 to 99, a to b. I am not aware of any GIF versions other than
13 GIF87a and GIF89a, so what is intended is not clear.
814
915 3.022 2021-03-03
1016
+0
-560
INFO/LICENSE less more
0 This software is Copyright (c) 2017-2021 by Phil M. Perry.
1 Previous copyrights are held by Steve Simms, Alfred Reibenschuh, et al.
2
3 Note that some files within this software are under DIFFERENT licenses (than
4 LGPL 2.1). These include (but are not necessarily limited to)
5 PDF::Builder::Matrix (same license as Perl itself), and
6 PDF::Builder::Basic::PDF files (except for the Filters and Literal.pm), which
7 are now under the MIT License (formerly under the Perl Artistic License, which
8 is still permitted). If not otherwise stated in such a file, the overall
9 license is LGPL 2.1, and you may redistribute and/or modify this software under
10 the terms of the indicated license. For LGPL, you are permitted to redistribute
11 and/or modify the software under a version higher than 2.1, at your option).
12
13 This library is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17 This is free software, licensed under:
18
19 The GNU Lesser General Public License, Version 2.1, February 1999
20
21 =============================================================================
22 == Original LGPL 2.1 license text ==
23 =============================================================================
24
25 The GNU Lesser General Public License (LGPL)
26 Version 2.1, February 1999
27
28 (The master copy of this license lives on the GNU website.)
29
30 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59
31 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32
33 Everyone is permitted to copy and distribute verbatim copies
34 of this license document, but changing it is not allowed.
35
36 [This is the first released version of the Lesser GPL. It also
37 counts as the successor of the GNU Library Public License,
38 version 2, hence the version number 2.1.]
39
40 Preamble
41
42 The licenses for most software are designed to take away
43 your freedom to share and change it. By contrast, the GNU
44 General Public Licenses are intended to guarantee your
45 freedom to share and change free software--to make sure the
46 software is free for all its users.
47
48 This license, the Lesser General Public License, applies to
49 some specially designated software packages--typically
50 libraries--of the Free Software Foundation and other authors
51 who decide to use it. You can use it too, but we suggest you
52 first think carefully about whether this license or the ordinary
53 General Public License is the better strategy to use in any
54 particular case, based on the explanations below.
55
56 When we speak of free software, we are referring to freedom
57 of use, not price. Our General Public Licenses are designed
58 to make sure that you have the freedom to distribute copies
59 of free software (and charge for this service if you wish); that
60 you receive source code or can get it if you want it; that you
61 can change the software and use pieces of it in new free
62 programs; and that you are informed that you can do these
63 things.
64
65 To protect your rights, we need to make restrictions that
66 forbid distributors to deny you these rights or to ask you to
67 surrender these rights. These restrictions translate to certain
68 responsibilities for you if you distribute copies of the library
69 or if you modify it.
70
71 For example, if you distribute copies of the library, whether
72 gratis or for a fee, you must give the recipients all the rights
73 that we gave you. You must make sure that they, too,
74 receive or can get the source code. If you link other code
75 with the library, you must provide complete object files to the
76 recipients, so that they can relink them with the library after
77 making changes to the library and recompiling it. And you
78 must show them these terms so they know their rights.
79
80 We protect your rights with a two-step method: (1) we
81 copyright the library, and (2) we offer you this license, which
82 gives you legal permission to copy, distribute and/or modify
83 the library.
84
85 To protect each distributor, we want to make it very clear
86 that there is no warranty for the free library. Also, if the
87 library is modified by someone else and passed on, the
88 recipients should know that what they have is not the original
89 version, so that the original author's reputation will not be
90 affected by problems that might be introduced by others.
91
92 Finally, software patents pose a constant threat to the
93 existence of any free program. We wish to make sure that a
94 company cannot effectively restrict the users of a free
95 program by obtaining a restrictive license from a patent
96 holder. Therefore, we insist that any patent license obtained
97 for a version of the library must be consistent with the full
98 freedom of use specified in this license.
99
100 Most GNU software, including some libraries, is covered by
101 the ordinary GNU General Public License. This license, the
102 GNU Lesser General Public License, applies to certain
103 designated libraries, and is quite different from the ordinary
104 General Public License. We use this license for certain
105 libraries in order to permit linking those libraries into non-free
106 programs.
107
108 When a program is linked with a library, whether statically or
109 using a shared library, the combination of the two is legally
110 speaking a combined work, a derivative of the original library.
111 The ordinary General Public License therefore permits such
112 linking only if the entire combination fits its criteria of
113 freedom. The Lesser General Public License permits more
114 lax criteria for linking other code with the library.
115
116 We call this license the "Lesser" General Public License
117 because it does Less to protect the user's freedom than the
118 ordinary General Public License. It also provides other free
119 software developers Less of an advantage over competing
120 non-free programs. These disadvantages are the reason we
121 use the ordinary General Public License for many libraries.
122 However, the Lesser license provides advantages in certain
123 special circumstances.
124
125 For example, on rare occasions, there may be a special
126 need to encourage the widest possible use of a certain
127 library, so that it becomes a de-facto standard. To achieve
128 this, non-free programs must be allowed to use the library. A
129 more frequent case is that a free library does the same job
130 as widely used non-free libraries. In this case, there is little
131 to gain by limiting the free library to free software only, so we
132 use the Lesser General Public License.
133
134 In other cases, permission to use a particular library in
135 non-free programs enables a greater number of people to use
136 a large body of free software. For example, permission to
137 use the GNU C Library in non-free programs enables many
138 more people to use the whole GNU operating system, as
139 well as its variant, the GNU/Linux operating system.
140
141 Although the Lesser General Public License is Less
142 protective of the users' freedom, it does ensure that the user
143 of a program that is linked with the Library has the freedom
144 and the wherewithal to run that program using a modified
145 version of the Library.
146
147 The precise terms and conditions for copying, distribution
148 and modification follow. Pay close attention to the difference
149 between a "work based on the library" and a "work that uses
150 the library". The former contains code derived from the
151 library, whereas the latter must be combined with the library
152 in order to run.
153
154 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION
155 AND MODIFICATION
156
157 0. This License Agreement applies to any software library or
158 other program which contains a notice placed by the
159 copyright holder or other authorized party saying it may be
160 distributed under the terms of this Lesser General Public
161 License (also called "this License"). Each licensee is
162 addressed as "you".
163
164 A "library" means a collection of software functions and/or
165 data prepared so as to be conveniently linked with
166 application programs (which use some of those functions
167 and data) to form executables.
168
169 The "Library", below, refers to any such software library or
170 work which has been distributed under these terms. A "work
171 based on the Library" means either the Library or any
172 derivative work under copyright law: that is to say, a work
173 containing the Library or a portion of it, either verbatim or with
174 modifications and/or translated straightforwardly into another
175 language. (Hereinafter, translation is included without
176 limitation in the term "modification".)
177
178 "Source code" for a work means the preferred form of the
179 work for making modifications to it. For a library, complete
180 source code means all the source code for all modules it
181 contains, plus any associated interface definition files, plus
182 the scripts used to control compilation and installation of the
183 library.
184
185 Activities other than copying, distribution and modification
186 are not covered by this License; they are outside its scope.
187 The act of running a program using the Library is not
188 restricted, and output from such a program is covered only if
189 its contents constitute a work based on the Library
190 (independent of the use of the Library in a tool for writing it).
191 Whether that is true depends on what the Library does and
192 what the program that uses the Library does.
193
194 1. You may copy and distribute verbatim copies of the
195 Library's complete source code as you receive it, in any
196 medium, provided that you conspicuously and appropriately
197 publish on each copy an appropriate copyright notice and
198 disclaimer of warranty; keep intact all the notices that refer
199 to this License and to the absence of any warranty; and
200 distribute a copy of this License along with the Library.
201
202 You may charge a fee for the physical act of transferring a
203 copy, and you may at your option offer warranty protection in
204 exchange for a fee.
205
206 2. You may modify your copy or copies of the Library or any
207 portion of it, thus forming a work based on the Library, and
208 copy and distribute such modifications or work under the
209 terms of Section 1 above, provided that you also meet all of
210 these conditions:
211
212 a) The modified work must itself be a software
213 library.
214 b) You must cause the files modified to carry
215 prominent notices stating that you changed the
216 files and the date of any change.
217 c) You must cause the whole of the work to be
218 licensed at no charge to all third parties under
219 the terms of this License.
220 d) If a facility in the modified Library refers to a
221 function or a table of data to be supplied by an
222 application program that uses the facility, other
223 than as an argument passed when the facility
224 is invoked, then you must make a good faith
225 effort to ensure that, in the event an application
226 does not supply such function or table, the
227 facility still operates, and performs whatever
228 part of its purpose remains meaningful.
229
230 (For example, a function in a library to
231 compute square roots has a purpose that is
232 entirely well-defined independent of the
233 application. Therefore, Subsection 2d requires
234 that any application-supplied function or table
235 used by this function must be optional: if the
236 application does not supply it, the square root
237 function must still compute square roots.)
238
239 These requirements apply to the modified work
240 as a whole. If identifiable sections of that work
241 are not derived from the Library, and can be
242 reasonably considered independent and
243 separate works in themselves, then this
244 License, and its terms, do not apply to those
245 sections when you distribute them as separate
246 works. But when you distribute the same
247 sections as part of a whole which is a work
248 based on the Library, the distribution of the
249 whole must be on the terms of this License,
250 whose permissions for other licensees extend
251 to the entire whole, and thus to each and every
252 part regardless of who wrote it.
253
254 Thus, it is not the intent of this section to claim
255 rights or contest your rights to work written
256 entirely by you; rather, the intent is to exercise
257 the right to control the distribution of derivative
258 or collective works based on the Library.
259
260 In addition, mere aggregation of another work
261 not based on the Library with the Library (or
262 with a work based on the Library) on a volume
263 of a storage or distribution medium does not
264 bring the other work under the scope of this
265 License.
266
267 3. You may opt to apply the terms of the ordinary GNU
268 General Public License instead of this License to a given
269 copy of the Library. To do this, you must alter all the notices
270 that refer to this License, so that they refer to the ordinary
271 GNU General Public License, version 2, instead of to this
272 License. (If a newer version than version 2 of the ordinary
273 GNU General Public License has appeared, then you can
274 specify that version instead if you wish.) Do not make any
275 other change in these notices.
276
277 Once this change is made in a given copy, it is irreversible
278 for that copy, so the ordinary GNU General Public License
279 applies to all subsequent copies and derivative works made
280 from that copy.
281
282 This option is useful when you wish to copy part of the code
283 of the Library into a program that is not a library.
284
285 4. You may copy and distribute the Library (or a portion or
286 derivative of it, under Section 2) in object code or executable
287 form under the terms of Sections 1 and 2 above provided that
288 you accompany it with the complete corresponding
289 machine-readable source code, which must be distributed
290 under the terms of Sections 1 and 2 above on a medium
291 customarily used for software interchange.
292
293 If distribution of object code is made by offering access to
294 copy from a designated place, then offering equivalent
295 access to copy the source code from the same place
296 satisfies the requirement to distribute the source code, even
297 though third parties are not compelled to copy the source
298 along with the object code.
299
300 5. A program that contains no derivative of any portion of the
301 Library, but is designed to work with the Library by being
302 compiled or linked with it, is called a "work that uses the
303 Library". Such a work, in isolation, is not a derivative work of
304 the Library, and therefore falls outside the scope of this
305 License.
306
307 However, linking a "work that uses the Library" with the
308 Library creates an executable that is a derivative of the
309 Library (because it contains portions of the Library), rather
310 than a "work that uses the library". The executable is
311 therefore covered by this License. Section 6 states terms for
312 distribution of such executables.
313
314 When a "work that uses the Library" uses material from a
315 header file that is part of the Library, the object code for the
316 work may be a derivative work of the Library even though the
317 source code is not. Whether this is true is especially
318 significant if the work can be linked without the Library, or if
319 the work is itself a library. The threshold for this to be true is
320 not precisely defined by law.
321
322 If such an object file uses only numerical parameters, data
323 structure layouts and accessors, and small macros and
324 small inline functions (ten lines or less in length), then the
325 use of the object file is unrestricted, regardless of whether it
326 is legally a derivative work. (Executables containing this
327 object code plus portions of the Library will still fall under
328 Section 6.)
329
330 Otherwise, if the work is a derivative of the Library, you may
331 distribute the object code for the work under the terms of
332 Section 6. Any executables containing that work also fall
333 under Section 6, whether or not they are linked directly with
334 the Library itself.
335
336 6. As an exception to the Sections above, you may also
337 combine or link a "work that uses the Library" with the
338 Library to produce a work containing portions of the Library,
339 and distribute that work under terms of your choice, provided
340 that the terms permit modification of the work for the
341 customer's own use and reverse engineering for debugging
342 such modifications.
343
344 You must give prominent notice with each copy of the work
345 that the Library is used in it and that the Library and its use
346 are covered by this License. You must supply a copy of this
347 License. If the work during execution displays copyright
348 notices, you must include the copyright notice for the Library
349 among them, as well as a reference directing the user to the
350 copy of this License. Also, you must do one of these things:
351
352 a) Accompany the work with the complete
353 corresponding machine-readable source code
354 for the Library including whatever changes were
355 used in the work (which must be distributed
356 under Sections 1 and 2 above); and, if the work
357 is an executable linked with the Library, with
358 the complete machine-readable "work that
359 uses the Library", as object code and/or
360 source code, so that the user can modify the
361 Library and then relink to produce a modified
362 executable containing the modified Library. (It
363 is understood that the user who changes the
364 contents of definitions files in the Library will
365 not necessarily be able to recompile the
366 application to use the modified definitions.)
367
368 b) Use a suitable shared library mechanism for
369 linking with the Library. A suitable mechanism
370 is one that (1) uses at run time a copy of the
371 library already present on the user's computer
372 system, rather than copying library functions
373 into the executable, and (2) will operate
374 properly with a modified version of the library, if
375 the user installs one, as long as the modified
376 version is interface-compatible with the version
377 that the work was made with.
378
379 c) Accompany the work with a written offer,
380 valid for at least three years, to give the same
381 user the materials specified in Subsection 6a,
382 above, for a charge no more than the cost of
383 performing this distribution.
384
385 d) If distribution of the work is made by offering
386 access to copy from a designated place, offer
387 equivalent access to copy the above specified
388 materials from the same place.
389
390 e) Verify that the user has already received a
391 copy of these materials or that you have
392 already sent this user a copy.
393
394 For an executable, the required form of the "work that uses
395 the Library" must include any data and utility programs
396 needed for reproducing the executable from it. However, as a
397 special exception, the materials to be distributed need not
398 include anything that is normally distributed (in either source
399 or binary form) with the major components (compiler, kernel,
400 and so on) of the operating system on which the executable
401 runs, unless that component itself accompanies the
402 executable.
403
404 It may happen that this requirement contradicts the license
405 restrictions of other proprietary libraries that do not normally
406 accompany the operating system. Such a contradiction
407 means you cannot use both them and the Library together in
408 an executable that you distribute.
409
410 7. You may place library facilities that are a work based on
411 the Library side-by-side in a single library together with other
412 library facilities not covered by this License, and distribute
413 such a combined library, provided that the separate
414 distribution of the work based on the Library and of the other
415 library facilities is otherwise permitted, and provided that you
416 do these two things:
417
418 a) Accompany the combined library with a
419 copy of the same work based on the Library,
420 uncombined with any other library facilities.
421 This must be distributed under the terms of the
422 Sections above.
423
424 b) Give prominent notice with the combined
425 library of the fact that part of it is a work based
426 on the Library, and explaining where to find the
427 accompanying uncombined form of the same
428 work.
429
430 8. You may not copy, modify, sublicense, link with, or
431 distribute the Library except as expressly provided under this
432 License. Any attempt otherwise to copy, modify, sublicense,
433 link with, or distribute the Library is void, and will
434 automatically terminate your rights under this License.
435 However, parties who have received copies, or rights, from
436 you under this License will not have their licenses terminated
437 so long as such parties remain in full compliance.
438
439 9. You are not required to accept this License, since you
440 have not signed it. However, nothing else grants you
441 permission to modify or distribute the Library or its derivative
442 works. These actions are prohibited by law if you do not
443 accept this License. Therefore, by modifying or distributing
444 the Library (or any work based on the Library), you indicate
445 your acceptance of this License to do so, and all its terms
446 and conditions for copying, distributing or modifying the
447 Library or works based on it.
448
449 10. Each time you redistribute the Library (or any work
450 based on the Library), the recipient automatically receives a
451 license from the original licensor to copy, distribute, link with
452 or modify the Library subject to these terms and conditions.
453 You may not impose any further restrictions on the
454 recipients' exercise of the rights granted herein. You are not
455 responsible for enforcing compliance by third parties with this
456 License.
457
458 11. If, as a consequence of a court judgment or allegation of
459 patent infringement or for any other reason (not limited to
460 patent issues), conditions are imposed on you (whether by
461 court order, agreement or otherwise) that contradict the
462 conditions of this License, they do not excuse you from the
463 conditions of this License. If you cannot distribute so as to
464 satisfy simultaneously your obligations under this License
465 and any other pertinent obligations, then as a consequence
466 you may not distribute the Library at all. For example, if a
467 patent license would not permit royalty-free redistribution of
468 the Library by all those who receive copies directly or
469 indirectly through you, then the only way you could satisfy
470 both it and this License would be to refrain entirely from
471 distribution of the Library.
472
473 If any portion of this section is held invalid or unenforceable
474 under any particular circumstance, the balance of the
475 section is intended to apply, and the section as a whole is
476 intended to apply in other circumstances.
477
478 It is not the purpose of this section to induce you to infringe
479 any patents or other property right claims or to contest
480 validity of any such claims; this section has the sole purpose
481 of protecting the integrity of the free software distribution
482 system which is implemented by public license practices.
483 Many people have made generous contributions to the wide
484 range of software distributed through that system in reliance
485 on consistent application of that system; it is up to the
486 author/donor to decide if he or she is willing to distribute
487 software through any other system and a licensee cannot
488 impose that choice.
489
490 This section is intended to make thoroughly clear what is
491 believed to be a consequence of the rest of this License.
492
493 12. If the distribution and/or use of the Library is restricted in
494 certain countries either by patents or by copyrighted
495 interfaces, the original copyright holder who places the
496 Library under this License may add an explicit geographical
497 distribution limitation excluding those countries, so that
498 distribution is permitted only in or among countries not thus
499 excluded. In such case, this License incorporates the
500 limitation as if written in the body of this License.
501
502 13. The Free Software Foundation may publish revised
503 and/or new versions of the Lesser General Public License
504 from time to time. Such new versions will be similar in spirit
505 to the present version, but may differ in detail to address new
506 problems or concerns.
507
508 Each version is given a distinguishing version number. If the
509 Library specifies a version number of this License which
510 applies to it and "any later version", you have the option of
511 following the terms and conditions either of that version or of
512 any later version published by the Free Software Foundation.
513 If the Library does not specify a license version number, you
514 may choose any version ever published by the Free Software
515 Foundation.
516
517 14. If you wish to incorporate parts of the Library into other
518 free programs whose distribution conditions are incompatible
519 with these, write to the author to ask for permission. For
520 software which is copyrighted by the Free Software
521 Foundation, write to the Free Software Foundation; we
522 sometimes make exceptions for this. Our decision will be
523 guided by the two goals of preserving the free status of all
524 derivatives of our free software and of promoting the sharing
525 and reuse of software generally.
526
527 NO WARRANTY
528
529 15. BECAUSE THE LIBRARY IS LICENSED FREE OF
530 CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY,
531 TO THE EXTENT PERMITTED BY APPLICABLE LAW.
532 EXCEPT WHEN OTHERWISE STATED IN WRITING THE
533 COPYRIGHT HOLDERS AND/OR OTHER PARTIES
534 PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY
535 OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
536 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
537 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
538 A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
539 QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
540 YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
541 ASSUME THE COST OF ALL NECESSARY SERVICING,
542 REPAIR OR CORRECTION.
543
544 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE
545 LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
546 HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
547 AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED
548 ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
549 ANY GENERAL, SPECIAL, INCIDENTAL OR
550 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
551 OR INABILITY TO USE THE LIBRARY (INCLUDING BUT
552 NOT LIMITED TO LOSS OF DATA OR DATA BEING
553 RENDERED INACCURATE OR LOSSES SUSTAINED BY
554 YOU OR THIRD PARTIES OR A FAILURE OF THE
555 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
556 EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
557 ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
558
559 END OF TERMS AND CONDITIONS
0 Road Map for Future Development of PDF::Builder 02 July 2021
0 Road Map for Future Development of PDF::Builder 09 September 2021
11
22 In order to encourage others to contribute code and/or algorithms to the
33 effort, I am publishing this road map of where I would like the product to go.
4747
4848 UPDATE: See Text::Layout and HarfBuzz::Shaper packages. Layout is usable
4949 with Builder (but no explicit support yet). Shaper is supported by Builder
50 for ligatures and complex scripts.
50 for ligatures and complex scripts. Need to see if it supports true small
51 and petite capitals (included with font) as a sort of alternate glyphs.
52 It's probably not feasible to decompose outline fonts and shrink them
53 down nonlinearly (stroke widths reduced less than overall height/width)
54 and recreate the new outlines as synthetic small/petite caps.
5155
5256 B. Unification of font support: including character set and encoding support
5357 improvements [see CTS 16 and CTS 23] to make more commonality between using
212216 during render to the file? Another possibility is to use a negative
213217 Y-coordinate to mean "place me at the bottom". Also remember that beyond
214218 200 inches in height, support in readers and tools will vary.
219
220 T. Extend the pageLabel() call to not only label the reader's thumb, but
221 also place the SAME page label text somewhere on the page. This might be
222 combined with header() and footer() calls, possibly to call pageLabel()
223 when the page numbering field is encountered (if flag set to do both).
224 The idea is to minimize labor and ensure a consistent page numbering
225 between the paper and the reader's thumb. header() and footer() might be
226 placed in the top and bottom margins, leaving it to the user not to write
227 into these areas. See #171 for pageLabel() enhancements. Also, page label
228 for outlines/bookmarks should be consistent with the thumb and what's
229 printed on the page. A manual page number call to put the page label on
230 an arbitrary place (such as centered in the outside margin) would be good.
231
232 U. Consider PCF (bitmapped font format) font support, in a manner similar to
233 the more primitive BDF support. PCF fonts are common on some systems (X11
234 used them extensively), but it's unlikely that there would be much interest
235 to widely use them today.
236 See https://fontforge.org/docs/techref/pcf-format.html
215237
216238 =============================================================================
217239 II. Items to add to a separate area (new module or sub-module)
(No changes)
(No changes)
(No changes)
2525 perl t\extgstate.t
2626 perl t\filter-ascii85decode.t
2727 perl t\filter-asciihexdecode.t
28 REM perl t\filter-ccittfaxdecode.t # add when TIFF changes go in
2829 perl t\filter-runlengthdecode.t
2930 perl t\font-corefont.t
3031 perl t\font-synfont.t
00 # This file is manually maintained
1 # if add or delete a .pm file, also update META.yml and META.json files
12 .perlcriticrc
23 Changes
34 CONTRIBUTING
56 MANIFEST
67 META.json
78 META.yml
8 optional_update.pl
99 README.md
1010 tools/1_pc.pl
1111 tools/2_t-tests.pl
1212 tools/3_examples.pl
1313 tools/4_contrib.pl
14 tools/optional_update.pl
1415 tools/TTFdump.pl
1516 INFO/Changes_2017
1617 INFO/Changes_2018
1718 INFO/Changes_2019
1819 INFO/Changes_2020
20 INFO/Changes_2021
1921 INFO/Changes-ver_2
2022 INFO/CONVERSION
2123 INFO/DEPRECATED
223225 t/filter-ascii85decode.t
224226 t/filter-asciihexdecode.t
225227 t/filter-lzwdecode.t
228 #t/filter-ccittfaxdecode.t
226229 t/filter-runlengthdecode.t
227230 t/font-corefont.t
228231 t/font-synfont.t
4949 PREREQ_PM => {
5050 "Compress::Zlib" => 1.0,
5151 "Font::TTF" => 1.04,
52 # "Readonly" => 0, use when TIFF changes go in
5253
5354 # === found in CORE, so no need to explicitly list
5455 #"Carp" => 0,
9798 # recommends (optional prereqs) goes here
9899 # if remove or comment out any, also do so in META.json and META.yml
99100 "recommends" => {
100 "Graphics::TIFF" => 16,
101 "Graphics::TIFF" => 16, # will be 17 when TIFF changes go in
101102 # advanced/fast PNG image processing.
102103 "Image::PNG::Libpng" => 0.57,
103104 # text shaping for Latin script ligatures and kerning, and for
2424 PDF::Builder::Docs, and decide whether or not you want to install any of them.
2525 By default, all are installed (as "recommended", so failure to install will
2626 not fail the overall PDF::Builder installation). You may choose which ones to
27 install by modifying certain installation files with "optional\_update.pl".
27 install by modifying certain installation files with
28 "tools/optional\_update.pl".
2829
2930 ## Requirements
3031
7677
7778 These libraries are _recommended_ for improved functionality and performance.
7879 The default behavior is to attempt to install all of them during PDF::Builder
79 installation. If you use optional\_update.pl to _not_ to install any of
80 installation. If you use tools/optional\_update.pl to _not_ to install any of
8081 them, or they fail to install automatically, you can always manually install
8182 them later.
8283
9293
9394 ## Copyright
9495
95 This software is Copyright (c) 2017-2021 by Phil M. Perry.
96 This software is Copyright (c) 2017-2022 by Phil M. Perry.
9697
9798 Previous copyrights are held by others (Steve Simms, Alfred Reibenschuh, et al.).
9899
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
77
88 use PDF::Builder;
99
33
44 use PDF::Builder::Basic::PDF::File;
55
6 our $VERSION = '3.023'; # VERSION
7 our $LAST_UPDATE = '3.010'; # manually update whenever code is changed
6 # VERSION
7 my $LAST_UPDATE = '3.010'; # manually update whenever code is changed
88
99 my $file = shift(@ARGV);
1010 unless ($file) {
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.016'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.016'; # manually update whenever code is changed
77
88 use PDF::Builder::Basic::PDF::File;
99 use PDF::Builder::Basic::PDF::Utils;
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.016'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.016'; # manually update whenever code is changed
77
88 use PDF::Builder::Basic::PDF::File;
99 use PDF::Builder::Basic::PDF::Utils;
7171 use strict;
7272 use warnings;
7373
74 our $VERSION = '3.023'; # VERSION
75 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
74 # VERSION
75 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
7676
7777 use PDF::Builder;
7878 use PDF::Builder::Util;
1515 use warnings;
1616 use Getopt::Long;
1717
18 our $VERSION = '3.023'; # VERSION
19 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
18 # VERSION
19 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2020
2121 # =============
2222 # CONFIGURATION these may be overridden by command-line flags. If reading from
1111 my $pdf = PDF::Builder->new(-compress => $compress);
1212
1313 my $f1=$pdf->corefont('Helvetica', -encode=>'latin1');
14 my $f2=$pdf->corefont('Helvetica-Bold', -encode=>'latin1');
14 my $f2=$pdf->corefont('Helvetica-Oblique', -encode=>'latin1');
1515
1616 my $page = $pdf->page();
17 $page->mediabox(595,842);
17 $page->mediabox(595,842); # A4 paper
1818
1919 my $txt = $page->text();
20 $txt->font($f1, 20);
20 my $grf = $page->gfx();
21 #$txt->font($f1, 20);
22 my $fsize = 20; # our standard font size for this page
23 my $subsupscl = 0.7; # scale factor for sub and superscripts
24
25 $grf->strokecolor('green'); # just leave line color as green
2126
2227 # rises (up +, down -) are relative to original baseline, not previous text
23
28 # further note that these are baseline changes, with no guarantee that text
29 # will not ascend above the original baseline (i.e., it is NOT the distance
30 # between the baseline and the TOP of the text!)
31
32 $grf->poly(50,800, 430,800);
33 $grf->poly(420,805, 430,805, 430,795, 420,795);
34 $grf->stroke();
35 $txt->translate(435,800);
36 $txt->fillcolor('green');
37 $txt->font($f1, $fsize*$subsupscl);
38 $txt->text('Baseline');
39
40 $txt->fillcolor('black');
41 $txt->font($f1, $fsize);
2442 $txt->translate(50,800);
25 $txt->text('normal text');
43 $txt->text('normal text ');
2644 $txt->rise(5);
2745 $txt->text('rise = 5 units');
2846 $txt->rise(-5);
2947 $txt->text('rise = -5 units');
3048 $txt->rise(0);
3149
50 # ----------------------------
51 $grf->poly(50,600, 430,600);
52 $grf->poly(420,610, 430,610, 430,590, 420,590);
53 $grf->stroke();
54 $txt->translate(435,600);
55 $txt->fillcolor('green');
56 $txt->font($f1, $fsize*$subsupscl);
57 $txt->text('Baseline');
58
59 $txt->fillcolor('black');
60 $txt->font($f1, $fsize);
3261 $txt->translate(50,600);
33 $txt->text('normal text');
62 $txt->text('normal text ');
3463 $txt->rise(10);
3564 $txt->text('rise = 10 units');
3665 $txt->rise(-10);
3766 $txt->text('rise = -10 units');
3867 $txt->rise(0);
3968
69 # ----------------------------
70 $grf->poly(50,400, 430,400);
71 $grf->poly(420,420, 430,420, 430,380, 420,380);
72 $grf->stroke();
73 $txt->translate(435,400);
74 $txt->fillcolor('green');
75 $txt->font($f1, $fsize*$subsupscl);
76 $txt->text('Baseline');
77
78 $txt->fillcolor('black');
79 $txt->font($f1, $fsize);
4080 $txt->translate(50,400);
41 $txt->text('normal text');
81 $txt->text('normal text ');
4282 $txt->rise(20);
4383 $txt->text('rise = 20 units');
4484 $txt->rise(-20);
4585 $txt->text('rise = -20 units');
4686 $txt->rise(0);
4787
88 # ----------------------------
89 # now for a line of text
90 # it would be good to consider a convenience function for
91 # subscript($scale,$font,$fontsize,$text) and likewise for superscript()
92 $txt->translate(50, 200);
93 $txt->text('The gases CO');
94 # $txt->subscript($subsupscl, $f1, $fsize, '2');
95 $txt->font($f1,$fsize*$subsupscl);
96 $txt->rise(-10*$subsupscl);
97 $txt->text('2');
98 $txt->rise(0);
99 $txt->font($f1,$fsize);
100 $txt->text(' and CH');
101 # $txt->subscript($subsupscl, $f1, $fsize, '4');
102 $txt->font($f1,$fsize*$subsupscl);
103 $txt->rise(-10*$subsupscl);
104 $txt->text('4');
105 $txt->rise(0);
106 $txt->font($f1,$fsize);
107 $txt->text(' are of concern for climate change.');
108
109 # ----------------------------
110 # and a math equation with sub- and superscripts
111 # italicize all variable name letters not function names
112 $txt->translate(50,100);
113 $txt->font($f2, $fsize); # italic y
114 $txt->text('y');
115 $txt->font($f1, $fsize); # roman = a
116 $txt->text(' = a');
117 # $txt->subscript($subsupscl, $f1, $fsize, '2');
118 $txt->font($f1,$fsize*$subsupscl); # <sub>2</sub>
119 $txt->rise(-10*$subsupscl);
120 $txt->text('2');
121 $txt->rise(0);
122 $txt->font($f2,$fsize); # italic x
123 $txt->text('x');
124 # $txt->superscript($subsupscl, $f1, $fsize, '2');
125 $txt->font($f1,$fsize*$subsupscl); # <sup>2</sup>
126 $txt->rise(10*$subsupscl);
127 $txt->text('2');
128 $txt->rise(0);
129 $txt->font($f1,$fsize);
130 $txt->text(' + a'); # roman + a
131 # $txt->subscript($subsupscl, $f1, $fsize, '1');
132 $txt->font($f1,$fsize*$subsupscl); # <sub>1</sub>
133 $txt->rise(-10*$subsupscl);
134 $txt->text('1');
135 $txt->rise(0);
136 $txt->font($f2,$fsize); # italic x
137 $txt->text('x');
138 # $txt->superscript($subsupscl, $f1, $fsize, '2');
139 $txt->font($f1,$fsize*$subsupscl); # <sup>1</sup>
140 $txt->rise(10*$subsupscl);
141 $txt->text('1');
142 $txt->rise(0);
143 $txt->font($f1,$fsize);
144 $txt->text(' + a'); # roman + a
145 # $txt->subscript($subsupscl, $f1, $fsize, '0');
146 $txt->font($f1,$fsize*$subsupscl); # <sub>0</sub>
147 $txt->rise(-10*$subsupscl);
148 $txt->text('0');
149 $txt->rise(0);
150 $txt->font($f1,$fsize);
151 $txt->text(' is an equation.');
152
153 # ----------------------------
154 # ah, just for the halibut, use functions
155 $txt->translate(50,65);
156 $txt->font($f2, $fsize); # italic y
157 $txt->text('y');
158 $txt->font($f1, $fsize); # roman = a
159 $txt->text(' = a');
160 subscript($subsupscl, $f1, $fsize, '3'); # <sub>3</sub>
161 $txt->font($f2,$fsize); # italic x
162 $txt->text('x');
163 superscript($subsupscl, $f1, $fsize, '3'); # <sup>3</sup>
164 $txt->font($f1,$fsize);
165 $txt->text(' + a'); # roman + a
166 subscript($subsupscl, $f1, $fsize, '2'); # <sub>2</sub>
167 $txt->font($f2,$fsize); # italic x
168 $txt->text('x');
169 superscript($subsupscl, $f1, $fsize, '2'); # <sup>2</sup>
170 $txt->font($f1,$fsize);
171 $txt->text(' + a'); # roman + a
172 subscript($subsupscl, $f1, $fsize, '1'); # <sub>1</sub>
173 $txt->font($f2,$fsize); # italic x
174 $txt->text('x');
175 superscript($subsupscl, $f1, $fsize, '1'); # <sup>1</sup>
176 $txt->font($f1,$fsize);
177 $txt->text(' + a'); # roman + a
178 subscript($subsupscl, $f1, $fsize, '0'); # <sub>0</sub>
179 $txt->font($f1,$fsize);
180 $txt->text(' is done with functions.');
181
182 # ----------------------------
48183 $pdf->saveas("$0.pdf");
49184 $pdf->end();
50185
51186 exit;
52187
188 # TBD These might go into content or content::text.
189 # As a method, $txt might not have to be passed in if can use $self.
190 # It might be a good idea to save and restore the font and size, too
191 # (might need to extend font() method to return the current font and size).
192 # Restores old rise() value, such as for putting superscript on a
193 # subscript, etc., instead of hardcoded 0. Use the current font size
194 # instead of passing it in. Could have optional values to override the
195 # font, size, rise %, etc., by default using the old font. The sub/sup scale
196 # might default, with an override (is it strongly dependent on font?).
197 # Potentially only the $text might be a mandatory parameter, or combine
198 # the functions with a 'sup' or 'sub' parameter, since only one line diff.
199 # TBD Probably doesn't yet handle super on sub and vice-versa, or super on
200 # super, etc. Needs more thought.
201 sub subscript {
202 my ($subsupscl, $font, $fsize, $text) = @_;
203 my $oldRise = $txt->rise();
204 # save old font here -- need anyway for font() call unless override given
205 $txt->font($font, $fsize*$subsupscl);
206 $txt->rise(-$fsize/2*$subsupscl);
207 $txt->text($text);
208 # restore old font here
209 $txt->rise($oldRise);
210 return;
211 }
212
213 sub superscript {
214 my ($subsupscl, $font, $fsize, $text) = @_;
215 my $oldRise = $txt->rise();
216 # save old font here -- need anyway for font() call unless override given
217 $txt->font($font, $fsize*$subsupscl);
218 $txt->rise($fsize/2*$subsupscl);
219 $txt->text($text);
220 # restore old font here
221 $txt->rise($oldRise);
222 return;
223 }
224
53225 __END__
2020 my $sx = 33;
2121 my $sy = 45;
2222 my $fx = 20;
23 #my $LoremIpsum = qq|Spin\x{0308}al Tap says: Sed ut perspici\x{0361}atis.|; # times.ttf includes
2324 my $LoremIpsum = qq|Sed ut perspici\x{0361}atis.|; # times.ttf includes
25 # U+0308 is combining diaeresis (spans n) unfortunately, doesn't quite align
2426 # U+0361 is combining double inverted breve (spans i to t)
2527 # "use utf8" says to interpret string as UTF-8
2628 my $encoding = 'latin1';
1313 my $compress = 'none'; # uncompressed streams
1414 #my $compress = 'flate'; # compressed streams
1515
16 my ($ant, $ant2, $ant3, $ant4, $ant5, $ant6);
1617 my $pdf = PDF::Builder->new(-compress => $compress);
1718
1819 #my $f1 = $pdf->corefont('Helvetica', -encode=>'latin1'); # unused
4849 # initially open note (annotation), can be replied to multiple times by users.
4950 # active area is supposed to be 100x100 at 50,150 (LL), but it seems to be a
5051 # little larger than the visible icon! BTW, the icon can be dragged and dropped.
51 my $ant = $page->annotation();
52 $ant = $page->annotation();
5253 $ant->text("This is an initially open note.\nnext line",
5354 -color=>[ 0.8 ], # light gray icon fill
5455 -icon=>'Key',
5859 # active area is supposed to be 100x100 at 200,300 (LL), but it seems to be
5960 # little larger than the visible icon! BTW, the icon can be dragged and dropped.
6061 # note that a new annotation object must be created.
61 $ant = $page->annotation();
62 $ant->text('This is an initially closed note',
62 $ant2 = $page->annotation();
63 $ant2->text('This is an initially closed note',
6364 -color=>[ 0.3 ], # dark gray icon fill
6465 -text=>'Closed for the day!', # extra note on rollover
6566 -opacity=> 0.75, # a little translucency
66 -border=>[10,10, 10], # prominent border
67 # -border=>[10,10, 10], # prominent border N/A
6768 # -icon use default (Note)
6869 -rect=>[210,110, 310,210]);
6970
9899 $text->paragraph($LoremIpsum, 250,640, 0, -spillover=>1);
99100
100101 # Now to do some annotations
101 $ant = $page->annotation(); # 1 line down from upper line
102 $ant3 = $page->annotation(); # 1 line down from upper line
102103 my $note = "This has a highlighter effect.";
103104 my @topbot = y_topbot(700, 1, $leading, $fontsize, $descender);
104105 my $corners = [115,$topbot[0], 221,$topbot[0], 115,$topbot[1], 221,$topbot[1]];
105 $ant->markup($note, $corners, "Highlight", -color=>[1, .82, 0]);
106 $ant3->markup($note, $corners, "Highlight", -color=>[1, .82, 0]);
106107
107 $ant = $page->annotation(); # 7 lines down from upper line
108 $ant4 = $page->annotation(); # 7 lines down from upper line
108109 $note = "This uses a squiggly line.";
109110 @topbot = y_topbot(700, 7, $leading, $fontsize, $descender);
110111 $corners = [75,$topbot[0], 298,$topbot[0], 75,$topbot[1], 298,$topbot[1]];
111 $ant->markup($note, $corners, "Squiggly", -color=>[0, 0, 1]);
112 $ant4->markup($note, $corners, "Squiggly", -color=>[0, 0, 1]);
112113
113 $ant = $page->annotation(); # 11 lines down from upper line
114 $ant5 = $page->annotation(); # 11 lines down from upper line
114115 $note = "This uses an underline spanning two lines.";
115116 @topbot = y_topbot(700, 11, $leading, $fontsize, $descender);
116117 $corners = [277,$topbot[0], 330,$topbot[0], 277,$topbot[1], 330,$topbot[1],
117118 75,$topbot[0]-$leading, 157,$topbot[0]-$leading,
118119 75,$topbot[1]-$leading, 157,$topbot[1]-$leading];
119 $ant->markup($note, $corners, "Underline", -color=>[0, 1, 0],
120 $ant5->markup($note, $corners, "Underline", -color=>[0, 1, 0],
120121 -text=>"Some title text");
121122
122 $ant = $page->annotation(); # 15 lines down from upper line
123 $ant6 = $page->annotation(); # 15 lines down from upper line
123124 $note = "This uses a strikeout spanning three lines.";
124125 @topbot = y_topbot(700, 15, $leading, $fontsize, $descender);
125126 $corners = [257,$topbot[0], 350,$topbot[0], 257,$topbot[1], 350,$topbot[1],
127128 75,$topbot[1]-$leading, 340,$topbot[1]-$leading,
128129 75,$topbot[0]-2*$leading, 338,$topbot[0]-2*$leading,
129130 75,$topbot[1]-2*$leading, 338,$topbot[1]-2*$leading];
130 $ant->markup($note, $corners, "StrikeOut", -opacity=>0.5);
131 $ant6->markup($note, $corners, "StrikeOut", -opacity=>0.5);
131132
132133 # ------------------
133134 $pdf->saveas("$0.pdf");
9797 );
9898
9999 # None icon, 100x100 size at LL= 50,400, border 10pt thick
100 # Notice that although the icon is "None", since an icon is "used", the
101 # border is suppressed
100102 my $ant5 = $page->annotation();
101103 $ant5->file_attachment($base."sample.txt",
102104 -rect=>[60,410, 160,510],
44
55 # program settings
66 my $border = 1; # line width of click rectangle, 0 for none
7
78 my $b_red = 0; # click rectangle border color (here medium green)
89 my $b_green = 0.5;
910 my $b_blue = 0;
11
12 my $normal_text_color = 'black';
13 my $link_text_color = 'blue';
14
1015 my $font_size = 20; # 20pt text
1116 my $local_movie = ""; # a local movie file such as .avi
1217
18 # ===========================================
1319 my $PDFname = $0;
1420 $PDFname =~ s/\..*$//; # remove any existing extension
1521 $PDFname .= '.pdf'; # add new extension
1925 my $text = $page->text();
2026 my $font = $pdf->corefont('Times-Roman');
2127 $text->font($font, $font_size);
28 $text->fillcolor($normal_text_color);
2229
2330 my $x = 100;
2431 my $y = 700;
3441 $x += $text->advancewidth("Click ");
3542
3643 # x,y should be at LL corner of "here" (on baseline)
37 $text->fillcolor('blue');
44 $text->fillcolor($link_text_color);
3845 $text->text("here");
3946 my $target_width = $text->advancewidth("here");
4047
4754 );
4855
4956 # restore color and do rest of line
50 $text->fillcolor('black');
57 $text->fillcolor($normal_text_color);
5158 $text->text(" to go to Google.");
5259
5360 # ---------- go to a specific location in a browser
5966 $x += $text->advancewidth("Go to ");
6067
6168 # x,y should be at LL corner of "here" (on baseline)
62 $text->fillcolor('blue');
69 $text->fillcolor($link_text_color);
6370 $text->text("a specific point");
6471 $target_width = $text->advancewidth("a specific point");
6572
7279 );
7380
7481 # restore color and do rest of line
75 $text->fillcolor('black');
82 $text->fillcolor($normal_text_color);
7683 $text->text(" on a website.");
84
85 # ---------- reminder to user
86 $x = 50;
87 $y = 300;
88 $text->translate($x, $y);
89 $text->text("In these examples the link text is explicitly colored blue and the");
90 $text->translate($x, $y-25);
91 $text->text("link box is outlined in green. These may be changed in the code.");
7792
7893 # ---------- go to a page within THIS document
7994 $page = $pdf->page(); # page 2
93108 $x += $text->advancewidth("Click ");
94109
95110 # x,y should be at LL corner of "here" (on baseline)
96 $text->fillcolor('blue');
111 $text->fillcolor($link_text_color);
97112 $text->text("here");
98113 $target_width = $text->advancewidth("here");
99114
107122 );
108123
109124 # restore color and do rest of line
110 $text->fillcolor('black');
125 $text->fillcolor($normal_text_color);
111126 $text->text(" to go to Page 1.");
112127
113128 # same, except position and zoom
119134 $x += $text->advancewidth("Click ");
120135
121136 # x,y should be at LL corner of "here" (on baseline)
122 $text->fillcolor('blue');
137 $text->fillcolor($link_text_color);
123138 $text->text("here");
124139 $target_width = $text->advancewidth("here");
125140
134149 );
135150
136151 # restore color and do rest of line
137 $text->fillcolor('black');
152 $text->fillcolor($normal_text_color);
138153 $text->text(" to go to Page 1 positioned/zoomed.");
139154
140155
156171 $x += $text->advancewidth("Click ");
157172
158173 # x,y should be at LL corner of "here" (on baseline)
159 $text->fillcolor('blue');
174 $text->fillcolor($link_text_color);
160175 $text->text("here");
161176 $target_width = $text->advancewidth("here");
162177
170185 );
171186
172187 # restore color and do rest of line
173 $text->fillcolor('black');
188 $text->fillcolor($normal_text_color);
174189 $text->text(" to go to Page 1 of another PDF document.");
175190
176191 # same, except position and zoom
182197 $x += $text->advancewidth("Click ");
183198
184199 # x,y should be at LL corner of "here" (on baseline)
185 $text->fillcolor('blue');
200 $text->fillcolor($link_text_color);
186201 $text->text("here");
187202 $target_width = $text->advancewidth("here");
188203
197212 );
198213
199214 # restore color and do rest of line
200 $text->fillcolor('black');
215 $text->fillcolor($normal_text_color);
201216 $text->text(" to go to Page 1 of another PDF document, windowed.");
202217
203218 # ---------- launch (default OS action) another file
220235 $x += $text->advancewidth("Click ");
221236
222237 # x,y should be at LL corner of "here" (on baseline)
223 $text->fillcolor('blue');
238 $text->fillcolor($link_text_color);
224239 $text->text("here");
225240 $target_width = $text->advancewidth("here");
226241
233248 );
234249
235250 # restore color and do rest of line
236 $text->fillcolor('black');
251 $text->fillcolor($normal_text_color);
237252 $text->text(" to \"launch\" a .txt file.");
238253
239254 # ----------------------
257272 );
258273
259274 # restore color
260 $text->fillcolor('black');
275 $text->fillcolor($normal_text_color);
261276
262277 # ----------------------
263278 if ($local_movie ne '' && -r $local_movie) {
88 use warnings;
99 use strict;
1010
11 our $VERSION = '3.023'; # VERSION
12 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
11 # VERSION
12 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
1313
1414 use Math::Trig;
1515 use List::Util qw(min max);
2020 my $bleedbox_adj = 36/pt; # in from crop box on top and right for printer inst.
2121 my $cropbox_adj = 0.25/in; # in from media edge
2222
23 our $VERSION = '3.023'; # VERSION
24 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
23 # VERSION
24 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
2525
2626 my $PDFname = $0;
2727 $PDFname =~ s/\..*$//; # remove extension such as .pl
3232 use warnings;
3333 use strict;
3434
35 our $VERSION = '3.023'; # VERSION
36 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
35 # VERSION
36 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
3737
3838 use Math::Trig;
3939 use List::Util qw(min max);
55 use warnings;
66 use strict;
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
1010
1111 use Math::Trig;
1212 use List::Util qw(min max);
55 use warnings;
66 use strict;
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
1010
1111 use Math::Trig;
1212 use List::Util qw(min max);
00 #!/usr/bin/perl
11 ##########################
2 # NOTE: appears to bring in the entire Ming font (Chinese), rather than a
3 # subset. sorry about that! ref RT 130041
42 # Note to maintainer: don't forget to refresh HarfBuzz_example.pdf
53 ##########################
64 # demonstrate some usage of HarfBuzz::Shaper and related text calls
108 use strict;
119 use warnings;
1210
13 our $VERSION = '3.023'; # VERSION
14 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
11 # VERSION
12 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1513
1614 my $PDFname = $0;
1715 $PDFname =~ s/\..*$//; # remove extension such as .pl
5149 # '/Users/Phil/AppData/Local/Microsoft/Windows/Fonts/NimbusRoman-Regular.otf';
5250 # '/WINDOWS/Fonts/verdana.ttf';
5351 # '/WINDOWS/Fonts/arial.ttf';
54 '/WINDOWS/Fonts/times.ttf';
55 my $arabicFont = '/Program Files (x86)/Adobe/Acrobat Reader DC/Resource/Font/AdobeArabic-Regular.otf';
52 '/WINDOWS/Fonts/times.ttf'; # missing fj, ij, and et
53 my $arabicFont = '/Program Files/Adobe/Acrobat DC/Resource/Font/AdobeArabic-Regular.otf';
5654 # You will certainly have to modify the font file locations and names
5755 # per your local installation and operating system, here and below in %samples.
5856 # Some .ttf fonts may be usable by HarfBuzz for shaping, but others don't seem
105103 'dir' => 'L',
106104 'script' => 'Latn',
107105 'specials' => 1, # -liga plus call Builder filter
108 # ss/eszett sz/eszett 'n/'n, ff fi fl ffi oo
109 'text' => ["strasse strasze R 'n R staff fish flow good"] },
106 # ss/eszett sz/eszett 'n/'n, ff fi fl fj oo
107 'text' => ["strasse strasze R 'n R staff fish flow fjord good"] },
110108 'LatinL3' => { 'title' => "LatinL3",
111109 'fontFile' => $ligFont,
112110 'dir' => 'L',
119117 'dir' => 'L',
120118 'script' => 'Latn',
121119 'specials' => 1, # -liga plus call Builder filter
122 # tz TZ ue vy ffi ffl
120 # tz TZ ue vy ffi ffl ij
123121 # TBD see if setting language to German will do ss, tz, TZ
124 'text' => ["Tirpitz TIRPITZ blue heavy suffice waffle"] },
122 'text' => ["Tirpitz TIRPITZ blue heavy suffice waffle pij"] },
125123
126124 # Demonstrate kerning (closing up overlapping characters) in a Latin script.
127125 # You should see AVA and AWAY are closed up, due to letter shapes. This can
153151 # and removal, all taken care of by HarfBuzz.
154152 'Devan' => { 'title' => "Devanagari", # see PP_Advanced pg 26 & 27
155153 # and PP_Avanced_typography_in_PDF.pdf
156 'fontFile' => '/Program Files (x86)/Adobe/Acrobat Reader DC/Resource/Font/AdobeDevanagari-Regular.otf',
154 'fontFile' => '/Program Files/Adobe/Acrobat DC/Resource/Font/AdobeDevanagari-Regular.otf',
157155 'dir' => 'L',
158156 'script' => 'Deva',
159157 'text' => ["\x{091A}\x{093F}\x{0928}\x{094D}\x{0939}\x{0947}", " PDF::Builder ", "\x{0905}\x{0932}\x{093f}\x{091c}\x{093f}\x{0939}\x{094d}\x{0935}\x{0940}\x{092f}"] },
387385 # some random Chinese characters. most interested in what direction is
388386 # the default, and what is settable
389387 'TTBChinese' => { 'title' => 'TTBChinese',
390 # 'fontFile' => '/Program Files (x86)/Adobe/Acrobat Reader DC/Resource/CIDFont/AdobeMingStd-Light.otf',
391 'fontFile' => '/Program Files (x86)/Adobe/Acrobat Reader DC/Resource/CIDFont/AdobeGothicStd-Light.otf',
388 # 'fontFile' => '/Program Files/Adobe/Acrobat DC/Resource/CIDFont/AdobeMingStd-Light.otf',
389 'fontFile' => '/Program Files/Adobe/Acrobat DC/Resource/CIDFont/AdobeGothicStd-Light.otf',
392390 'dir' => 'T',
393391 'script' => 'Chin',
394392 # 'text' => ["\x{5A40}\x{5A41}\x{5A42}\x{5A43}", " PDF::Builder ", "\x{5A44}\x{5A45}"] },
395 'text' => ["\x{58D8}\x{5A41}\x{5C62}\x{6A13}", " PDF::Builder ", "\x{6DDA}\x{6F0F}"] },
393 # 'text' => ["\x{58D8}\x{5A41}\x{5C62}\x{6A13}", " PDF::Builder ", "\x{6DDA}\x{6F0F}"] },
394 # want to show some punctuation that gets rotated around in TTB mode. text is Google Translate-produced "use this (whiter teeth)"
395 ## 'text' => ["使用這個(更白的牙齒)。"] },
396 'text' => ["\x{4F7F}\x{7528}\x{9019}\x{500B}\x{FF08}\x{66F4}\x{767D}\x{7684}\x{7259}\x{9F52}\x{FF09}\x{3002}"] },
396397
397398 # Languages which are normally RTL don't seem to behave with TTB.
398399 # I would expect them to be reversed, but they aren't. Maybe the direction
66 use warnings;
77 use strict;
88
9 our $VERSION = '3.023'; # VERSION
10 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
9 # VERSION
10 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
1111
1212 use PDF::Builder;
1313
66 use strict;
77 use warnings;
88
9 our $VERSION = '3.023'; # VERSION
10 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
9 # VERSION
10 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1111
1212 use PDF::Builder;
1313 use Encode;
33 use warnings;
44 #no warnings qw[ deprecated recursion uninitialized ];
55
6 our $VERSION = '3.023'; # VERSION
7 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
6 # VERSION
7 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
88
99 use Win32::TieRegistry qw( :KEY_ ); # creates $Registry, et al.
1010
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.024'; # manually update whenever code is changed
99
1010 use PDF::Builder::Basic::PDF::Utils;
1111 use List::Util qw(min max);
3737
3838 my $self = $class->SUPER::new();
3939 $self->{'Type'} = PDFName('Annot');
40 $self->{'Border'} = PDFArray(PDFNum(0), PDFNum(0), PDFNum(1));
40 $self->{'Border'} = PDFArray(PDFNum(0), PDFNum(0), PDFNum(0)); # no border
4141
4242 return $self;
4343 }
172172
173173 Defines the annotation as a text note with content string C<$text> and
174174 options %options (-rect, -color, -text, -open: see descriptions below).
175 The C<$text> may include newlines \n for multiple lines.
175 The C<$text> may include newlines \n for multiple lines. The option -border is
176 ignored, since an I<icon> is used.
176177
177178 C<-text> is the popup's label string, not to be confused with the main C<$text>.
178179
219220
220221 $self->rect(@{$options{'-rect'}}) if defined $options{'-rect'};
221222 $self->open($options{'-open'}) if defined $options{'-open'};
223 #$self->border($options{'-border'}) if defined $options{'-border'}; # ignored
222224 $self->Color(@{$options{'-color'}}) if defined $options{'-color'};
223225 # popup label (title)
224226 # have seen /T as (xFEFF UTF-16 chars)
581583 Sets the border-style of the annotation, if applicable, as given by the
582584 -border option. There are three entries in the array:
583585 horizontal and vertical corner radii, and border width.
586 An optional fourth entry (described below) may be used for a dashed or dotted
587 line.
584588
585589 A border is used in annotations where text or some other material is put down,
586 and a clickable rectangle is defined over it (-rect). A border is not used
587 when an icon is being used to mark the clickable area.
588
589 The default is [0 0 1] (solid line of width 1, with sharp corners).
590 and a clickable rectangle is defined over it (-rect). A border is not shown
591 when an B<icon> is being used to mark the clickable area.
592
593 A I<PDF Reader> normally defaults to [0 0 1] (solid line of width 1, with
594 sharp corners) if no border (C</Border>) is specified. Keeping compatibility
595 with PDF::API2's longstanding practice, PDF::Builder defaults to no visible
596 border C<[0 0 0]> (solid line of width 0, and thus invisible).
590597
591598 Defining option:
592599
594601
595602 =item -border => [CRh, CRv, W]
596603
597 =item -border => [CRh, CRv, W [, on, off...]]
604 =item -border => [CRh, CRv, W, [on, off...]]
605
606 Note that the square brackets [ and ] are literally I<there>, indicating a
607 vector or array of values. They do B<not> indicate optional values!
598608
599609 Set annotation B<border style> of horizontal and vertical corner radii C<CRh>
600610 and C<CRv> (value 0 for squared corners) and width C<W> (value 0 for no border).
601 The default is squared corners and a solid line of width 1 ([0 0 1]).
611 The PDF::Builder default is no border (while a I<PDF Reader> typically defaults
612 to squared corners and a solid line of width 1 ([0 0 1]), if no /Border entry
613 is given).
602614 Optionally, a dash pattern array may be given (C<on> length, C<off> length,
603615 as one or more I<pairs>). The default is a solid line.
604616
605617 The border vector seems to ignore the first two settings (corner radii), but
606618 the line thickness works, on basic Readers.
607 The radii I<may> work on some other Readers.
619 The corner radii I<may> work on some other Readers.
608620
609621 =back
610622
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
2020 use warnings;
2121 #no warnings qw[ deprecated recursion uninitialized ];
2222
23 our $VERSION = '3.023'; # VERSION
24 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
23 # VERSION
24 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2525
2626 our $mincache = 16 * 1024 * 1024;
2727
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.010'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.010'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.016'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.016'; # manually update whenever code is changed
99
1010 use POSIX qw(ceil floor);
1111
55 use POSIX;
66 use base 'PDF::Builder::Basic::PDF::Filter::FlateDecode';
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
1010
1111 =head1 NAME
1212
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
1717 use strict;
1818 use warnings;
1919
20 our $VERSION = '3.023'; # VERSION
21 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
20 # VERSION
21 my $LAST_UPDATE = '3.024'; # manually update whenever code is changed
2222
2323 use PDF::Builder::Basic::PDF::Filter::ASCII85Decode;
2424 use PDF::Builder::Basic::PDF::Filter::ASCIIHexDecode;
2525 use PDF::Builder::Basic::PDF::Filter::FlateDecode;
2626 use PDF::Builder::Basic::PDF::Filter::LZWDecode;
2727 use PDF::Builder::Basic::PDF::Filter::RunLengthDecode;
28 # use PDF::Builder::Basic::PDF::Filter::CCITTFaxDecode; when TIFF changes in
2829 use Scalar::Util qw(blessed reftype);
2930
3031 =head1 NAME
55 use strict;
66 use warnings;
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Filter;
1212 use PDF::Builder::Basic::PDF::Name;
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
1818 use warnings;
1919 use Scalar::Util 'isweak';
2020
21 our $VERSION = '3.023'; # VERSION
22 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
21 # VERSION
22 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2323
2424 =head1 NAME
2525
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 use PDF::Builder::Basic::PDF::Dict;
2626 use PDF::Builder::Basic::PDF::Utils;
1919
2020 use base 'PDF::Builder::Basic::PDF::Dict';
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2424
2525 use PDF::Builder::Basic::PDF::Array;
2626 use PDF::Builder::Basic::PDF::Dict;
1919 use strict;
2020 use warnings;
2121
22 our $VERSION = '3.023'; # VERSION
23 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
22 # VERSION
23 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
2424
2525 =head1 NAME
2626
1717 use strict;
1818 use warnings;
1919
20 our $VERSION = '3.023'; # VERSION
21 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
20 # VERSION
21 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
2222
2323 =head1 NAME
2424
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.020'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.020'; # manually update whenever code is changed
77
88 =head1 NAME
99
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
55 use warnings;
66 #no warnings qw( deprecated recursion uninitialized );
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
1010
1111 use Carp;
1212 use Compress::Zlib qw();
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.024'; # manually update whenever code is changed
77
88 # originally part of Builder.pm, it was split out due to its length
99
509509 In 2011, PDF::API2 maintenance was taken over by Steve Simms.
510510 In 2017, PDF::Builder was forked by Phil M. Perry, who desired a more aggressive
511511 schedule of new features and bug fixes than Simms was providing.
512
513 According to "pdfapi2_for_fun_and_profit_APW2005.pdf" (on
514 http://pdfapi2.sourceforge.net, an unmaintained site), the history of PDF::API2
515 (the predecessor to PDF::Builder) goes as such:
516
517 =over
518
519 =item E<nbsp> E<nbsp> E<bull>E<nbsp> First Code implemented based on PDFlib-0.6 (AFPL)
520
521 =item E<nbsp> E<nbsp> E<bull>E<nbsp> Changed to Text::PDF with a total rewrite as Text::PDF::API (procedural)
522
523 =item E<nbsp> E<nbsp> E<bull>E<nbsp> Unmaintainable Code triggered rewrite into new Namespace PDF::API2 (object-oriented, LGPL)
524
525 =item E<nbsp> E<nbsp> E<bull>E<nbsp> Object-Structure streamlined in 0.4x
526
527 =back
512528
513529 At Simms's request, the name of the new offering was changed from PDF::API4
514530 to PDF::Builder, to reduce the chance of confusion due to parallel development.
33 use warnings;
44 #no warnings qw[ deprecated recursion uninitialized ];
55
6 our $VERSION = '3.023'; # VERSION
7 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
6 # VERSION
7 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
88 # NOTE that this sub-package has not been tested and is not well documented!
99 # It is possible that it will be deprecated and removed.
1010
1212 use warnings;
1313 use Carp;
1414
15 our $VERSION = '3.023'; # VERSION
16 our $LAST_UPDATE = '3.020'; # manually update whenever code is changed
15 # VERSION
16 my $LAST_UPDATE = '3.020'; # manually update whenever code is changed
1717
1818 =head1 NAME
1919
55 use warnings;
66 #no warnings qw[ recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 # TBD: do -rect and -border apply to Named Destinations (link, url, file)?
1212 # There is nothing to implement these options. Perhaps the code was copied
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.020'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.020'; # manually update whenever code is changed
99
1010 use Carp qw(croak);
1111 use PDF::Builder::Basic::PDF::Utils;
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
99
1010 use PDF::Builder::Basic::PDF::Utils;
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
99
1010 use POSIX qw(floor);
1111 use Scalar::Util qw(weaken);
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
99
1010 use Compress::Zlib;
1111 use Encode qw(:all);
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Util;
1212 use PDF::Builder::Basic::PDF::Utils;
55 use warnings;
66 #no warnings qw[ recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use Carp;
1212 use Encode qw(:all);
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Resource::CIDFont::TrueType::FontFile;
33
44 use strict;
55 use warnings;
6 #no warnings qw[ deprecated recursion uninitialized ];
7
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
6
7 # VERSION
8 my $LAST_UPDATE = '3.024'; # manually update whenever code is changed
109
1110 use Encode qw(:all);
1211
3029 sub new {
3130 my ($class, $pdf, $name, @opts) = @_;
3231
33 my %opts = ();
34 %opts = @opts if (scalar @opts)%2 == 0;
35
36 $class = ref $class if ref $class;
32 $class = ref($class) if ref($class);
3733 my $self = $class->SUPER::new($pdf, $name);
3834 $pdf->new_obj($self) if defined($pdf) && !$self->is_obj($pdf);
3935
40 $self->{'Type'} = PDFName('Font');
41 $self->{'Subtype'} = PDFName('Type0');
36 $self->{'Type'} = PDFName('Font');
37 $self->{'Subtype'} = PDFName('Type0');
4238 $self->{'Encoding'} = PDFName('Identity-H');
4339
4440 my $de = PDFDict();
8076 }
8177
8278 sub wxByCId {
83 my $self = shift;
84 my $g = shift;
79 my ($self, $g) = @_;
8580
8681 my $w;
8782
88 if (ref($self->data()->{'wx'}) eq 'ARRAY' &&
89 defined $self->data()->{'wx'}->[$g]) {
90 $w = int($self->data()->{'wx'}->[$g]);
91 } elsif (ref($self->data()->{'wx'}) eq 'HASH' &&
92 defined $self->data()->{'wx'}->{$g}) {
93 $w = int($self->data()->{'wx'}->{$g});
83 my $widths = $self->data()->{'wx'};
84
85 if (ref($widths) eq 'ARRAY' && defined $widths->[$g]) {
86 $w = int($widths->[$g]);
87 } elsif (ref($widths) eq 'HASH' && defined $widths->{$g}) {
88 $w = int($widths->{$g});
9489 } else {
9590 $w = $self->missingwidth();
9691 }
150145 defined $self->data()->{'decode'} &&
151146 $self->data()->{'decode'} ne 'ident') {
152147 $text = encode($self->data()->{'decode'}, $text);
153 } elsif (utf8::is_utf8($text) && $self->data()->{'decode'} eq 'ident') {
148 } elsif (utf8::is_utf8($text) &&
149 defined $self->data()->{'decode'} &&
150 $self->data()->{'decode'} eq 'ident') {
154151 $text = $self->cidsByUtf($text);
155152 } elsif (!utf8::is_utf8($text) &&
156153 defined $self->data()->{'encode'} &&
154 defined $self->data()->{'decode'} &&
157155 $self->data()->{'decode'} eq 'ident') {
158156 $text = $self->cidsByUtf(decode($self->data()->{'encode'}, $text));
159157 } elsif (!utf8::is_utf8($text) &&
160158 $self->can('issymbol') &&
161159 $self->issymbol() &&
160 defined $self->data()->{'decode'} &&
162161 $self->data()->{'decode'} eq 'ident') {
163162 $text = pack('U*', (map { $_+0xf000 } unpack('C*', $text)));
164163 $text = $self->cidsByUtf($text);
177176 sub cidsByUtf {
178177 my ($self, $s) = @_;
179178
180 $s = pack('n*', map { $self->cidByUni($_)||0 } (map { $_>0x7f && $_<0xA0? uniByName(nameByUni($_)): $_ } unpack('U*', $s)));
179 $s = pack('n*',
180 map { $self->cidByUni($_)||0 }
181 (map {
182 ($_ and $_>0x7f and $_<0xA0)? uniByName(nameByUni($_)): $_
183 }
184 unpack('U*', $s)));
185
181186 utf8::downgrade($s);
182187 return $s;
183188 }
236241 $self->fontfile()->subsetByCId($g);
237242 }
238243 }
239 if (defined $size && $self->{'-dokern'} && $self->haveKernPairs()) {
244 if (defined $size && $self->{'-dokern'} && $self->haveKernPairs()) {
240245 my $newtext = ' ';
241246 my $lastglyph = 0;
242247 my $tBefore = 0;
248253 }
249254 $lastglyph = $n;
250255 my $t = sprintf('%04X', $n);
251 $newtext .= '<' if !$tBefore;
256 $newtext .= '<' unless $tBefore;
252257 $newtext .= $t;
253258 $tBefore = 1;
254259 }
276281 }
277282
278283 sub haveKernPairs {
279 return 0;
284 return 0; # PDF::API2 changed to just 'return;'
280285 }
281286
282287 sub encodeByName {
284289
285290 return if $self->issymbol();
286291
287 $self->data()->{'e2u'} = [ map { $_>0x7f && $_<0xA0? uniByName(nameByUni($_)): $_ } unpack('U*', decode($enc, pack('C*', 0..255))) ] if defined $enc;
288 $self->data()->{'e2n'} = [ map { $self->data()->{'g2n'}->[$self->data()->{'u2g'}->{$_} || 0] || '.notdef' } @{$self->data()->{'e2u'}} ];
289 $self->data()->{'e2g'} = [ map { $self->data()->{'u2g'}->{$_} || 0 } @{$self->data()->{'e2u'}} ];
292 if (defined $enc) {
293 $self->data()->{'e2u'} = [
294 map { ($_ and $_>0x7f and $_<0xA0)? uniByName(nameByUni($_)): $_ }
295 unpack('U*', decode($enc, pack('C*', 0..255)))
296 ];
297 }
298 $self->data()->{'e2n'} = [
299 map { $self->data()->{'g2n'}->[$self->data()->{'u2g'}->{$_} || 0] || '.notdef' }
300 @{$self->data()->{'e2u'}}
301 ];
302 $self->data()->{'e2g'} = [
303 map { $self->data()->{'u2g'}->{$_} || 0 }
304 @{$self->data()->{'e2u'}}
305 ];
290306
291307 $self->data()->{'u2e'} = {};
292308 foreach my $n (reverse 0..255) {
293 $self->data()->{'u2e'}->{$self->data()->{'e2u'}->[$n]} = $n
294 unless defined $self->data()->{'u2e'}->{$self->data()->{'e2u'}->[$n]};
309 $self->data()->{'u2e'}->{$self->data()->{'e2u'}->[$n]} //= $n;
295310 }
296311
297312 return $self;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 =head1 NAME
1212
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
77
88 =head1 NAME
99
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Basic::PDF::Utils;
1212 use PDF::Builder::Util;
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use PDF::Builder::Util;
1212 use PDF::Builder::Basic::PDF::Utils;
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.013'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.013'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.019'; # manually update whenever code is changed
77
88 =head1 NAME
99
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use File::Basename;
1212
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use Encode qw(:all);
1212 use IO::File qw();
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.022'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.022'; # manually update whenever code is changed
1010
1111 use Math::Trig; # CAUTION: deg2rad(0) = deg2rad(360) = 0!
1212 use Unicode::UCD 'charinfo';
55 use warnings;
66 #no warnings qw[ deprecated recursion uninitialized ];
77
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8 # VERSION
9 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1010
1111 use Encode qw(:all);
1212
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
77
88 =head1 NAME
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.020'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.020'; # manually update whenever code is changed
77
88 =head1 NAME
99
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.031'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.031'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.016'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.016'; # manually update whenever code is changed
77
88 use Carp;
99 use Encode qw(:all);
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.029'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.029'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.004'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.004'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.017'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.017'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.004'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.004'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.004'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.004'; # manually update whenever code is changed
99
1010 =head1 NAME
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.010'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.010'; # manually update whenever code is changed
99
1010 use PDF::Builder::Util;
1111 use PDF::Builder::Basic::PDF::Utils;
0 This is a placeholder until 2D bar codes get added
0 This is a placeholder until 2D bar codes get added
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.016'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.016'; # manually update whenever code is changed
99
1010 use PDF::Builder::Basic::PDF::Dict;
1111 use PDF::Builder::Basic::PDF::Utils;
0 This is a placeholder until QR codes get added
0 This is a placeholder until QR codes get added
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.031'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.031'; # manually update whenever code is changed
99
1010 use PDF::Builder::Basic::PDF::Utils;
1111
33
44 use strict;
55 use warnings;
6 #no warnings qw[ deprecated recursion uninitialized ];
76
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
109
1110 use PDF::Builder::Util;
1211 use PDF::Builder::Basic::PDF::Utils;
1615
1716 PDF::Builder::Resource::XObject::Image::GD - support routines for Graphics Development image library. Inherits from L<PDF::Builder::Resource::XObject::Image>
1817
18 =head1 METHODS
19
20 =over
21
22 =item $res = PDF::Builder::Resource::XObject::Image::GD->new($pdf, $file, %opts)
23
24 =item $res = PDF::Builder::Resource::XObject::Image::GD->new($pdf, $file)
25
26 =back
27
28 Options:
29
30 =over
31
32 =item -name => 'string'
33
34 This is the name you can give for the GD image object. The default is Dxnnnn.
35
36 =item -lossless => 1
37
38 Use lossless compression.
39
40 =back
41
1942 =cut
2043
2144 sub new {
22 my ($class, $pdf, $obj, $name, @opts) = @_;
45 my ($class, $pdf, $obj, %opts) = @_;
46
47 my ($name, $compress);
48 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
49 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
2350
2451 my $self;
2552
26 $class = ref $class if ref $class;
53 $class = ref($class) if ref($class);
2754
28 $self = $class->SUPER::new($pdf, $name || 'Jx'.pdfkey());
55 $self = $class->SUPER::new($pdf, $name || 'Dx'.pdfkey());
2956 $pdf->new_obj($self) unless $self->is_obj($pdf);
3057
3158 $self->{' apipdf'} = $pdf;
3259 weaken $self->{' apipdf'};
3360
34 $self->read_gd($obj, @opts);
61 $self->read_gd($obj, %opts);
3562
3663 return $self;
3764 }
33
44 use strict;
55 use warnings;
6 #no warnings qw[ deprecated recursion uninitialized ];
7
8 our $VERSION = '3.023'; # VERSION
9 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
6
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
109
1110 use IO::File;
1211 use PDF::Builder::Util;
1716
1817 PDF::Builder::Resource::XObject::Image::GIF - support routines for GIF image library. Inherits from L<PDF::Builder::Resource::XObject::Image>
1918
19 =head2 History
20
21 GIF89a Specification: https://www.w3.org/Graphics/GIF/spec-gif89a.txt
22
23 A fairly thorough description of the GIF format may be found in
24 L<http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html>.
25
26 Code originally from PDF::Create, PDF::Image::GIFImage - GIF image support
27 Author: Michael Gross <mdgrosse@sboxtugraz.at>
28
2029 =head1 Supported Formats
2130
2231 GIF87a and GIF89a headers are supported. The Image block (x2C) is supported.
3241 than 256 colors to be used overall in the image (despite the 8 bit color table
3342 depth).
3443
35 A fairly thorough description of the GIF format may be found in
36 L<http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html>.
37
3844 =head2 Options
3945
4046 =over
4349
4450 When defined and not 0, C<-notrans> suppresses the use of transparency if such
4551 is defined in the GIF file.
52
53 =item -name => 'string'
54
55 This is the name you can give for the GIF image object. The default is Gxnnnn.
4656
4757 =item -multi
4858
5464
5565 =cut
5666
57 # added from PDF::Create:
58 # PDF::Image::GIFImage - GIF image support
59 # Author: Michael Gross <mdgrosse@sbox.tugraz.at>
6067 # modified for internal use. (c) 2004 fredo.
6168 sub unInterlace {
6269 my $self = shift;
6875 my $height = $self->height();
6976 my $idx = 0;
7077
71 #Pass 1 - every 8th row, starting with row 0
78 # Pass 1 - every 8th row, starting with row 0
7279 $row = 0;
7380 while ($row < $height) {
7481 $result[$row] = substr($data, $idx*$width, $width);
7683 $idx++;
7784 }
7885
79 #Pass 2 - every 8th row, starting with row 4
86 # Pass 2 - every 8th row, starting with row 4
8087 $row = 4;
8188 while ($row < $height) {
8289 $result[$row] = substr($data, $idx*$width, $width);
8491 $idx++;
8592 }
8693
87 #Pass 3 - every 4th row, starting with row 2
94 # Pass 3 - every 4th row, starting with row 2
8895 $row = 2;
8996 while ($row < $height) {
9097 $result[$row] = substr($data, $idx*$width, $width);
9299 $idx++;
93100 }
94101
95 #Pass 4 - every 2nd row, starting with row 1
102 # Pass 4 - every 2nd row, starting with row 1
96103 $row = 1;
97104 while ($row < $height) {
98105 $result[$row] = substr($data, $idx*$width, $width);
131138 # $tag |= vec($stream, $ptr+$off, 1);
132139 # }
133140 # print STDERR "ptr=$ptr,tag=$tag,bits=$bits,next=$nextcode\n";
134 # print STDERR "tag to large\n" if($tag>$nextcode);
141 # print STDERR "tag too large\n" if($tag>$nextcode);
135142 $ptr += $bits;
136143 $bits++ if $nextcode == 1 << $bits and $bits < 12;
137144 if ($tag == $resetcode) {
155162 }
156163
157164 sub new {
158 my ($class, $pdf, $file, $name, %opts) = @_;
165 my ($class, $pdf, $file, %opts) = @_;
166
167 my ($name, $compress);
168 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
169 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
159170
160171 my $self;
161172
162 my $inter = 0;
163
164 $class = ref $class if ref $class;
173 my $interlaced = 0;
174
175 $class = ref($class) if ref($class);
165176
166177 $self = $class->SUPER::new($pdf, $name || 'Gx'.pdfkey());
167178 $pdf->new_obj($self) unless $self->is_obj($pdf);
183194 # GIF Header
184195 # 6 bytes "GIF87a" or "GIF89a"
185196 $fh->read($buf, 6); # signature
186 die "unknown image signature '$buf' -- not a GIF." unless $buf =~ /^GIF[0-9][0-9][a-b]/; # TBD b? is anything other than 87a and 89a valid?
197 unless ($buf =~ /^GIF[0-9][0-9][a-b]/) {
198 # TBD b? is anything other than 87a and 89a valid?
199 # PDF::API2 allows a-z, not just a-b
200 die "unknown image signature '$buf' -- not a GIF."
201 }
187202
188203 # 4 bytes logical screen width and height (2 x 16 bit LSB first)
189204 # 1 byte flags, 1 byte background color index, 1 byte pixel aspect ratio
190 $fh->read($buf, 7); # logical descr.
205 $fh->read($buf, 7); # logical screen descriptor
191206 my($wg, $hg, $flags, $bgColorIndex, $aspect) = unpack('vvCCC', $buf);
192207
193208 # flags numbered left to right 0-7:
199214 my $colSize = 2**(($flags & 0x7)+1); # 2 - 256 entries
200215 my $dict = PDFDict();
201216 $pdf->new_obj($dict);
202 $self->colorspace(PDFArray(PDFName('Indexed'), PDFName('DeviceRGB'), PDFNum($colSize-1), $dict));
217 $self->colorspace(PDFArray(PDFName('Indexed'),
218 PDFName('DeviceRGB'),
219 PDFNum($colSize-1),
220 $dict));
203221 $fh->read($dict->{' stream'}, 3*$colSize); # Global Color Table
204222 }
205223
210228
211229 if ($sep == 0x2C) {
212230 # x2C = image block (separator, equals ASCII comma ',')
213 $fh->read($buf, 9); # image-descr.
231 $fh->read($buf, 9); # image descriptor
214232 # image left (16 bits), image top (16 bits LSB first)
215233 # image width (16 bits), image height (16 bits LSB first)
216234 # flags (1 byte):
229247 my $colSize = 2**(($flags & 0x7)+1);
230248 my $dict = PDFDict();
231249 $pdf->new_obj($dict);
232 $self->colorspace(PDFArray(PDFName('Indexed'), PDFName('DeviceRGB'), PDFNum($colSize-1), $dict));
250 $self->colorspace(PDFArray(PDFName('Indexed'),
251 PDFName('DeviceRGB'),
252 PDFNum($colSize-1),
253 $dict));
233254 $fh->read($dict->{' stream'}, 3*$colSize); # Local Color Table
234255 }
235256 if ($flags & 0x40) { # need de-interlace
236 $inter = 1; # default to 0 earlier
257 $interlaced = 1; # default to 0 earlier
237258 }
238259
239260 # LZW Minimum Code Size
252273 $len = unpack('C', $buf);
253274 }
254275 $self->{' stream'} = deGIF($sep+1, $stream);
255 $self->unInterlace() if $inter;
276 $self->unInterlace() if $interlaced;
256277 # old (and current default) behavior is to quit processing at the
257278 # end of the first Image Block. This means that any other blocks,
258279 # including the Trailer, will not be processed.
280301 }
281302 my ($cFlags, $delay, $transIndex) = unpack('CvC', $stream);
282303 if (($cFlags & 0x01) && !$opts{'-notrans'}) {
283 $self->{'Mask'} = PDFArray(PDFNum($transIndex), PDFNum($transIndex));
304 $self->{'Mask'} = PDFArray(PDFNum($transIndex),
305 PDFNum($transIndex));
284306 }
285307
286308 } elsif ($tag == 0xFE) {
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.017'; # manually update whenever code is changed
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
99
1010 use IO::File;
1111 use PDF::Builder::Util;
1616
1717 PDF::Builder::Resource::XObject::Image::JPEG - support routines for JPEG image library. Inherits from L<PDF::Builder::Resource::XObject::Image>
1818
19 =head1 METHODS
20
21 =over
22
23 =item $res = PDF::Builder::Resource::XObject::Image::JPEG->new($pdf, $file, %opts)
24
25 =item $res = PDF::Builder::Resource::XObject::Image::JPEG->new($pdf, $file)
26
27 =back
28
29 Options:
30
31 =over
32
33 =item -name => 'string'
34
35 This is the name you can give for the JPEG image object. The default is Jxnnnn.
36
37 =back
38
1939 =cut
2040
2141 sub new {
22 my ($class, $pdf, $file, $name) = @_;
42 my ($class, $pdf, $file, %opts) = @_;
43
44 my ($name, $compress);
45 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
46 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
2347
2448 my $fh = IO::File->new();
2549
26 $class = ref($class) if ref $class;
50 $class = ref($class) if ref($class);
2751
2852 my $self = $class->SUPER::new($pdf, $name || 'Jx' . pdfkey());
2953 $pdf->new_obj($self) unless $self->is_obj($pdf);
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.019'; # manually update whenever code is changed
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
99
1010 use Compress::Zlib;
1111 use POSIX qw(ceil floor);
2525
2626 =over
2727
28 =item $res = PDF::Builder::Resource::XObject::Image::PNG->new($pdf, $file, $name, %opts)
29
30 =item $res = PDF::Builder::Resource::XObject::Image::PNG->new($pdf, $file, $name)
28 =item $res = PDF::Builder::Resource::XObject::Image::PNG->new($pdf, $file, %opts)
3129
3230 =item $res = PDF::Builder::Resource::XObject::Image::PNG->new($pdf, $file)
3331
4139 used instead of the PNG library. In such a case, use of the PNG library may be
4240 forced via the C<-nouseIPL> flag (see Builder documentation for C<image_png()>).
4341
44 opts: -notrans
45
46 No transparency -- ignore tRNS chunk if provided, ignore Alpha channel
47 if provided.
42 B<opts:>
43
44 =over
45
46 =item -notrans => 1
47
48 No transparency -- ignore tRNS chunk if provided, ignore Alpha channel
49 if provided.
50
51 =item -name => 'string'
52
53 This is the name you can give for the PNG image object. The default is Pxnnnn.
54
55 =back
4856
4957 =head2 Supported PNG types
5058
99107 # TBD: gAMA (gamma) chunk, perhaps some others?
100108
101109 sub new {
102 my ($class, $pdf, $file, $name, %opts) = @_;
110 my ($class, $pdf, $file, %opts) = @_;
111
112 my ($name, $compress);
113 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
114 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
103115
104116 my $self;
105117
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
99
1010 use Compress::Zlib;
1111 use POSIX qw(ceil floor);
2727
2828 =over
2929
30 =item $res = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($pdf, $file, $name, %opts)
31
32 =item $res = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($pdf, $file, $name)
30 =item $res = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($pdf, $file, %opts)
3331
3432 =item $res = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($pdf, $file)
3533
5654
5755 If the PNG source is 16bps, tell the libpng library to strip down all
5856 channels to 8bps, permitting use on PDF 1.4 output.
57
58 =item -name => 'string'
59
60 This is the name you can give for the PNG image object. The default is Pxnnnn.
5961
6062 =back
6163
112114 # TBD: gAMA (gamma) chunk, perhaps some others?
113115
114116 sub new {
115 my ($class, $pdf, $file, $name, %opts) = @_;
117 my ($class, $pdf, $file, %opts) = @_;
118
119 my ($name, $compress);
120 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
121 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
116122
117123 my $self;
118124
55
66 use strict;
77 use warnings;
8 #no warnings qw[ deprecated recursion uninitialized ];
9
10 our $VERSION = '3.023'; # VERSION
11 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
8
9 # VERSION
10 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
1211
1312 use IO::File;
1413 use PDF::Builder::Util;
1514 use PDF::Builder::Basic::PDF::Utils;
1615 use Scalar::Util qw(weaken);
1716
17 # massively rewritten recently, so assuming nothing in PDF::API2 rewrite (2021)
18 # should make any functional difference
19
1820 =head1 NAME
1921
2022 PDF::Builder::Resource::XObject::Image::PNM - support routines for PNM (Portable aNy Map) image library. Inherits from L<PDF::Builder::Resource::XObject::Image>
2325
2426 =over
2527
26 =new($pdf, $file, $name)
28 =item $res = PDF::Builder::Resource::XObject::Image::PNM->new($pdf, $file, %opts)
29
30 =item $res = PDF::Builder::Resource::XObject::Image::PNM->new($pdf, $file)
31
32 =back
33
34 Options:
35
36 =over
37
38 =item -name => 'string'
39
40 This is the name you can give for the PNM image object. The default is Nxnnnn.
41
42 =item -compress => 1
43
44 This is the compression you can give for the PNM image object. Any value will
45 cause the use of I<Flate> compression, otherwise I<ASCIIHexDecode>.
46 If not explicitly given, use whatever the global C<forcecompress> setting is.
47
48 =back
2749
2850 Returns an image in the PDF. PNM types 1 (ASCII/plain bi-level/PBM),
2951 2 (ASCII/plain grayscale/PGM), 3 (ASCII/plain RGB/PPM),
3860 with 0 being full black. If the maximum sample value is 255 or smaller, three
3961 bytes of raw binary data per pixel, otherwise six bytes.
4062
41 =back
42
4363 =cut
4464
4565 # -------------------------------------------------------------------
4666 sub new {
47 my ($class, $pdf, $file, $name) = @_;
67 my ($class, $pdf, $file, %opts) = @_;
68
69 my ($name, $compress);
70 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
71 if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
4872
4973 my $self;
5074
51 $class = ref $class if ref $class;
75 $class = ref($class) if ref($class);
5276
5377 $self = $class->SUPER::new($pdf, $name || 'Nx'.pdfkey());
5478 $pdf->new_obj($self) unless $self->is_obj($pdf);
5781 weaken $self->{' apipdf'};
5882
5983 $self->read_pnm($pdf, $file);
84
85 if (defined $compress) {
86 $self->filters('FlateDecode');
87 } else {
88 $self->filters('ASCIIHexDecode');
89 }
6090
6191 return $self;
6292 }
6898 # extensively modified by Phil M Perry, copyright 2020
6999 #
70100 sub readppmheader {
101 # renamed to _read_header() in PDF::API2
71102 my ($gr, $buffer) = @_; # already-opened input file's filehandle
72103 my %info;
73104 $info{'error'} = undef;
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
77
88 use IO::File;
99
22 use strict;
33 use warnings;
44
5 our $VERSION = '3.023'; # VERSION
6 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
5 # VERSION
6 my $LAST_UPDATE = '3.023'; # manually update whenever code is changed
77
88 use IO::File;
99 use Graphics::TIFF ':all'; # already confirmed to be installed
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
99
1010 use Compress::Zlib;
1111
2222
2323 =over
2424
25 =item $res = PDF::Builder::Resource::XObject::Image::TIFF->new($pdf, $file, $name)
25 =item $res = PDF::Builder::Resource::XObject::Image::TIFF->new($pdf, $file, %opts)
2626
2727 =item $res = PDF::Builder::Resource::XObject::Image::TIFF->new($pdf, $file)
2828
3232 instead of the TIFF library. In such a case, use of the TIFF library may be
3333 forced via the C<-nouseGT> flag (see Builder documentation for C<image_tiff()>).
3434
35 Options:
36
37 =over
38
39 =item -name => 'string'
40
41 This is the name you can give for the TIFF image object. The default is Ixnnnn.
42
43 =back
44
3545 =cut
3646
3747 sub new {
38 my ($class, $pdf, $file, $name) = @_;
48 my ($class, $pdf, $file, %opts) = @_;
49
50 my ($name, $compress);
51 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
52 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
3953
4054 my $self;
4155
42 my $tif = PDF::Builder::Resource::XObject::Image::TIFF::File->new($file);
56 my $tif = PDF::Builder::Resource::XObject::Image::TIFF::File->new($file, %opts);
4357
4458 # dump everything in tif except huge data streams
4559 # foreach (sort keys %{ $tif }) {
5771 # in case of problematic things
5872 # proxy to other modules
5973
60 $class = ref($class) if ref $class;
74 $class = ref($class) if ref($class);
6175
6276 $self = $class->SUPER::new($pdf, $name || 'Ix'.pdfkey());
6377 $pdf->new_obj($self) unless $self->is_obj($pdf);
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
7 # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
99
1010 use Compress::Zlib;
1111
2424
2525 =over
2626
27 =item $res = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($pdf, $file, $name, %opts)
28
29 =item $res = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($pdf, $file, $name)
27 =item $res = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($pdf, $file, %opts)
3028
3129 =item $res = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($pdf, $file)
3230
4543 =item -notrans => 1
4644
4745 Ignore any alpha layer (transparency) and make the image fully opaque.
46
47 =item -name => 'string'
48
49 This is the name you can give for the TIFF image object. The default is Ixnnnn.
4850
4951 =back
5052
7173 =cut
7274
7375 sub new {
74 my ($class, $pdf, $file, $name, %opts) = @_;
76 my ($class, $pdf, $file, %opts) = @_;
77
78 my ($name, $compress);
79 if (exists $opts{'-name'}) { $name = $opts{'-name'}; }
80 #if (exists $opts{'-compress'}) { $compress = $opts{'-compress'}; }
7581
7682 my $self;
7783
78 my $tif = PDF::Builder::Resource::XObject::Image::TIFF::File_GT->new($file);
84 my $tif = PDF::Builder::Resource::XObject::Image::TIFF::File_GT->new($file, %opts);
7985
8086 # in case of problematic things
8187 # proxy to other modules
8288
83 $class = ref($class) if ref $class;
89 $class = ref($class) if ref($class);
8490
8591 $self = $class->SUPER::new($pdf, $name || 'Ix'.pdfkey());
8692 $pdf->new_obj($self) unless $self->is_obj($pdf);
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.017'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.017'; # manually update whenever code is changed
99
1010 use PDF::Builder::Basic::PDF::Utils;
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '2.031'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '2.031'; # manually update whenever code is changed
99
1010 use PDF::Builder::Basic::PDF::Utils;
1111
44 use strict;
55 use warnings;
66
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.017'; # manually update whenever code is changed
7 # VERSION
8 my $LAST_UPDATE = '3.017'; # manually update whenever code is changed
99
1010 use PDF::Builder::Util qw(pdfkey);
1111 use PDF::Builder::Basic::PDF::Utils; # PDFName
33 use warnings;
44 #no warnings qw[ deprecated recursion uninitialized ];
55
6 our $VERSION = '3.023'; # VERSION
7 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
6 # VERSION
7 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
88
99 =head1 NAME
1010
33 use warnings;
44 #no warnings qw[ recursion uninitialized ];
55
6 our $VERSION = '3.023'; # VERSION
7 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
6 # VERSION
7 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
88
99 # note: $a and $b are "Magic variables" according to perlcritic, and so it
1010 # has conniptions over using them as variable names (even with "my"). so, I
44
55 # $VERSION defined here so developers can run PDF::Builder from git.
66 # it should be automatically updated as part of the CPAN build.
7 our $VERSION = '3.023'; # VERSION
8 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
9
10 my $GrTFversion = 16; # minimum version of Graphics::TIFF
7 our $VERSION = '3.024'; # VERSION
8 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
9
10 # updated during CPAN build
11 my $GrTFversion = 16; # minimum version of Graphics::TIFF will be 17
1112 my $LpngVersion = 0.57; # minimum version of Image::PNG::Libpng
1213
1314 use Carp;
162163
163164 The release distribution is on CPAN: https://metacpan.org/pod/PDF::Builder.
164165
165 Bug reports are on https://github.com/PhilterPaper/Perl-PDF-Builder/issues?q=is%3Aissue+sort%3Aupdated-desc (with "bug" label), feature requests have an "enhancement" label, and general discussions (architecture, roadmap, etc.) have a "general discussion" label.
166
167 Do B<not> under I<any> circumstances open a PR (Pull Request) to report a bug. It is a waste of both your and our time and effort. Open a regular ticket (issue), and attach a Perl (.pl) program illustrating the problem, if possible. If you believe that you have a program patch, and offer to share it as a PR, we may give the go-ahead. Unsolicited PRs may be closed without further action.
166 Bug reports are on https://github.com/PhilterPaper/Perl-PDF-Builder/issues?q=is%3Aissue+sort%3Aupdated-desc
167 (with "bug" label), feature requests have an "enhancement" label, and general discussions (architecture, roadmap, etc.)
168 have a "general discussion" label.
169
170 Do B<not> under I<any> circumstances open a PR (Pull Request) to report a bug. It is a waste of both your and
171 our time and effort. Open a regular ticket (issue), and attach a Perl (.pl) program illustrating the problem, if possible.
172 If you believe that you have a program patch, and offer to share it as a PR, we may give the go-ahead. Unsolicited PRs
173 may be closed without further action.
168174
169175 =head1 LICENSE
170176
171 This software is Copyright (c) 2017-2021 by Phil M. Perry.
177 This software is Copyright (c) 2017-2022 by Phil M. Perry.
172178
173179 This is free software, licensed under:
174180
278284 $self->{'pages'} = PDF::Builder::Basic::PDF::Pages->new($self->{'pdf'});
279285 $self->{'pages'}->proc_set(qw(PDF Text ImageB ImageC ImageI));
280286 $self->{'pages'}->{'Resources'} ||= PDFDict();
281 $self->{'pdf'}->new_obj($self->{'pages'}->{'Resources'}) unless $self->{'pages'}->{'Resources'}->is_obj($self->{'pdf'});
287 $self->{'pdf'}->new_obj($self->{'pages'}->{'Resources'})
288 unless $self->{'pages'}->{'Resources'}->is_obj($self->{'pdf'});
282289 $self->{'catalog'} = $self->{'pdf'}->{'Root'};
283290 weaken $self->{'catalog'};
284291 $self->{'fonts'} = {};
330337
331338 my $version = eval { $PDF::Builder::VERSION } || '(Unreleased Version)';
332339 #$self->info('Producer' => "PDF::Builder $version [$^O]");
333 $self->info('Producer' => "PDF::Builder $version [see https://github.com/PhilterPaper/Perl-PDF-Builder/blob/master/INFO/SUPPORT]");
340 $self->info('Producer' => "PDF::Builder $version [see ".
341 "https://github.com/PhilterPaper/Perl-PDF-Builder/blob/master/INFO/SUPPORT]");
334342
335343 return $self;
336344 } # end of new()
406414 # ' version' should be the same as $outVer
407415 if ($PDFver > $outVer) {
408416 if ($msgVer) {
409 print "PDF version of requested feature '$featureName'\n is higher than outVer of $outVer (outVer reset to $PDFver)\n";
417 print "PDF version of requested feature '$featureName'\n is higher than outVer ".
418 "of $outVer (outVer reset to $PDFver)\n";
410419 }
411420 $outVer = $myself->{' version'} = $PDFver;
412421 return 1;
506515 }
507516 if ($newVer > $currentVer) {
508517 if (length($newVer) > length($currentVer)) {
509 print STDERR "Unable to update 'content' version because override '$newVer' is longer than header version '$currentVer'.\nYou may receive warnings about features that bump up the PDF level.\n";
518 print STDERR "Unable to update 'content' version because override '$newVer' is longer ".
519 "than header version '$currentVer'.\nYou may receive warnings about features ".
520 "that bump up the PDF level.\n";
510521 } else {
511522 if (length($newVer) < length($currentVer)) {
512523 # unlikely, but cover all the bases
666677 $self->{'catalog'}->{'OpenAction'} = PDFArray($page, PDFName('FitBV'), PDFNum($args{'-fitbv'}));
667678 } elsif (defined $args{'-fitr'}) {
668679 croak 'insufficient parameters to -fitr => []' unless scalar @{$args{'-fitr'}} == 4;
669 $self->{'catalog'}->{'OpenAction'} = PDFArray($page, PDFName('FitR'), map { PDFNum($_) } @{$args{'-fitr'}});
680 $self->{'catalog'}->{'OpenAction'} = PDFArray($page, PDFName('FitR'),
681 map { PDFNum($_) } @{$args{'-fitr'}});
670682 } elsif (defined $args{'-xyz'}) {
671683 croak 'insufficient parameters to -xyz => []' unless scalar @{$args{'-xyz'}} == 3;
672 $self->{'catalog'}->{'OpenAction'} = PDFArray($page, PDFName('XYZ'), map { PDFNum($_) } @{$args{'-xyz'}});
684 $self->{'catalog'}->{'OpenAction'} = PDFArray($page, PDFName('XYZ'),
685 map { PDFNum($_) } @{$args{'-xyz'}});
673686 }
674687 }
675688 $self->{'pdf'}->out_obj($self->{'catalog'});
851864 $self->{'pdf'}->new_obj($self->{'catalog'}->{'Metadata'});
852865 } else {
853866 $self->{'catalog'}->{'Metadata'}->realise();
854 $self->{'catalog'}->{'Metadata'}->{' stream'} = unfilter($self->{'catalog'}->{'Metadata'}->{'Filter'}, $self->{'catalog'}->{'Metadata'}->{' stream'});
867 $self->{'catalog'}->{'Metadata'}->{' stream'} =
868 unfilter($self->{'catalog'}->{'Metadata'}->{'Filter'},
869 $self->{'catalog'}->{'Metadata'}->{' stream'});
855870 delete $self->{'catalog'}->{'Metadata'}->{' nofilt'};
856871 delete $self->{'catalog'}->{'Metadata'}->{'Filter'};
857872 }
871886
872887 =item $pdf->pageLabel($index, $options)
873888
874 Sets page label options.
889 Sets page label options, for the page-selection slider thumb (I<not> the
890 outline/bookmarks). At this time, there is no method to automatically
891 synchronize a page's label with the outline/bookmarks, or to somewhere on the
892 printed page.
893
894 Note that many PDF Readers ignore these settings, and (at most) simply give
895 you the physical page number 1, 2, 3,... instead of the page label specified
896 here.
875897
876898 B<Supported Options:>
877899
879901
880902 =item -style
881903
882 Roman, roman, decimal, Alpha or alpha.
904 B<Roman> (I,II,III,...), B<roman> (i,ii,iii,...), B<decimal> (1,2,3,...),
905 B<Alpha> (A,B,C,...), B<alpha> (a,b,c,...), or B<nocounter>. This is the
906 styling of the counter part of the label (unless C<nocounter>, in which case
907 there is no counter output).
883908
884909 =item -start
885910
886 Restart numbering at given number.
911 (Re)start numbering the I<counter> at given page number (this is a decimal
912 integer, I<not> the styled counter). By default it starts at 1, and B<resets>
913 to 1 at each call to C<pageLabel()>! You need to explicitly give C<-start> if
914 you want to I<continue> counting at the current page number when you call
915 C<pageLabel()>, whether or not you are changing the format.
916
917 Also note that the counter starts at physical page B<1>, while the page
918 C<$index> number in the C<pageLabel()> call (as well as the PDF PageLabels
919 dictionary) starts at logical page (index) B<0>.
887920
888921 =item -prefix
889922
890 Text prefix for numbering.
923 Text prefix for numbering, such as an Appendix letter B<B->. If C<-style> is
924 I<nocounter>, just this text is used, otherwise a styled counter will be
925 appended. If C<-style> is omitted, remember that it will default to a decimal
926 number, which will be appended to the prefix.
927
928 According to the Adobe/ISO PDF specification, a prefix of 'Content' has a
929 special meaning, in that any /S counter is ignored and only that text is used.
930 However, this appears to be ignored (use a style of I<nocounter> to suppress
931 the counter).
891932
892933 =back
893934
894935 B<Example:>
895936
896 # Start with Roman Numerals
937 # Start with lowercase Roman Numerals at the 1st page, starting with i (1)
897938 $pdf->pageLabel(0, {
898939 -style => 'roman',
899940 });
900941
901 # Switch to Arabic
942 # Switch to Arabic (decimal) at the 5th page, starting with 1
902943 $pdf->pageLabel(4, {
903944 -style => 'decimal',
904945 });
905946
906 # Numbering for Appendix A
947 # invalid style at the 25th page, should just continue
948 # with decimal at the current counter
949 $pdf->pageLabel(24, {
950 -style => 'glorp', # fail over to decimal
951 -start => 21, # necessary, otherwise would restart at 1
952 });
953
954 # No page label at the 31st and 32nd pages. Note that this could be
955 # confusing to the person viewing the PDF, but may be appropriate if
956 # the page itself has no numbering.
957 $pdf->pageLabel(30, {
958 -style => 'nocounter',
959 });
960
961 # Numbering for Appendix A at the 33rd page, A-1, A-2,...
907962 $pdf->pageLabel(32, {
908 -start => 1,
963 -start => 1, # unnecessary
909964 -prefix => 'A-'
910965 });
911966
912 # Numbering for Appendix B
967 # Numbering for Appendix B at the 37th page, B-1, B-2,...
913968 $pdf->pageLabel( 36, {
914 -start => 1,
915969 -prefix => 'B-'
916970 });
917971
918 # Numbering for the Index
972 # Numbering for the Index at the 41st page, Index I, Index II,...
919973 $pdf->pageLabel(40, {
920 -style => 'Roman'
921 -start => 1,
974 -style => 'Roman',
975 -start => 1, # unnecessary
976 -prefix => 'Index ' # note trailing space
977 });
978
979 # Unnumbered 'Index' at the 45th page, Index, Index,...
980 $pdf->pageLabel(40, {
981 -style => 'nocounter',
922982 -prefix => 'Index '
923983 });
924984
939999
9401000 my $d = PDFDict();
9411001 if (defined $opts->{'-style'}) {
942 $d->{'S'} = PDFName($opts->{'-style'} eq 'Roman' ? 'R' :
943 $opts->{'-style'} eq 'roman' ? 'r' :
944 $opts->{'-style'} eq 'Alpha' ? 'A' :
945 $opts->{'-style'} eq 'alpha' ? 'a' : 'D');
1002 if ($opts->{'-style'} ne 'nocounter') {
1003 # defaults to decimal if unrecogized style given
1004 $d->{'S'} = PDFName($opts->{'-style'} eq 'Roman' ? 'R' :
1005 $opts->{'-style'} eq 'roman' ? 'r' :
1006 $opts->{'-style'} eq 'Alpha' ? 'A' :
1007 $opts->{'-style'} eq 'alpha' ? 'a' : 'D');
1008 } else {
1009 # for nocounter (no styled counter), do not create /S entry
1010 }
9461011 } else {
1012 # default to decimal counter if no -style given
9471013 $d->{'S'} = PDFName('D');
9481014 }
9491015
9501016 if (defined $opts->{'-prefix'}) {
1017 # 'Content' supposedly treated differently
9511018 $d->{'P'} = PDFString($opts->{'-prefix'}, 's');
9521019 }
9531020
14671534 # This should never get past MediaBox, since it's a required object.
14681535 foreach my $k (qw(MediaBox ArtBox TrimBox BleedBox CropBox)) {
14691536 #next unless defined $s_page->{$k};
1470 #my $box = _walk_obj($self->{'apiimportcache'}->{$s_pdf}, $s_pdf->{'pdf'}, $self->{'pdf'}, $s_page->{$k});
1537 #my $box = _walk_obj($self->{'apiimportcache'}->{$s_pdf}, $s_pdf->{'pdf'},
1538 # $self->{'pdf'}, $s_page->{$k});
14711539 next unless defined $s_page->find_prop($k);
1472 my $box = _walk_obj($self->{'apiimportcache'}->{$s_pdf}, $s_pdf->{'pdf'}, $self->{'pdf'}, $s_page->find_prop($k));
1540 my $box = _walk_obj($self->{'apiimportcache'}->{$s_pdf}, $s_pdf->{'pdf'},
1541 $self->{'pdf'}, $s_page->find_prop($k));
14731542 $xo->bbox(map { $_->val() } $box->elements());
14741543 last;
14751544 }
14851554 $s_page->{$k}->{$sk}->realise() if ref($s_page->{$k}->{$sk}) =~ /Objind$/;
14861555 foreach my $ssk (keys %{$s_page->{$k}->{$sk}}) {
14871556 next if $ssk =~ /^ /;
1488 $xo->resource($sk, $ssk, _walk_obj($self->{'apiimportcache'}->{$s_pdf}, $s_pdf->{'pdf'}, $self->{'pdf'}, $s_page->{$k}->{$sk}->{$ssk}));
1557 $xo->resource($sk, $ssk, _walk_obj($self->{'apiimportcache'}->{$s_pdf},
1558 $s_pdf->{'pdf'}, $self->{'pdf'}, $s_page->{$k}->{$sk}->{$ssk}));
14891559 }
14901560 }
14911561 }
16151685 if (my $a = $s_pdf->{'pdf'}->{'Root'}->realise()->{'AcroForm'}) {
16161686 $a->realise();
16171687
1618 $AcroForm = _walk_obj({}, $s_pdf->{'pdf'}, $self->{'pdf'}, $a, qw(NeedAppearances SigFlags CO DR DA Q));
1688 $AcroForm = _walk_obj({}, $s_pdf->{'pdf'}, $self->{'pdf'}, $a,
1689 qw(NeedAppearances SigFlags CO DR DA Q));
16191690 }
16201691 my @Fields = ();
16211692 my @Annots = ();
21512222
21522223 =over
21532224
2225 =item $jpeg = $pdf->image_jpeg($file, %options)
2226
21542227 =item $jpeg = $pdf->image_jpeg($file)
21552228
21562229 Imports and returns a new JPEG image object. C<$file> may be either a filename
21612234
21622235 =cut
21632236
2164 # =item $jpeg = $pdf->image_jpeg($file, %options) no current options
2165
21662237 sub image_jpeg {
21672238 my ($self, $file, %opts) = @_;
21682239
21692240 require PDF::Builder::Resource::XObject::Image::JPEG;
2170 my $obj = PDF::Builder::Resource::XObject::Image::JPEG->new($self->{'pdf'}, $file);
2241 my $obj = PDF::Builder::Resource::XObject::Image::JPEG->new($self->{'pdf'}, $file, %opts);
21712242
21722243 $self->{'pdf'}->out_obj($self->{'pages'});
21732244
21742245 return $obj;
21752246 }
21762247
2177 =item $tiff = $pdf->image_tiff($file, %opts)
2248 =item $tiff = $pdf->image_tiff($file, %options)
21782249
21792250 =item $tiff = $pdf->image_tiff($file)
21802251
21862257 L<PDF::Builder::Resource::XObject::Image::TIFF_GT> for additional information
21872258 and C<examples/Content.pl>
21882259 for some examples of placing an image on a page (JPEG, but the principle is
2189 the same). There is an optional TIFF library described, that gives more
2190 capability than the default one.
2260 the same).
2261 There is an optional TIFF library (TIFF_GT) described, that gives more
2262 capability than the default one. However, note that C<$file> can only be
2263 a filename when using this library.
21912264
21922265 =cut
21932266
22052278 if ($rc == 1) {
22062279 # Graphics::TIFF (_GT suffix) available and to be used
22072280 require PDF::Builder::Resource::XObject::Image::TIFF_GT;
2208 $obj = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($self->{'pdf'}, $file, 'Ix'.pdfkey(), %opts);
2281 $obj = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($self->{'pdf'}, $file, %opts);
22092282 $self->{'pdf'}->out_obj($self->{'pages'});
22102283 } else {
22112284 # Graphics::TIFF not available, or is but is not to be used
22122285 require PDF::Builder::Resource::XObject::Image::TIFF;
2213 $obj = PDF::Builder::Resource::XObject::Image::TIFF->new($self->{'pdf'}, $file, 'Ix'.pdfkey(), %opts);
2286 $obj = PDF::Builder::Resource::XObject::Image::TIFF->new($self->{'pdf'}, $file, %opts);
22142287 $self->{'pdf'}->out_obj($self->{'pages'});
22152288
22162289 if ($rc == 0 && $MSG_COUNT[0]++ == 0) {
22172290 # give warning message once, unless silenced (-silent) or
22182291 # deliberately not using Graphics::TIFF (rc == -1)
22192292 if (!defined $opts{'-silent'} || $opts{'-silent'} == 0) {
2220 print STDERR "Your system does not have Graphics::TIFF installed, so some\nTIFF functions may not run correctly.\n";
2293 print STDERR "Your system does not have Graphics::TIFF installed, ".
2294 "so some\nTIFF functions may not run correctly.\n";
22212295 # even if -silent only once, COUNT still incremented
22222296 }
22232297 }
22632337 return $rc;
22642338 }
22652339
2340 =item $pnm = $pdf->image_pnm($file, %options)
2341
22662342 =item $pnm = $pdf->image_pnm($file)
22672343
22682344 Imports and returns a new PNM image object. C<$file> may be either a filename
22692345 or a filehandle.
22702346
2271 See C<examples/Content.pl>
2272 for some examples of placing an image on a page (JPEG, but the principle is
2273 the same).
2274
2275 =cut
2276
2277 # =item $pnm = $pdf->image_pnm($file, %options) no current options
2347 See L<PDF::Builder::Resource::XObject::Image::PNM> for additional information
2348 and C<examples/Content.pl> for some examples of placing an image on a page
2349 (JPEG, but the principle is the same).
2350
2351 =cut
22782352
22792353 sub image_pnm {
22802354 my ($self, $file, %opts) = @_;
22812355
2356 $opts{'-compress'} //= $self->{'forcecompress'};
2357
22822358 require PDF::Builder::Resource::XObject::Image::PNM;
2283 my $obj = PDF::Builder::Resource::XObject::Image::PNM->new($self->{'pdf'}, $file);
2359 my $obj = PDF::Builder::Resource::XObject::Image::PNM->new($self->{'pdf'}, $file, %opts);
2360
22842361 $self->{'pdf'}->out_obj($self->{'pages'});
22852362
22862363 return $obj;
22982375 L<PDF::Builder::Resource::XObject::Image::PNG_IPL> for additional information
22992376 and C<examples/Content.pl>
23002377 for some examples of placing an image on a page (JPEG, but the principle is
2301 the same). There is an optional PNG library (PNG_IPL) described, that gives more
2302 capability than the default one.
2378 the same).
2379
2380 There is an optional PNG library (PNG_IPL) described, that gives more
2381 capability than the default one. However, note that C<$file> can only be
2382 a filename when using this library.
23032383
23042384 =cut
23052385
23172397 if ($rc == 1) {
23182398 # Image::PNG::Libpng (_IPL suffix) available and to be used
23192399 require PDF::Builder::Resource::XObject::Image::PNG_IPL;
2320 $obj = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($self->{'pdf'}, $file, 'Px'.pdfkey(), %opts);
2400 $obj = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($self->{'pdf'}, $file, %opts);
23212401 $self->{'pdf'}->out_obj($self->{'pages'});
23222402 } else {
23232403 # Image::PNG::Libpng not available, or is but is not to be used
23242404 require PDF::Builder::Resource::XObject::Image::PNG;
2325 $obj = PDF::Builder::Resource::XObject::Image::PNG->new($self->{'pdf'}, $file, 'Px'.pdfkey(), %opts);
2405 $obj = PDF::Builder::Resource::XObject::Image::PNG->new($self->{'pdf'}, $file, %opts);
23262406 $self->{'pdf'}->out_obj($self->{'pages'});
23272407
23282408 if ($rc == 0 && $MSG_COUNT[1]++ == 0) {
23292409 # give warning message once, unless silenced (-silent) or
23302410 # deliberately not using Image::PNG::Libpng (rc == -1)
23312411 if (!defined $opts{'-silent'} || $opts{'-silent'} == 0) {
2332 print STDERR "Your system does not have Image::PNG::Libpng installed, so some\nPNG functions may not run correctly.\n";
2412 print STDERR "Your system does not have Image::PNG::Libpng installed, ".
2413 "so some\nPNG functions may not run correctly.\n";
23332414 # even if -silent only once, COUNT still incremented
23342415 }
23352416 }
23742455 return $rc;
23752456 }
23762457
2458 =item $gif = $pdf->image_gif($file, %options)
2459
23772460 =item $gif = $pdf->image_gif($file)
23782461
23792462 Imports and returns a new GIF image object. C<$file> may be either a filename
23852468
23862469 =cut
23872470
2388 # =item $gif = $pdf->image_gif($file, %options) no current options
2389
23902471 sub image_gif {
23912472 my ($self, $file, %opts) = @_;
23922473
24032484
24042485 Imports and returns a new image object from Image::GD.
24052486
2406 Valid %options are:
2407
2408 =over
2409
2410 =item -lossless => 1
2411
2412 Use lossless compression.
2413
2414 =back
2415
24162487 See L<PDF::Builder::Resource::XObject::Image::GD> for additional information
24172488 and C<examples/Content.pl> for some examples of placing an image on a page
24182489 (JPEG, but the principle is the same).
24232494 my ($self, $gd, %options) = @_;
24242495
24252496 require PDF::Builder::Resource::XObject::Image::GD;
2426 my $obj = PDF::Builder::Resource::XObject::Image::GD->new($self->{'pdf'}, $gd, undef, %options);
2497 my $obj = PDF::Builder::Resource::XObject::Image::GD->new($self->{'pdf'}, $gd, %options);
24272498 $self->{'pdf'}->out_obj($self->{'pages'});
24282499
24292500 return $obj;
28662937 # first /Parent (should not be more)
28672938 $objList{$objKey}->[$idx_parent] = $Parent;
28682939 #} else {
2869 # print STDERR "$IC Additional Parent ($Parent) in object $objKey, already list $objList{$objKey}->[$idx_parent] as Parent.\n" if $level >= $level_error;
2940 # print STDERR "$IC Additional Parent ($Parent) in object $objKey, already list ".
2941 # "$objList{$objKey}->[$idx_parent] as Parent.\n" if $level >= $level_error;
28702942 #}
28712943 }
28722944
28952967 @{$objList{$objKey}->[$idx_kid_list]} = @Kids;
28962968 $objList{$objKey}->[$idx_kid_cnt] = scalar(@Kids);
28972969 #} else {
2898 # print STDERR "$IC Multiple Kids lists in object $objKey, already list @{$objList{$objKey}->[$idx_kid_list]} as Kids.\n" if $level >= $level_error;
2970 # print STDERR "$IC Multiple Kids lists in object $objKey, already list ".
2971 # "@{$objList{$objKey}->[$idx_kid_list]} as Kids.\n" if $level >= $level_error;
28992972 #}
29002973 }
29012974
30263099 $objList{$child}[$idx_par_clmd] = $thisObj;
30273100 } else {
30283101 # someone else has already claimed to be parent
3029 print STDERR "$IC object $thisObj wants to claim object $child as its child, but $objList{$child}[$idx_par_clmd] already has!\nPossibly $child is on more than one /Kids list?\n" if $level >= $level_error;
3102 print STDERR "$IC object $thisObj wants to claim object $child as its child, ".
3103 "but $objList{$child}[$idx_par_clmd] already has!\nPossibly $child ".
3104 "is on more than one /Kids list?\n" if $level >= $level_error;
30303105 }
30313106 # if no object defined for child, already flagged as missing
30323107 if ($objList{$child}[$idx_defined] == 1) {
30333108 # child should list thisObj as its Parent
30343109 if ($objList{$child}[$idx_parent] == -1) {
3035 print STDERR "$IC object $thisObj claims $child as a child (/Kids), but $child claims no Parent!\n" if $level >= $level_error;
3110 print STDERR "$IC object $thisObj claims $child as a child (/Kids), but ".
3111 "$child claims no Parent!\n" if $level >= $level_error;
30363112 $objList{$child}[$idx_parent] = $thisObj;
30373113 } elsif ($objList{$child}[$idx_parent] != $thisObj) {
3038 print STDERR "$IC object $thisObj claims $child as a child (/Kids), but $child claims $objList{$child}[$idx_parent] as its parent!\n" if $level >= $level_error;
3114 print STDERR "$IC object $thisObj claims $child as a child (/Kids), but ".
3115 "$child claims $objList{$child}[$idx_parent] as its parent!\n"
3116 if $level >= $level_error;
30393117 }
30403118 }
30413119 }
+0
-280
optional_update.pl less more
0 #!/usr/bin/perl
1 use warnings;
2 use strict;
3
4 # a utility to select which optional prerequisites to remove from the
5 # "recommends" list in Makefile.PL, META.json, and META.yml before manually
6 # running Makefile.PL to build the product.
7
8 # Makefile.PL and META.yml
9 # delete an option by #-out the line
10 # restore an option by removing #
11 # META.json (does not support comments)
12 # delete an option by erasing the line
13 # restore an option by adding line back in
14
15 # t/00-all-usable.t and lib/PDF/Builder.pm, while also making use of the
16 # optional prerequisites, do not need to exclude unused optionals.
17
18 our $VERSION = '3.023'; # VERSION
19 our $LAST_UPDATE = '3.023'; # manually update whenever code is changed
20
21 # master list of optional prerequisites:
22 # make sure that any updates to patterns etc. keep the same order
23 my %options = (
24 '1' => ["Graphics::TIFF", "16" ],
25 '2' => ["Image::PNG::Libpng", "0.57" ],
26 '3' => ["HarfBuzz::Shaper", "0.024"],
27 );
28
29 print "\nHere are the available optional libraries. Select 0 or more of\n";
30 print "them by entering their key numbers 1,2,3, etc. in a one-line list,\n";
31 print "separated by commas and/or spaces. Enter all numbers for the normal\n";
32 print "default of ALL selected:\n";
33
34 my ($i, $j, @list);
35 my $numEntries = scalar keys %options;
36 for ($i=1; $i<=$numEntries; $i++) {
37 print "$i $options{$i}[0] (version $options{$i}[1])\n";
38 }
39 print "\nEnter any (or all) numbers to use: ";
40 my $input = <>;
41 if (length($input)) {
42 @list = split /[\s,]+/, $input;
43 # valid entries?
44 for ($j=0; $j<scalar @list; $j++) {
45 if ($list[$j] =~ m/^\d+$/ &&
46 $list[$j] <= $numEntries &&
47 $list[$j] > 0) {
48 # valid number
49 } else {
50 die "Invalid entry '$list[$j]'!\n";
51 }
52 }
53 # too many entries?
54 if (scalar @list > $numEntries) {
55 die "Too many entries!\n";
56 }
57 # duplicate entries?
58 for ($i=0; $i<scalar @list; $i++) {
59 for ($j=0; $j<$i; $j++) {
60 if ($list[$i] == $list[$j]) {
61 die "Duplicate entry at position $i!\n";
62 }
63 }
64 }
65 } else {
66 @list = ();
67 }
68 print "list: @list\n";
69
70 update_Makefile();
71 update_META_json();
72 update_META_yml();
73
74 return;
75
76 # in all cases, remove "recommends" if @list is empty
77 # Makefile.PL find line and # out if not in @list, remove any # if in @list
78 sub update_Makefile {
79 # file should be ./Makefile.PL
80 my @pattern = (
81 "(\"Graphics::TIFF\"\\s*=>\\s*)[\\d.]+,",
82 "(\"Image::PNG::Libpng\"\\s*=>\\s*)[\\d.]+,",
83 "(\"HarfBuzz::Shaper\"\\s*=>\\s*)[\\d.]+,",
84 );
85
86 my $infile = "Makefile.PL";
87 my $outtemp = "xxxx.tmp";
88 my ($IN, $OUT);
89 unless (open($IN, "<", $infile)) {
90 die "Unable to read $infile for update\n";
91 }
92 unless (open($OUT, ">", $outtemp)) {
93 die "Unable to write temporary output file for $infile update\n";
94 }
95
96 my ($line, $i);
97 my $flag = 0;
98 while ($line = <$IN>) {
99 # $line still has line-end \n
100
101 # no optionals requested? #-out "recommends" => { and },
102 if (!scalar(@list)) {
103 if ($line =~ m/^[^#]\s+"recommends" => \{/) {
104 $flag = 1;
105 $line = '#'.$line;
106 }
107 if ($flag && $line =~ m/},/) {
108 $flag = 0;
109 $line = '#'.$line;
110 }
111 }
112
113 # if there ARE optionals, un-# "recommends" and }
114 if (scalar(@list)) {
115 if ($line =~ m/^#\s+"recommends" => \{/) {
116 $flag = 1;
117 $line = substr($line, 1);
118 }
119 if ($flag && $line =~ m/^#\s+},?/) {
120 $flag = 0;
121 $line = substr($line, 1);
122 }
123 }
124
125 for ($i=0; $i<$numEntries; $i++) {
126 if ($line =~ m/$pattern[$i]/) {
127 if (member_of($i+1, @list)) {
128 # is in list, remove any leading #
129 if ($line =~ m/^#/) {
130 $line =~ s/^#//;
131 }
132 } else {
133 # is not in list, comment-out unless already done so
134 if ($line !~ m/^#/) {
135 $line = '#'.$line;
136 }
137 }
138 last;
139 }
140 }
141 print $OUT $line;
142 }
143
144 close($IN);
145 close($OUT);
146 system("copy $outtemp $infile");
147 unlink($outtemp);
148
149 return;
150 } # end of update_Makefile()
151
152 # META.json find line and remove if not in @list, add back in if in @list
153 sub update_META_json {
154 # file should be ./META.json
155 my @pattern = (
156 "(\"Graphics::TIFF\"\\s*:\\s*)\"[\\d.]+\"",
157 "(\"Image::PNG::Libpng\"\\s*:\\s*)\"[\\d.]+\"",
158 "(\"HarfBuzz::Shaper\"\\s*:\\s*)\"[\\d.]+\"",
159 );
160
161 my $infile = "META.json";
162 my $outtemp = "xxxx.tmp";
163 my ($IN, $OUT);
164 unless (open($IN, "<", $infile)) {
165 die "Unable to read $infile for update\n";
166 }
167 unless (open($OUT, ">", $outtemp)) {
168 die "Unable to write temporary output file for $infile update\n";
169 }
170
171 my ($line, $i);
172 my $flag = 0;
173 while ($line = <$IN>) {
174 # $line still has line-end \n
175
176 # NOTE: my understanding is that an empty { } is legal
177 # remove lines in-between "recommends" and }[,]
178 # re-insert desired ones
179 if ($line =~ m/"recommends"\s*:/) {
180 $flag = 1;
181 } elsif ($flag && $line =~ m/},?/) {
182 $flag = 0;
183 # re-insert desired options before closing },
184 # $line still has }, in it waiting to be output
185 my $count = 0;
186 for ($i=1; $i<=$numEntries; $i++) {
187 # is $i in @list? replace in file
188 if (member_of($i, @list)) {
189 print $OUT " \"$options{$i}[0]\" : \"$options{$i}[1]\"";
190 if (++$count == scalar(@list)) {
191 # last one, no comma
192 print $OUT "\n";
193 } else {
194 # not last one, add comma
195 print $OUT ",\n";
196 }
197 }
198 }
199 } elsif ($flag) {
200 # erase this entry (all optional entries will be erased)
201 next;
202 }
203 print $OUT $line;
204 }
205
206 close($IN);
207 close($OUT);
208 system("copy $outtemp $infile");
209 unlink($outtemp);
210
211 return;
212 } # end of update_META_json()
213
214 # META.yml find line and # out if not in @list, remove any # if in @list
215 sub update_META_yml {
216 # file should be ./Makefile.PL
217 my @pattern = (
218 "(Graphics::TIFF:\\s*)'[\\d.]+'",
219 "(Image::PNG::Libpng:\\s*)'[\\d.]+'",
220 "(HarfBuzz::Shaper:\\s*)'[\\d.]+'",
221 );
222
223 my $infile = "META.yml";
224 my $outtemp = "xxxx.tmp";
225 my ($IN, $OUT);
226 unless (open($IN, "<", $infile)) {
227 die "Unable to read $infile for update\n";
228 }
229 unless (open($OUT, ">", $outtemp)) {
230 die "Unable to write temporary output file for $infile update\n";
231 }
232
233 my ($line, $i);
234 while ($line = <$IN>) {
235 # $line still has line-end \n
236
237 # no optionals requested? #-out recommends:
238 if (!scalar(@list)) {
239 if ($line =~ m/^[^#]\s*recommends:/) {
240 $line = '#'.$line;
241 }
242 }
243
244 for ($i=0; $i<$numEntries; $i++) {
245 if ($line =~ m/$pattern[$i]/) {
246 if (member_of($i+1, @list)) {
247 # is in list, remove any leading #
248 if ($line =~ m/^#/) {
249 $line =~ s/^#//;
250 }
251 } else {
252 # is not in list, comment-out unless already done so
253 if ($line !~ m/^#/) {
254 $line = '#'.$line;
255 }
256 }
257 last;
258 }
259 }
260 print $OUT $line;
261 }
262
263 close($IN);
264 close($OUT);
265 system("copy $outtemp $infile");
266 unlink($outtemp);
267
268 return;
269 } # end of update_META_yml()
270
271 sub member_of {
272 my ($member, @list) = @_;
273
274 if ($member ~~ @list) {
275 return 1;
276 } else {
277 return 0;
278 }
279 }
44 use Test::More;
55 use File::Find;
66
7 my $GrTFversion = 16; # minimum version of Graphics::TIFF
7 my $GrTFversion = 17; # minimum version of Graphics::TIFF
88 my $LpngVersion = 0.57; # minimum version of Image::PNG::Libpng
99
1010 # Test all of the modules to make sure that a simple "use Module"
1414
1515 my $string = $pdf->stringify();
1616 like($string,
17 qr{/Type /Annot /Subtype /Text /Border \[ 0 0 1 \] /Contents \(This is an annotation\) /Rect \[ 72 144 172 244 \]},
17 qr{/Type /Annot /Subtype /Text /Border \[ 0 0 0 \] /Contents \(This is an annotation\) /Rect \[ 72 144 172 244 \]},
1818 q{Text Annotation in a rectangle});
1919
2020 # [RT #118352] Crash if $page->annotation is called on a page with an
3838
3939 $string = $pdf->stringify();
4040 like($string,
41 qr{/Type /Annot /Subtype /Text /Border \[ 0 0 1 \] /Contents \(This is an annotation\) /Rect \[ 72 144 172 244 \]},
41 qr{/Type /Annot /Subtype /Text /Border \[ 0 0 0 \] /Contents \(This is an annotation\) /Rect \[ 72 144 172 244 \]},
4242 q{Add an annotation to an existing annotations array stored in an indirect object});
4343
4444 1;
66 use File::Temp;
77 use version;
88 use Test::More tests => 19;
9 #use Test::More tests => 25; when TIFF changes in
910
1011 use PDF::Builder;
1112 # 0: allow use of Graphics::TIFF, 1: force non-GT usage
353354 $height = 100;
354355 }
355356
356 # 17
357 SKIP: {
358 #skip "currently fails due to bug inherited from PDF::API2", 1;
357 # 17 TODO
358 SKIP: {
359359 skip "multi-strip lzw without GT is not currently supported", 1;
360360 system("$convert -depth 1 -gravity center -pointsize 78 -size ${width}x${height} caption:\"A caption for the image\" -background white -alpha off -define tiff:rows-per-strip=50 -compress lzw $tiff_f");
361361 # ----------
433433
434434 is($example, $expected, "bilevel and alpha when width not a whole number of bytes with GT") or show_diag();
435435 }
436
437 if (0) { ####################################### when TIFF changes in
438 # 20 TODO
439 SKIP: {
440 skip "alpha layer without GT is not currently supported", 1;
441 #SKIP: {
442 # skip "Either ImageMagick or Ghostscript not available.", 1 unless
443 # defined $convert and defined $gs;
444 $width = 6;
445 $height = 1;
446 system("$convert -depth 1 -size ${width}x${height} pattern:gray50 -alpha on $tiff_f");
447 $pdf = PDF::Builder->new(-file => $pdfout);
448 $page = $pdf->page();
449 $page->mediabox( $width, $height );
450 $gfx = $page->gfx();
451 $img = $pdf->image_tiff($tiff_f, -nouseGT => 1);
452 $gfx->image( $img, 0, 0, $width, $height );
453 $pdf->save();
454 $pdf->end();
455
456 # ----------
457 system("$gs -q -dNOPAUSE -dBATCH -sDEVICE=pnggray -g${width}x${height} -dPDFFitPage -dUseCropBox -sOutputFile=$pngout $pdfout");
458 $example = `$convert $pngout -depth 1 -alpha off txt:-`;
459 $expected = `$convert $tiff_f -depth 1 -alpha off txt:-`;
460 # for reasons I don't understand, gs swaps the last two pixels here, so let's
461 # ignore them
462 $example =~ s/(.*\n).*\n.*\n$/$1/;
463 $expected =~ s/(.*\n).*\n.*\n$/$1/;
464 # ----------
465
466 is($example, $expected, "bilevel and alpha when width not a whole number of bytes without GT");
467 }
468
469 # 21
470 SKIP: {
471 skip "Either ImageMagick, Ghostscript or Graphics::TIFF not available.", 1 unless
472 defined $convert and defined $gs and $has_GT;
473
474 $width = 6;
475 $height = 2;
476 system("$convert -depth 1 -size ${width}x${height} pattern:gray50 -alpha off -define tiff:rows-per-strip=1 -compress fax $tiff_f");
477 $pdf = PDF::Builder->new(-file => $pdfout);
478 $page = $pdf->page();
479 $page->mediabox( $width, $height );
480 $gfx = $page->gfx();
481 $img = $pdf->image_tiff($tiff_f, -nouseGT => 0);
482 $gfx->image( $img, 0, 0, $width, $height );
483 $pdf->save();
484 $pdf->end();
485
486 # ----------
487 system("$gs -q -dNOPAUSE -dBATCH -sDEVICE=pnggray -g${width}x${height} -dPDFFitPage -dUseCropBox -sOutputFile=$pngout $pdfout");
488 $example = `$convert $pngout -depth 1 -alpha off txt:-`;
489 $expected = `$convert $tiff_f -depth 1 -alpha off txt:-`;
490 # ----------
491
492 is($example, $expected, 'multi-strip group 3 (not converted to flate) with GT');
493 }
494
495 # 22
496 SKIP: {
497 skip "Either ImageMagick, Ghostscript or Graphics::TIFF not available.", 1 unless
498 defined $convert and defined $gs and $has_GT;
499
500 $width = 6;
501 $height = 2;
502 system("$convert -depth 1 -size ${width}x${height} pattern:gray50 -alpha off -define tiff:rows-per-strip=1 -compress group4 $tiff_f");
503 $pdf = PDF::Builder->new(-file => $pdfout);
504 $page = $pdf->page();
505 $page->mediabox( $width, $height );
506 $gfx = $page->gfx();
507 $img = $pdf->image_tiff($tiff_f, -nouseGT => 0);
508 $gfx->image( $img, 0, 0, $width, $height );
509 $pdf->save();
510 $pdf->end();
511
512 # ----------
513 system("$gs -q -dNOPAUSE -dBATCH -sDEVICE=pnggray -g${width}x${height} -dPDFFitPage -dUseCropBox -sOutputFile=$pngout $pdfout");
514 $example = `$convert $pngout -depth 1 -alpha off txt:-`;
515 $expected = `$convert $tiff_f -depth 1 -alpha off txt:-`;
516 # ----------
517
518 is($example, $expected, 'multi-strip g4 (not converted to flate) with GT');
519 }
520
521 # 23
522 SKIP: {
523 skip "Either ImageMagick, Ghostscript or Graphics::TIFF not available.", 1 unless
524 defined $convert and defined $gs and $has_GT;
525
526 $width = 6;
527 $height = 2;
528 system("$convert -depth 1 -size ${width}x${height} pattern:gray50 -alpha off -define tiff:rows-per-strip=1 -define quantum:polarity=min-is-black -compress fax $tiff_f");
529 $pdf = PDF::Builder->new(-file => $pdfout);
530 $page = $pdf->page();
531 $page->mediabox( $width, $height );
532 $gfx = $page->gfx();
533 $img = $pdf->image_tiff($tiff_f, -nouseGT => 0);
534 $gfx->image( $img, 0, 0, $width, $height );
535 $pdf->save();
536 $pdf->end();
537
538 # ----------
539 system("$gs -q -dNOPAUSE -dBATCH -sDEVICE=pnggray -g${width}x${height} -dPDFFitPage -dUseCropBox -sOutputFile=$pngout $pdfout");
540 $example = `$convert $pngout -depth 1 -alpha off txt:-`;
541 $expected = `$convert $tiff_f -depth 1 -alpha off txt:-`;
542 # ----------
543
544 is($example, $expected, 'multi-strip g3 min-is-black (not converted to flate) with GT');
545 }
546
547 # 24
548 SKIP: {
549 skip "Either ImageMagick, Ghostscript or Graphics::TIFF not available.", 1 unless
550 defined $convert and defined $gs and $has_GT;
551
552 $width = 6;
553 $height = 2;
554 system("$convert -depth 1 -size ${width}x${height} pattern:gray50 -alpha off -define tiff:rows-per-strip=1 -define quantum:polarity=min-is-black -compress group4 $tiff_f");
555 $pdf = PDF::Builder->new(-file => $pdfout);
556 $page = $pdf->page();
557 $page->mediabox( $width, $height );
558 $gfx = $page->gfx();
559 $img = $pdf->image_tiff($tiff_f, -nouseGT => 0);
560 $gfx->image( $img, 0, 0, $width, $height );
561 $pdf->save();
562 $pdf->end();
563
564 # ----------
565 system("$gs -q -dNOPAUSE -dBATCH -sDEVICE=pnggray -g${width}x${height} -dPDFFitPage -dUseCropBox -sOutputFile=$pngout $pdfout");
566 $example = `$convert $pngout -depth 1 -alpha off txt:-`;
567 $expected = `$convert $tiff_f -depth 1 -alpha off txt:-`;
568 # ----------
569
570 is($example, $expected, 'multi-strip g4 min-is-black (not converted to flate) with GT');
571 }
572
573 # 25
574 SKIP: {
575 skip "Either ImageMagick, Ghostscript or Graphics::TIFF not available.", 1 unless
576 defined $convert and defined $gs and $has_GT;
577
578 $width = 6;
579 $height = 2;
580 system("$convert -depth 1 -size ${width}x${height} pattern:gray50 -alpha off -define tiff:fill-order=lsb -compress group4 $tiff_f");
581 $pdf = PDF::Builder->new(-file => $pdfout);
582 $page = $pdf->page();
583 $page->mediabox( $width, $height );
584 $gfx = $page->gfx();
585 $img = $pdf->image_tiff($tiff_f, -nouseGT => 0);
586 $gfx->image( $img, 0, 0, $width, $height );
587 $pdf->save();
588 $pdf->end();
589
590 # ----------
591 system("$gs -q -dNOPAUSE -dBATCH -sDEVICE=pnggray -g${width}x${height} -dPDFFitPage -dUseCropBox -sOutputFile=$pngout $pdfout");
592 $example = `$convert $pngout -depth 1 -alpha off txt:-`;
593 $expected = `$convert $tiff_f -depth 1 -alpha off txt:-`;
594 # ----------
595
596 is($example, $expected, 'LSB fillorder with GT');
597 }
598 } ####################################### when TIFF changes in
436599
437600 ##############################################################
438601 # cleanup. all tests involving these files skipped?
66 use strict;
77 use warnings;
88
9 our $VERSION = '3.023'; # VERSION
10 our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
9 # VERSION
10 my $LAST_UPDATE = '3.021'; # manually update whenever code is changed
1111
1212 # command line:
1313 # -5 run perlcritic -5 . (should be clean)
66 use strict;
77 use warnings;
88
9 our $VERSION = '3.023'; # VERSION
10 our $LAST_UPDATE = '3.016'; # manually update whenever code is changed
9 # VERSION
10 my $LAST_UPDATE = '3.024'; # manually update whenever code is changed
1111
1212 # command line flags, mutually exclusive:
1313 # -raw show full output of each t-test run
1414 # -noOK exclude "ok" lines so can easily spot error lines DEFAULT
1515
16 # add after filter-lzwdecode
17 # filter-ccittfaxdecode
1618 my @test_list = qw(
1719 00-all-usable
1820 01-basic
3133 extgstate
3234 filter-ascii85decode
3335 filter-asciihexdecode
36 filter-lzwdecode
3437 filter-runlengthdecode
3538 font-corefont
3639 font-synfont
66 use strict;
77 use warnings;
88
9 our $VERSION = '3.023'; # VERSION
10 our $LAST_UPDATE = '3.018'; # manually update whenever code is changed
9 # VERSION
10 my $LAST_UPDATE = '3.018'; # manually update whenever code is changed
1111
1212 # dependent on optional packages:
1313 my $HS_installed = 1; # HarfBuzz::Shaper IS installed and you want to use it.
66 use strict;
77 use warnings;
88
9 our $VERSION = '3.023'; # VERSION
10 our $LAST_UPDATE = '3.013'; # manually update whenever code is changed
9 # VERSION
10 my $LAST_UPDATE = '3.013'; # manually update whenever code is changed
1111
1212 # command line:
1313 #
0 #!/usr/bin/perl
1 use warnings;
2 use strict;
3
4 # a utility to select which optional prerequisites to remove from the
5 # "recommends" list in Makefile.PL, META.json, and META.yml before manually
6 # running Makefile.PL to build the product.
7
8 # Makefile.PL and META.yml
9 # delete an option by #-out the line
10 # restore an option by removing #
11 # META.json (does not support comments)
12 # delete an option by erasing the line
13 # restore an option by adding line back in
14
15 # t/00-all-usable.t and lib/PDF/Builder.pm, while also making use of the
16 # optional prerequisites, do not need to exclude unused optionals.
17
18 our $VERSION = '3.023'; # VERSION
19 our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
20
21 # master list of optional prerequisites:
22 # make sure that any updates to patterns etc. keep the same order
23 my %options = (
24 '1' => ["Graphics::TIFF", "16" ],
25 '2' => ["Image::PNG::Libpng", "0.57" ],
26 '3' => ["HarfBuzz::Shaper", "0.024"],
27 );
28
29 print "\nHere are the available optional libraries. Select 0 or more of\n";
30 print "them by entering their key numbers 1,2,3, etc. in a one-line list,\n";
31 print "separated by commas and/or spaces. Enter all numbers for the normal\n";
32 print "default of ALL selected:\n";
33
34 my ($i, $j, @list);
35 my $numEntries = scalar keys %options;
36 for ($i=1; $i<=$numEntries; $i++) {
37 print "$i $options{$i}[0] (version $options{$i}[1])\n";
38 }
39 print "\nEnter any (or all) numbers to use: ";
40 my $input = <>;
41 if (length($input)) {
42 @list = split /[\s,]+/, $input;
43 # valid entries?
44 for ($j=0; $j<scalar @list; $j++) {
45 if ($list[$j] =~ m/^\d+$/ &&
46 $list[$j] <= $numEntries &&
47 $list[$j] > 0) {
48 # valid number
49 } else {
50 die "Invalid entry '$list[$j]'!\n";
51 }
52 }
53 # too many entries?
54 if (scalar @list > $numEntries) {
55 die "Too many entries!\n";
56 }
57 # duplicate entries?
58 for ($i=0; $i<scalar @list; $i++) {
59 for ($j=0; $j<$i; $j++) {
60 if ($list[$i] == $list[$j]) {
61 die "Duplicate entry at position $i!\n";
62 }
63 }
64 }
65 } else {
66 @list = ();
67 }
68 print "list: @list\n";
69
70 update_Makefile();
71 update_META_json();
72 update_META_yml();
73
74 # in all cases, remove "recommends" if @list is empty
75 # Makefile.PL find line and # out if not in @list, remove any # if in @list
76 sub update_Makefile {
77 # file should be ./Makefile.PL
78 my @pattern = (
79 "(\"Graphics::TIFF\"\\s*=>\\s*)[\\d.]+,",
80 "(\"Image::PNG::Libpng\"\\s*=>\\s*)[\\d.]+,",
81 "(\"HarfBuzz::Shaper\"\\s*=>\\s*)[\\d.]+,",
82 );
83
84 my $infile = "Makefile.PL";
85 my $outtemp = "xxxx.tmp";
86 my ($IN, $OUT);
87 unless (open($IN, "<", $infile)) {
88 die "Unable to read $infile for update\n";
89 }
90 unless (open($OUT, ">", $outtemp)) {
91 die "Unable to write temporary output file for $infile update\n";
92 }
93
94 my ($line, $i);
95 my $flag = 0;
96 while ($line = <$IN>) {
97 # $line still has line-end \n
98
99 # no optionals requested? #-out "recommends" => { and },
100 if (!scalar(@list)) {
101 if ($line =~ m/^[^#]\s+"recommends" => \{/) {
102 $flag = 1;
103 $line = '#'.$line;
104 }
105 if ($flag && $line =~ m/},/) {
106 $flag = 0;
107 $line = '#'.$line;
108 }
109 }
110
111 # if there ARE optionals, un-# "recommends" and }
112 if (scalar(@list)) {
113 if ($line =~ m/^#\s+"recommends" => \{/) {
114 $flag = 1;
115 $line = substr($line, 1);
116 }
117 if ($flag && $line =~ m/^#\s+},?/) {
118 $flag = 0;
119 $line = substr($line, 1);
120 }
121 }
122
123 for ($i=0; $i<$numEntries; $i++) {
124 if ($line =~ m/$pattern[$i]/) {
125 if (member_of($i+1, @list)) {
126 # is in list, remove any leading #
127 if ($line =~ m/^#/) {
128 $line =~ s/^#//;
129 }
130 } else {
131 # is not in list, comment-out unless already done so
132 if ($line !~ m/^#/) {
133 $line = '#'.$line;
134 }
135 }
136 last;
137 }
138 }
139 print $OUT $line;
140 }
141
142 close($IN);
143 close($OUT);
144 system("copy $outtemp $infile");
145 unlink($outtemp);
146
147 return;
148 } # end of update_Makefile()
149
150 # META.json find line and remove if not in @list, add back in if in @list
151 sub update_META_json {
152 # file should be ./META.json
153 my @pattern = (
154 "(\"Graphics::TIFF\"\\s*:\\s*)\"[\\d.]+\"",
155 "(\"Image::PNG::Libpng\"\\s*:\\s*)\"[\\d.]+\"",
156 "(\"HarfBuzz::Shaper\"\\s*:\\s*)\"[\\d.]+\"",
157 );
158
159 my $infile = "META.json";
160 my $outtemp = "xxxx.tmp";
161 my ($IN, $OUT);
162 unless (open($IN, "<", $infile)) {
163 die "Unable to read $infile for update\n";
164 }
165 unless (open($OUT, ">", $outtemp)) {
166 die "Unable to write temporary output file for $infile update\n";
167 }
168
169 my ($line, $i);
170 my $flag = 0;
171 while ($line = <$IN>) {
172 # $line still has line-end \n
173
174 # NOTE: my understanding is that an empty { } is legal
175 # remove lines in-between "recommends" and }[,]
176 # re-insert desired ones
177 if ($line =~ m/"recommends"\s*:/) {
178 $flag = 1;
179 } elsif ($flag && $line =~ m/},?/) {
180 $flag = 0;
181 # re-insert desired options before closing },
182 # $line still has }, in it waiting to be output
183 my $count = 0;
184 for ($i=1; $i<=$numEntries; $i++) {
185 # is $i in @list? replace in file
186 if (member_of($i, @list)) {
187 print $OUT " \"$options{$i}[0]\" : \"$options{$i}[1]\"";
188 if (++$count == scalar(@list)) {
189 # last one, no comma
190 print $OUT "\n";
191 } else {
192 # not last one, add comma
193 print $OUT ",\n";
194 }
195 }
196 }
197 } elsif ($flag) {
198 # erase this entry (all optional entries will be erased)
199 next;
200 }
201 print $OUT $line;
202 }
203
204 close($IN);
205 close($OUT);
206 system("copy $outtemp $infile");
207 unlink($outtemp);
208
209 return;
210 } # end of update_META_json()
211
212 # META.yml find line and # out if not in @list, remove any # if in @list
213 sub update_META_yml {
214 # file should be ./Makefile.PL
215 my @pattern = (
216 "(Graphics::TIFF:\\s*)'[\\d.]+'",
217 "(Image::PNG::Libpng:\\s*)'[\\d.]+'",
218 "(HarfBuzz::Shaper:\\s*)'[\\d.]+'",
219 );
220
221 my $infile = "META.yml";
222 my $outtemp = "xxxx.tmp";
223 my ($IN, $OUT);
224 unless (open($IN, "<", $infile)) {
225 die "Unable to read $infile for update\n";
226 }
227 unless (open($OUT, ">", $outtemp)) {
228 die "Unable to write temporary output file for $infile update\n";
229 }
230
231 my ($line, $i);
232 while ($line = <$IN>) {
233 # $line still has line-end \n
234
235 # no optionals requested? #-out recommends:
236 if (!scalar(@list)) {
237 if ($line =~ m/^[^#]\s*recommends:/) {
238 $line = '#'.$line;
239 }
240 }
241
242 for ($i=0; $i<$numEntries; $i++) {
243 if ($line =~ m/$pattern[$i]/) {
244 if (member_of($i+1, @list)) {
245 # is in list, remove any leading #
246 if ($line =~ m/^#/) {
247 $line =~ s/^#//;
248 }
249 } else {
250 # is not in list, comment-out unless already done so
251 if ($line !~ m/^#/) {
252 $line = '#'.$line;
253 }
254 }
255 last;
256 }
257 }
258 print $OUT $line;
259 }
260
261 close($IN);
262 close($OUT);
263 system("copy $outtemp $infile");
264 unlink($outtemp);
265
266 return;
267 } # end of update_META_yml()
268
269 sub member_of {
270 my ($member, @list) = @_;
271
272 if ($member ~~ @list) {
273 return 1;
274 } else {
275 return 0;
276 }
277 }