Import upstream version 3.023+git20220405.1.ca65269
Debian Janitor
2 years ago
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) |
5 | 5 | Bug fixes to PDF::API2 (in PDF::Builder) are not mentioned if they correct |
6 | 6 | an error (that produces an error message and/or incorrect output) and do not |
7 | 7 | 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. | |
8 | 14 | |
9 | 15 | 3.022 2021-03-03 |
10 | 16 |
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 | |
1 | 1 | |
2 | 2 | In order to encourage others to contribute code and/or algorithms to the |
3 | 3 | effort, I am publishing this road map of where I would like the product to go. |
47 | 47 | |
48 | 48 | UPDATE: See Text::Layout and HarfBuzz::Shaper packages. Layout is usable |
49 | 49 | 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. | |
51 | 55 | |
52 | 56 | B. Unification of font support: including character set and encoding support |
53 | 57 | improvements [see CTS 16 and CTS 23] to make more commonality between using |
212 | 216 | during render to the file? Another possibility is to use a negative |
213 | 217 | Y-coordinate to mean "place me at the bottom". Also remember that beyond |
214 | 218 | 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 | |
215 | 237 | |
216 | 238 | ============================================================================= |
217 | 239 | II. Items to add to a separate area (new module or sub-module) |
25 | 25 | perl t\extgstate.t |
26 | 26 | perl t\filter-ascii85decode.t |
27 | 27 | perl t\filter-asciihexdecode.t |
28 | REM perl t\filter-ccittfaxdecode.t # add when TIFF changes go in | |
28 | 29 | perl t\filter-runlengthdecode.t |
29 | 30 | perl t\font-corefont.t |
30 | 31 | perl t\font-synfont.t |
0 | 0 | # This file is manually maintained |
1 | # if add or delete a .pm file, also update META.yml and META.json files | |
1 | 2 | .perlcriticrc |
2 | 3 | Changes |
3 | 4 | CONTRIBUTING |
5 | 6 | MANIFEST |
6 | 7 | META.json |
7 | 8 | META.yml |
8 | optional_update.pl | |
9 | 9 | README.md |
10 | 10 | tools/1_pc.pl |
11 | 11 | tools/2_t-tests.pl |
12 | 12 | tools/3_examples.pl |
13 | 13 | tools/4_contrib.pl |
14 | tools/optional_update.pl | |
14 | 15 | tools/TTFdump.pl |
15 | 16 | INFO/Changes_2017 |
16 | 17 | INFO/Changes_2018 |
17 | 18 | INFO/Changes_2019 |
18 | 19 | INFO/Changes_2020 |
20 | INFO/Changes_2021 | |
19 | 21 | INFO/Changes-ver_2 |
20 | 22 | INFO/CONVERSION |
21 | 23 | INFO/DEPRECATED |
223 | 225 | t/filter-ascii85decode.t |
224 | 226 | t/filter-asciihexdecode.t |
225 | 227 | t/filter-lzwdecode.t |
228 | #t/filter-ccittfaxdecode.t | |
226 | 229 | t/filter-runlengthdecode.t |
227 | 230 | t/font-corefont.t |
228 | 231 | t/font-synfont.t |
49 | 49 | PREREQ_PM => { |
50 | 50 | "Compress::Zlib" => 1.0, |
51 | 51 | "Font::TTF" => 1.04, |
52 | # "Readonly" => 0, use when TIFF changes go in | |
52 | 53 | |
53 | 54 | # === found in CORE, so no need to explicitly list |
54 | 55 | #"Carp" => 0, |
97 | 98 | # recommends (optional prereqs) goes here |
98 | 99 | # if remove or comment out any, also do so in META.json and META.yml |
99 | 100 | "recommends" => { |
100 | "Graphics::TIFF" => 16, | |
101 | "Graphics::TIFF" => 16, # will be 17 when TIFF changes go in | |
101 | 102 | # advanced/fast PNG image processing. |
102 | 103 | "Image::PNG::Libpng" => 0.57, |
103 | 104 | # text shaping for Latin script ligatures and kerning, and for |
24 | 24 | PDF::Builder::Docs, and decide whether or not you want to install any of them. |
25 | 25 | By default, all are installed (as "recommended", so failure to install will |
26 | 26 | 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". | |
28 | 29 | |
29 | 30 | ## Requirements |
30 | 31 | |
76 | 77 | |
77 | 78 | These libraries are _recommended_ for improved functionality and performance. |
78 | 79 | 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 | |
80 | 81 | them, or they fail to install automatically, you can always manually install |
81 | 82 | them later. |
82 | 83 | |
92 | 93 | |
93 | 94 | ## Copyright |
94 | 95 | |
95 | This software is Copyright (c) 2017-2021 by Phil M. Perry. | |
96 | This software is Copyright (c) 2017-2022 by Phil M. Perry. | |
96 | 97 | |
97 | 98 | Previous copyrights are held by others (Steve Simms, Alfred Reibenschuh, et al.). |
98 | 99 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | use PDF::Builder; |
9 | 9 |
3 | 3 | |
4 | 4 | use PDF::Builder::Basic::PDF::File; |
5 | 5 | |
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 | |
8 | 8 | |
9 | 9 | my $file = shift(@ARGV); |
10 | 10 | unless ($file) { |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | use PDF::Builder::Basic::PDF::File; |
9 | 9 | use PDF::Builder::Basic::PDF::Utils; |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | use PDF::Builder::Basic::PDF::File; |
9 | 9 | use PDF::Builder::Basic::PDF::Utils; |
71 | 71 | use strict; |
72 | 72 | use warnings; |
73 | 73 | |
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 | |
76 | 76 | |
77 | 77 | use PDF::Builder; |
78 | 78 | use PDF::Builder::Util; |
15 | 15 | use warnings; |
16 | 16 | use Getopt::Long; |
17 | 17 | |
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 | |
20 | 20 | |
21 | 21 | # ============= |
22 | 22 | # CONFIGURATION these may be overridden by command-line flags. If reading from |
11 | 11 | my $pdf = PDF::Builder->new(-compress => $compress); |
12 | 12 | |
13 | 13 | 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'); | |
15 | 15 | |
16 | 16 | my $page = $pdf->page(); |
17 | $page->mediabox(595,842); | |
17 | $page->mediabox(595,842); # A4 paper | |
18 | 18 | |
19 | 19 | 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 | |
21 | 26 | |
22 | 27 | # 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); | |
24 | 42 | $txt->translate(50,800); |
25 | $txt->text('normal text'); | |
43 | $txt->text('normal text '); | |
26 | 44 | $txt->rise(5); |
27 | 45 | $txt->text('rise = 5 units'); |
28 | 46 | $txt->rise(-5); |
29 | 47 | $txt->text('rise = -5 units'); |
30 | 48 | $txt->rise(0); |
31 | 49 | |
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); | |
32 | 61 | $txt->translate(50,600); |
33 | $txt->text('normal text'); | |
62 | $txt->text('normal text '); | |
34 | 63 | $txt->rise(10); |
35 | 64 | $txt->text('rise = 10 units'); |
36 | 65 | $txt->rise(-10); |
37 | 66 | $txt->text('rise = -10 units'); |
38 | 67 | $txt->rise(0); |
39 | 68 | |
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); | |
40 | 80 | $txt->translate(50,400); |
41 | $txt->text('normal text'); | |
81 | $txt->text('normal text '); | |
42 | 82 | $txt->rise(20); |
43 | 83 | $txt->text('rise = 20 units'); |
44 | 84 | $txt->rise(-20); |
45 | 85 | $txt->text('rise = -20 units'); |
46 | 86 | $txt->rise(0); |
47 | 87 | |
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 | # ---------------------------- | |
48 | 183 | $pdf->saveas("$0.pdf"); |
49 | 184 | $pdf->end(); |
50 | 185 | |
51 | 186 | exit; |
52 | 187 | |
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 | ||
53 | 225 | __END__ |
20 | 20 | my $sx = 33; |
21 | 21 | my $sy = 45; |
22 | 22 | my $fx = 20; |
23 | #my $LoremIpsum = qq|Spin\x{0308}al Tap says: Sed ut perspici\x{0361}atis.|; # times.ttf includes | |
23 | 24 | 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 | |
24 | 26 | # U+0361 is combining double inverted breve (spans i to t) |
25 | 27 | # "use utf8" says to interpret string as UTF-8 |
26 | 28 | my $encoding = 'latin1'; |
13 | 13 | my $compress = 'none'; # uncompressed streams |
14 | 14 | #my $compress = 'flate'; # compressed streams |
15 | 15 | |
16 | my ($ant, $ant2, $ant3, $ant4, $ant5, $ant6); | |
16 | 17 | my $pdf = PDF::Builder->new(-compress => $compress); |
17 | 18 | |
18 | 19 | #my $f1 = $pdf->corefont('Helvetica', -encode=>'latin1'); # unused |
48 | 49 | # initially open note (annotation), can be replied to multiple times by users. |
49 | 50 | # active area is supposed to be 100x100 at 50,150 (LL), but it seems to be a |
50 | 51 | # little larger than the visible icon! BTW, the icon can be dragged and dropped. |
51 | my $ant = $page->annotation(); | |
52 | $ant = $page->annotation(); | |
52 | 53 | $ant->text("This is an initially open note.\nnext line", |
53 | 54 | -color=>[ 0.8 ], # light gray icon fill |
54 | 55 | -icon=>'Key', |
58 | 59 | # active area is supposed to be 100x100 at 200,300 (LL), but it seems to be |
59 | 60 | # little larger than the visible icon! BTW, the icon can be dragged and dropped. |
60 | 61 | # 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', | |
63 | 64 | -color=>[ 0.3 ], # dark gray icon fill |
64 | 65 | -text=>'Closed for the day!', # extra note on rollover |
65 | 66 | -opacity=> 0.75, # a little translucency |
66 | -border=>[10,10, 10], # prominent border | |
67 | # -border=>[10,10, 10], # prominent border N/A | |
67 | 68 | # -icon use default (Note) |
68 | 69 | -rect=>[210,110, 310,210]); |
69 | 70 | |
98 | 99 | $text->paragraph($LoremIpsum, 250,640, 0, -spillover=>1); |
99 | 100 | |
100 | 101 | # 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 | |
102 | 103 | my $note = "This has a highlighter effect."; |
103 | 104 | my @topbot = y_topbot(700, 1, $leading, $fontsize, $descender); |
104 | 105 | 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]); | |
106 | 107 | |
107 | $ant = $page->annotation(); # 7 lines down from upper line | |
108 | $ant4 = $page->annotation(); # 7 lines down from upper line | |
108 | 109 | $note = "This uses a squiggly line."; |
109 | 110 | @topbot = y_topbot(700, 7, $leading, $fontsize, $descender); |
110 | 111 | $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]); | |
112 | 113 | |
113 | $ant = $page->annotation(); # 11 lines down from upper line | |
114 | $ant5 = $page->annotation(); # 11 lines down from upper line | |
114 | 115 | $note = "This uses an underline spanning two lines."; |
115 | 116 | @topbot = y_topbot(700, 11, $leading, $fontsize, $descender); |
116 | 117 | $corners = [277,$topbot[0], 330,$topbot[0], 277,$topbot[1], 330,$topbot[1], |
117 | 118 | 75,$topbot[0]-$leading, 157,$topbot[0]-$leading, |
118 | 119 | 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], | |
120 | 121 | -text=>"Some title text"); |
121 | 122 | |
122 | $ant = $page->annotation(); # 15 lines down from upper line | |
123 | $ant6 = $page->annotation(); # 15 lines down from upper line | |
123 | 124 | $note = "This uses a strikeout spanning three lines."; |
124 | 125 | @topbot = y_topbot(700, 15, $leading, $fontsize, $descender); |
125 | 126 | $corners = [257,$topbot[0], 350,$topbot[0], 257,$topbot[1], 350,$topbot[1], |
127 | 128 | 75,$topbot[1]-$leading, 340,$topbot[1]-$leading, |
128 | 129 | 75,$topbot[0]-2*$leading, 338,$topbot[0]-2*$leading, |
129 | 130 | 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); | |
131 | 132 | |
132 | 133 | # ------------------ |
133 | 134 | $pdf->saveas("$0.pdf"); |
97 | 97 | ); |
98 | 98 | |
99 | 99 | # 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 | |
100 | 102 | my $ant5 = $page->annotation(); |
101 | 103 | $ant5->file_attachment($base."sample.txt", |
102 | 104 | -rect=>[60,410, 160,510], |
4 | 4 | |
5 | 5 | # program settings |
6 | 6 | my $border = 1; # line width of click rectangle, 0 for none |
7 | ||
7 | 8 | my $b_red = 0; # click rectangle border color (here medium green) |
8 | 9 | my $b_green = 0.5; |
9 | 10 | my $b_blue = 0; |
11 | ||
12 | my $normal_text_color = 'black'; | |
13 | my $link_text_color = 'blue'; | |
14 | ||
10 | 15 | my $font_size = 20; # 20pt text |
11 | 16 | my $local_movie = ""; # a local movie file such as .avi |
12 | 17 | |
18 | # =========================================== | |
13 | 19 | my $PDFname = $0; |
14 | 20 | $PDFname =~ s/\..*$//; # remove any existing extension |
15 | 21 | $PDFname .= '.pdf'; # add new extension |
19 | 25 | my $text = $page->text(); |
20 | 26 | my $font = $pdf->corefont('Times-Roman'); |
21 | 27 | $text->font($font, $font_size); |
28 | $text->fillcolor($normal_text_color); | |
22 | 29 | |
23 | 30 | my $x = 100; |
24 | 31 | my $y = 700; |
34 | 41 | $x += $text->advancewidth("Click "); |
35 | 42 | |
36 | 43 | # x,y should be at LL corner of "here" (on baseline) |
37 | $text->fillcolor('blue'); | |
44 | $text->fillcolor($link_text_color); | |
38 | 45 | $text->text("here"); |
39 | 46 | my $target_width = $text->advancewidth("here"); |
40 | 47 | |
47 | 54 | ); |
48 | 55 | |
49 | 56 | # restore color and do rest of line |
50 | $text->fillcolor('black'); | |
57 | $text->fillcolor($normal_text_color); | |
51 | 58 | $text->text(" to go to Google."); |
52 | 59 | |
53 | 60 | # ---------- go to a specific location in a browser |
59 | 66 | $x += $text->advancewidth("Go to "); |
60 | 67 | |
61 | 68 | # x,y should be at LL corner of "here" (on baseline) |
62 | $text->fillcolor('blue'); | |
69 | $text->fillcolor($link_text_color); | |
63 | 70 | $text->text("a specific point"); |
64 | 71 | $target_width = $text->advancewidth("a specific point"); |
65 | 72 | |
72 | 79 | ); |
73 | 80 | |
74 | 81 | # restore color and do rest of line |
75 | $text->fillcolor('black'); | |
82 | $text->fillcolor($normal_text_color); | |
76 | 83 | $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."); | |
77 | 92 | |
78 | 93 | # ---------- go to a page within THIS document |
79 | 94 | $page = $pdf->page(); # page 2 |
93 | 108 | $x += $text->advancewidth("Click "); |
94 | 109 | |
95 | 110 | # x,y should be at LL corner of "here" (on baseline) |
96 | $text->fillcolor('blue'); | |
111 | $text->fillcolor($link_text_color); | |
97 | 112 | $text->text("here"); |
98 | 113 | $target_width = $text->advancewidth("here"); |
99 | 114 | |
107 | 122 | ); |
108 | 123 | |
109 | 124 | # restore color and do rest of line |
110 | $text->fillcolor('black'); | |
125 | $text->fillcolor($normal_text_color); | |
111 | 126 | $text->text(" to go to Page 1."); |
112 | 127 | |
113 | 128 | # same, except position and zoom |
119 | 134 | $x += $text->advancewidth("Click "); |
120 | 135 | |
121 | 136 | # x,y should be at LL corner of "here" (on baseline) |
122 | $text->fillcolor('blue'); | |
137 | $text->fillcolor($link_text_color); | |
123 | 138 | $text->text("here"); |
124 | 139 | $target_width = $text->advancewidth("here"); |
125 | 140 | |
134 | 149 | ); |
135 | 150 | |
136 | 151 | # restore color and do rest of line |
137 | $text->fillcolor('black'); | |
152 | $text->fillcolor($normal_text_color); | |
138 | 153 | $text->text(" to go to Page 1 positioned/zoomed."); |
139 | 154 | |
140 | 155 | |
156 | 171 | $x += $text->advancewidth("Click "); |
157 | 172 | |
158 | 173 | # x,y should be at LL corner of "here" (on baseline) |
159 | $text->fillcolor('blue'); | |
174 | $text->fillcolor($link_text_color); | |
160 | 175 | $text->text("here"); |
161 | 176 | $target_width = $text->advancewidth("here"); |
162 | 177 | |
170 | 185 | ); |
171 | 186 | |
172 | 187 | # restore color and do rest of line |
173 | $text->fillcolor('black'); | |
188 | $text->fillcolor($normal_text_color); | |
174 | 189 | $text->text(" to go to Page 1 of another PDF document."); |
175 | 190 | |
176 | 191 | # same, except position and zoom |
182 | 197 | $x += $text->advancewidth("Click "); |
183 | 198 | |
184 | 199 | # x,y should be at LL corner of "here" (on baseline) |
185 | $text->fillcolor('blue'); | |
200 | $text->fillcolor($link_text_color); | |
186 | 201 | $text->text("here"); |
187 | 202 | $target_width = $text->advancewidth("here"); |
188 | 203 | |
197 | 212 | ); |
198 | 213 | |
199 | 214 | # restore color and do rest of line |
200 | $text->fillcolor('black'); | |
215 | $text->fillcolor($normal_text_color); | |
201 | 216 | $text->text(" to go to Page 1 of another PDF document, windowed."); |
202 | 217 | |
203 | 218 | # ---------- launch (default OS action) another file |
220 | 235 | $x += $text->advancewidth("Click "); |
221 | 236 | |
222 | 237 | # x,y should be at LL corner of "here" (on baseline) |
223 | $text->fillcolor('blue'); | |
238 | $text->fillcolor($link_text_color); | |
224 | 239 | $text->text("here"); |
225 | 240 | $target_width = $text->advancewidth("here"); |
226 | 241 | |
233 | 248 | ); |
234 | 249 | |
235 | 250 | # restore color and do rest of line |
236 | $text->fillcolor('black'); | |
251 | $text->fillcolor($normal_text_color); | |
237 | 252 | $text->text(" to \"launch\" a .txt file."); |
238 | 253 | |
239 | 254 | # ---------------------- |
257 | 272 | ); |
258 | 273 | |
259 | 274 | # restore color |
260 | $text->fillcolor('black'); | |
275 | $text->fillcolor($normal_text_color); | |
261 | 276 | |
262 | 277 | # ---------------------- |
263 | 278 | if ($local_movie ne '' && -r $local_movie) { |
8 | 8 | use warnings; |
9 | 9 | use strict; |
10 | 10 | |
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 | |
13 | 13 | |
14 | 14 | use Math::Trig; |
15 | 15 | use List::Util qw(min max); |
20 | 20 | my $bleedbox_adj = 36/pt; # in from crop box on top and right for printer inst. |
21 | 21 | my $cropbox_adj = 0.25/in; # in from media edge |
22 | 22 | |
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 | |
25 | 25 | |
26 | 26 | my $PDFname = $0; |
27 | 27 | $PDFname =~ s/\..*$//; # remove extension such as .pl |
32 | 32 | use warnings; |
33 | 33 | use strict; |
34 | 34 | |
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 | |
37 | 37 | |
38 | 38 | use Math::Trig; |
39 | 39 | use List::Util qw(min max); |
5 | 5 | use warnings; |
6 | 6 | use strict; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Math::Trig; |
12 | 12 | use List::Util qw(min max); |
5 | 5 | use warnings; |
6 | 6 | use strict; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Math::Trig; |
12 | 12 | use List::Util qw(min max); |
0 | 0 | #!/usr/bin/perl |
1 | 1 | ########################## |
2 | # NOTE: appears to bring in the entire Ming font (Chinese), rather than a | |
3 | # subset. sorry about that! ref RT 130041 | |
4 | 2 | # Note to maintainer: don't forget to refresh HarfBuzz_example.pdf |
5 | 3 | ########################## |
6 | 4 | # demonstrate some usage of HarfBuzz::Shaper and related text calls |
10 | 8 | use strict; |
11 | 9 | use warnings; |
12 | 10 | |
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 | |
15 | 13 | |
16 | 14 | my $PDFname = $0; |
17 | 15 | $PDFname =~ s/\..*$//; # remove extension such as .pl |
51 | 49 | # '/Users/Phil/AppData/Local/Microsoft/Windows/Fonts/NimbusRoman-Regular.otf'; |
52 | 50 | # '/WINDOWS/Fonts/verdana.ttf'; |
53 | 51 | # '/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'; | |
56 | 54 | # You will certainly have to modify the font file locations and names |
57 | 55 | # per your local installation and operating system, here and below in %samples. |
58 | 56 | # Some .ttf fonts may be usable by HarfBuzz for shaping, but others don't seem |
105 | 103 | 'dir' => 'L', |
106 | 104 | 'script' => 'Latn', |
107 | 105 | '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"] }, | |
110 | 108 | 'LatinL3' => { 'title' => "LatinL3", |
111 | 109 | 'fontFile' => $ligFont, |
112 | 110 | 'dir' => 'L', |
119 | 117 | 'dir' => 'L', |
120 | 118 | 'script' => 'Latn', |
121 | 119 | 'specials' => 1, # -liga plus call Builder filter |
122 | # tz TZ ue vy ffi ffl | |
120 | # tz TZ ue vy ffi ffl ij | |
123 | 121 | # 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"] }, | |
125 | 123 | |
126 | 124 | # Demonstrate kerning (closing up overlapping characters) in a Latin script. |
127 | 125 | # You should see AVA and AWAY are closed up, due to letter shapes. This can |
153 | 151 | # and removal, all taken care of by HarfBuzz. |
154 | 152 | 'Devan' => { 'title' => "Devanagari", # see PP_Advanced pg 26 & 27 |
155 | 153 | # 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', | |
157 | 155 | 'dir' => 'L', |
158 | 156 | 'script' => 'Deva', |
159 | 157 | '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}"] }, |
387 | 385 | # some random Chinese characters. most interested in what direction is |
388 | 386 | # the default, and what is settable |
389 | 387 | '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', | |
392 | 390 | 'dir' => 'T', |
393 | 391 | 'script' => 'Chin', |
394 | 392 | # '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}"] }, | |
396 | 397 | |
397 | 398 | # Languages which are normally RTL don't seem to behave with TTB. |
398 | 399 | # I would expect them to be reversed, but they aren't. Maybe the direction |
6 | 6 | use warnings; |
7 | 7 | use strict; |
8 | 8 | |
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 | |
11 | 11 | |
12 | 12 | use PDF::Builder; |
13 | 13 |
6 | 6 | use strict; |
7 | 7 | use warnings; |
8 | 8 | |
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 | |
11 | 11 | |
12 | 12 | use PDF::Builder; |
13 | 13 | use Encode; |
3 | 3 | use warnings; |
4 | 4 | #no warnings qw[ deprecated recursion uninitialized ]; |
5 | 5 | |
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 | |
8 | 8 | |
9 | 9 | use Win32::TieRegistry qw( :KEY_ ); # creates $Registry, et al. |
10 | 10 |
Binary diff not shown
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Basic::PDF::Utils; |
11 | 11 | use List::Util qw(min max); |
37 | 37 | |
38 | 38 | my $self = $class->SUPER::new(); |
39 | 39 | $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 | |
41 | 41 | |
42 | 42 | return $self; |
43 | 43 | } |
172 | 172 | |
173 | 173 | Defines the annotation as a text note with content string C<$text> and |
174 | 174 | 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. | |
176 | 177 | |
177 | 178 | C<-text> is the popup's label string, not to be confused with the main C<$text>. |
178 | 179 | |
219 | 220 | |
220 | 221 | $self->rect(@{$options{'-rect'}}) if defined $options{'-rect'}; |
221 | 222 | $self->open($options{'-open'}) if defined $options{'-open'}; |
223 | #$self->border($options{'-border'}) if defined $options{'-border'}; # ignored | |
222 | 224 | $self->Color(@{$options{'-color'}}) if defined $options{'-color'}; |
223 | 225 | # popup label (title) |
224 | 226 | # have seen /T as (xFEFF UTF-16 chars) |
581 | 583 | Sets the border-style of the annotation, if applicable, as given by the |
582 | 584 | -border option. There are three entries in the array: |
583 | 585 | 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. | |
584 | 588 | |
585 | 589 | 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). | |
590 | 597 | |
591 | 598 | Defining option: |
592 | 599 | |
594 | 601 | |
595 | 602 | =item -border => [CRh, CRv, W] |
596 | 603 | |
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! | |
598 | 608 | |
599 | 609 | Set annotation B<border style> of horizontal and vertical corner radii C<CRh> |
600 | 610 | 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). | |
602 | 614 | Optionally, a dash pattern array may be given (C<on> length, C<off> length, |
603 | 615 | as one or more I<pairs>). The default is a solid line. |
604 | 616 | |
605 | 617 | The border vector seems to ignore the first two settings (corner radii), but |
606 | 618 | 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. | |
608 | 620 | |
609 | 621 | =back |
610 | 622 |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
20 | 20 | use warnings; |
21 | 21 | #no warnings qw[ deprecated recursion uninitialized ]; |
22 | 22 | |
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 | |
25 | 25 | |
26 | 26 | our $mincache = 16 * 1024 * 1024; |
27 | 27 |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use POSIX qw(ceil floor); |
11 | 11 |
5 | 5 | use POSIX; |
6 | 6 | use base 'PDF::Builder::Basic::PDF::Filter::FlateDecode'; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | =head1 NAME |
12 | 12 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
17 | 17 | use strict; |
18 | 18 | use warnings; |
19 | 19 | |
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 | |
22 | 22 | |
23 | 23 | use PDF::Builder::Basic::PDF::Filter::ASCII85Decode; |
24 | 24 | use PDF::Builder::Basic::PDF::Filter::ASCIIHexDecode; |
25 | 25 | use PDF::Builder::Basic::PDF::Filter::FlateDecode; |
26 | 26 | use PDF::Builder::Basic::PDF::Filter::LZWDecode; |
27 | 27 | use PDF::Builder::Basic::PDF::Filter::RunLengthDecode; |
28 | # use PDF::Builder::Basic::PDF::Filter::CCITTFaxDecode; when TIFF changes in | |
28 | 29 | use Scalar::Util qw(blessed reftype); |
29 | 30 | |
30 | 31 | =head1 NAME |
5 | 5 | use strict; |
6 | 6 | use warnings; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Filter; |
12 | 12 | use PDF::Builder::Basic::PDF::Name; |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
18 | 18 | use warnings; |
19 | 19 | use Scalar::Util 'isweak'; |
20 | 20 | |
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 | |
23 | 23 | |
24 | 24 | =head1 NAME |
25 | 25 |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | use PDF::Builder::Basic::PDF::Dict; |
26 | 26 | use PDF::Builder::Basic::PDF::Utils; |
19 | 19 | |
20 | 20 | use base 'PDF::Builder::Basic::PDF::Dict'; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | use PDF::Builder::Basic::PDF::Array; |
26 | 26 | use PDF::Builder::Basic::PDF::Dict; |
19 | 19 | use strict; |
20 | 20 | use warnings; |
21 | 21 | |
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 | |
24 | 24 | |
25 | 25 | =head1 NAME |
26 | 26 |
17 | 17 | use strict; |
18 | 18 | use warnings; |
19 | 19 | |
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 | |
22 | 22 | |
23 | 23 | =head1 NAME |
24 | 24 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw( deprecated recursion uninitialized ); |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Carp; |
12 | 12 | use Compress::Zlib qw(); |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | # originally part of Builder.pm, it was split out due to its length |
9 | 9 | |
509 | 509 | In 2011, PDF::API2 maintenance was taken over by Steve Simms. |
510 | 510 | In 2017, PDF::Builder was forked by Phil M. Perry, who desired a more aggressive |
511 | 511 | 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 | |
512 | 528 | |
513 | 529 | At Simms's request, the name of the new offering was changed from PDF::API4 |
514 | 530 | to PDF::Builder, to reduce the chance of confusion due to parallel development. |
3 | 3 | use warnings; |
4 | 4 | #no warnings qw[ deprecated recursion uninitialized ]; |
5 | 5 | |
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 | |
8 | 8 | # NOTE that this sub-package has not been tested and is not well documented! |
9 | 9 | # It is possible that it will be deprecated and removed. |
10 | 10 |
12 | 12 | use warnings; |
13 | 13 | use Carp; |
14 | 14 | |
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 | |
17 | 17 | |
18 | 18 | =head1 NAME |
19 | 19 |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | # TBD: do -rect and -border apply to Named Destinations (link, url, file)? |
12 | 12 | # There is nothing to implement these options. Perhaps the code was copied |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use Carp qw(croak); |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Basic::PDF::Utils; |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use POSIX qw(floor); |
11 | 11 | use Scalar::Util qw(weaken); |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use Compress::Zlib; |
11 | 11 | use Encode qw(:all); |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Util; |
12 | 12 | use PDF::Builder::Basic::PDF::Utils; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Carp; |
12 | 12 | use Encode qw(:all); |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Resource::CIDFont::TrueType::FontFile; |
3 | 3 | |
4 | 4 | use strict; |
5 | 5 | 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 | |
10 | 9 | |
11 | 10 | use Encode qw(:all); |
12 | 11 | |
30 | 29 | sub new { |
31 | 30 | my ($class, $pdf, $name, @opts) = @_; |
32 | 31 | |
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); | |
37 | 33 | my $self = $class->SUPER::new($pdf, $name); |
38 | 34 | $pdf->new_obj($self) if defined($pdf) && !$self->is_obj($pdf); |
39 | 35 | |
40 | $self->{'Type'} = PDFName('Font'); | |
41 | $self->{'Subtype'} = PDFName('Type0'); | |
36 | $self->{'Type'} = PDFName('Font'); | |
37 | $self->{'Subtype'} = PDFName('Type0'); | |
42 | 38 | $self->{'Encoding'} = PDFName('Identity-H'); |
43 | 39 | |
44 | 40 | my $de = PDFDict(); |
80 | 76 | } |
81 | 77 | |
82 | 78 | sub wxByCId { |
83 | my $self = shift; | |
84 | my $g = shift; | |
79 | my ($self, $g) = @_; | |
85 | 80 | |
86 | 81 | my $w; |
87 | 82 | |
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}); | |
94 | 89 | } else { |
95 | 90 | $w = $self->missingwidth(); |
96 | 91 | } |
150 | 145 | defined $self->data()->{'decode'} && |
151 | 146 | $self->data()->{'decode'} ne 'ident') { |
152 | 147 | $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') { | |
154 | 151 | $text = $self->cidsByUtf($text); |
155 | 152 | } elsif (!utf8::is_utf8($text) && |
156 | 153 | defined $self->data()->{'encode'} && |
154 | defined $self->data()->{'decode'} && | |
157 | 155 | $self->data()->{'decode'} eq 'ident') { |
158 | 156 | $text = $self->cidsByUtf(decode($self->data()->{'encode'}, $text)); |
159 | 157 | } elsif (!utf8::is_utf8($text) && |
160 | 158 | $self->can('issymbol') && |
161 | 159 | $self->issymbol() && |
160 | defined $self->data()->{'decode'} && | |
162 | 161 | $self->data()->{'decode'} eq 'ident') { |
163 | 162 | $text = pack('U*', (map { $_+0xf000 } unpack('C*', $text))); |
164 | 163 | $text = $self->cidsByUtf($text); |
177 | 176 | sub cidsByUtf { |
178 | 177 | my ($self, $s) = @_; |
179 | 178 | |
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 | ||
181 | 186 | utf8::downgrade($s); |
182 | 187 | return $s; |
183 | 188 | } |
236 | 241 | $self->fontfile()->subsetByCId($g); |
237 | 242 | } |
238 | 243 | } |
239 | if (defined $size && $self->{'-dokern'} && $self->haveKernPairs()) { | |
244 | if (defined $size && $self->{'-dokern'} && $self->haveKernPairs()) { | |
240 | 245 | my $newtext = ' '; |
241 | 246 | my $lastglyph = 0; |
242 | 247 | my $tBefore = 0; |
248 | 253 | } |
249 | 254 | $lastglyph = $n; |
250 | 255 | my $t = sprintf('%04X', $n); |
251 | $newtext .= '<' if !$tBefore; | |
256 | $newtext .= '<' unless $tBefore; | |
252 | 257 | $newtext .= $t; |
253 | 258 | $tBefore = 1; |
254 | 259 | } |
276 | 281 | } |
277 | 282 | |
278 | 283 | sub haveKernPairs { |
279 | return 0; | |
284 | return 0; # PDF::API2 changed to just 'return;' | |
280 | 285 | } |
281 | 286 | |
282 | 287 | sub encodeByName { |
284 | 289 | |
285 | 290 | return if $self->issymbol(); |
286 | 291 | |
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 | ]; | |
290 | 306 | |
291 | 307 | $self->data()->{'u2e'} = {}; |
292 | 308 | 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; | |
295 | 310 | } |
296 | 311 | |
297 | 312 | return $self; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | =head1 NAME |
12 | 12 |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
12 | 12 | use PDF::Builder::Util; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use PDF::Builder::Util; |
12 | 12 | use PDF::Builder::Basic::PDF::Utils; |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use File::Basename; |
12 | 12 |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Encode qw(:all); |
12 | 12 | use IO::File qw(); |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Math::Trig; # CAUTION: deg2rad(0) = deg2rad(360) = 0! |
12 | 12 | use Unicode::UCD 'charinfo'; |
5 | 5 | use warnings; |
6 | 6 | #no warnings qw[ deprecated recursion uninitialized ]; |
7 | 7 | |
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 | |
10 | 10 | |
11 | 11 | use Encode qw(:all); |
12 | 12 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | =head1 NAME |
9 | 9 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | use Carp; |
9 | 9 | use Encode qw(:all); |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | =head1 NAME |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Util; |
11 | 11 | 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 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Basic::PDF::Dict; |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Basic::PDF::Utils; |
11 | 11 |
3 | 3 | |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | #no warnings qw[ deprecated recursion uninitialized ]; | |
7 | 6 | |
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 | |
10 | 9 | |
11 | 10 | use PDF::Builder::Util; |
12 | 11 | use PDF::Builder::Basic::PDF::Utils; |
16 | 15 | |
17 | 16 | PDF::Builder::Resource::XObject::Image::GD - support routines for Graphics Development image library. Inherits from L<PDF::Builder::Resource::XObject::Image> |
18 | 17 | |
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 | ||
19 | 42 | =cut |
20 | 43 | |
21 | 44 | 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'}; } | |
23 | 50 | |
24 | 51 | my $self; |
25 | 52 | |
26 | $class = ref $class if ref $class; | |
53 | $class = ref($class) if ref($class); | |
27 | 54 | |
28 | $self = $class->SUPER::new($pdf, $name || 'Jx'.pdfkey()); | |
55 | $self = $class->SUPER::new($pdf, $name || 'Dx'.pdfkey()); | |
29 | 56 | $pdf->new_obj($self) unless $self->is_obj($pdf); |
30 | 57 | |
31 | 58 | $self->{' apipdf'} = $pdf; |
32 | 59 | weaken $self->{' apipdf'}; |
33 | 60 | |
34 | $self->read_gd($obj, @opts); | |
61 | $self->read_gd($obj, %opts); | |
35 | 62 | |
36 | 63 | return $self; |
37 | 64 | } |
3 | 3 | |
4 | 4 | use strict; |
5 | 5 | 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 | |
10 | 9 | |
11 | 10 | use IO::File; |
12 | 11 | use PDF::Builder::Util; |
17 | 16 | |
18 | 17 | PDF::Builder::Resource::XObject::Image::GIF - support routines for GIF image library. Inherits from L<PDF::Builder::Resource::XObject::Image> |
19 | 18 | |
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 | ||
20 | 29 | =head1 Supported Formats |
21 | 30 | |
22 | 31 | GIF87a and GIF89a headers are supported. The Image block (x2C) is supported. |
32 | 41 | than 256 colors to be used overall in the image (despite the 8 bit color table |
33 | 42 | depth). |
34 | 43 | |
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 | ||
38 | 44 | =head2 Options |
39 | 45 | |
40 | 46 | =over |
43 | 49 | |
44 | 50 | When defined and not 0, C<-notrans> suppresses the use of transparency if such |
45 | 51 | 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. | |
46 | 56 | |
47 | 57 | =item -multi |
48 | 58 | |
54 | 64 | |
55 | 65 | =cut |
56 | 66 | |
57 | # added from PDF::Create: | |
58 | # PDF::Image::GIFImage - GIF image support | |
59 | # Author: Michael Gross <mdgrosse@sbox.tugraz.at> | |
60 | 67 | # modified for internal use. (c) 2004 fredo. |
61 | 68 | sub unInterlace { |
62 | 69 | my $self = shift; |
68 | 75 | my $height = $self->height(); |
69 | 76 | my $idx = 0; |
70 | 77 | |
71 | #Pass 1 - every 8th row, starting with row 0 | |
78 | # Pass 1 - every 8th row, starting with row 0 | |
72 | 79 | $row = 0; |
73 | 80 | while ($row < $height) { |
74 | 81 | $result[$row] = substr($data, $idx*$width, $width); |
76 | 83 | $idx++; |
77 | 84 | } |
78 | 85 | |
79 | #Pass 2 - every 8th row, starting with row 4 | |
86 | # Pass 2 - every 8th row, starting with row 4 | |
80 | 87 | $row = 4; |
81 | 88 | while ($row < $height) { |
82 | 89 | $result[$row] = substr($data, $idx*$width, $width); |
84 | 91 | $idx++; |
85 | 92 | } |
86 | 93 | |
87 | #Pass 3 - every 4th row, starting with row 2 | |
94 | # Pass 3 - every 4th row, starting with row 2 | |
88 | 95 | $row = 2; |
89 | 96 | while ($row < $height) { |
90 | 97 | $result[$row] = substr($data, $idx*$width, $width); |
92 | 99 | $idx++; |
93 | 100 | } |
94 | 101 | |
95 | #Pass 4 - every 2nd row, starting with row 1 | |
102 | # Pass 4 - every 2nd row, starting with row 1 | |
96 | 103 | $row = 1; |
97 | 104 | while ($row < $height) { |
98 | 105 | $result[$row] = substr($data, $idx*$width, $width); |
131 | 138 | # $tag |= vec($stream, $ptr+$off, 1); |
132 | 139 | # } |
133 | 140 | # 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); | |
135 | 142 | $ptr += $bits; |
136 | 143 | $bits++ if $nextcode == 1 << $bits and $bits < 12; |
137 | 144 | if ($tag == $resetcode) { |
155 | 162 | } |
156 | 163 | |
157 | 164 | 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'}; } | |
159 | 170 | |
160 | 171 | my $self; |
161 | 172 | |
162 | my $inter = 0; | |
163 | ||
164 | $class = ref $class if ref $class; | |
173 | my $interlaced = 0; | |
174 | ||
175 | $class = ref($class) if ref($class); | |
165 | 176 | |
166 | 177 | $self = $class->SUPER::new($pdf, $name || 'Gx'.pdfkey()); |
167 | 178 | $pdf->new_obj($self) unless $self->is_obj($pdf); |
183 | 194 | # GIF Header |
184 | 195 | # 6 bytes "GIF87a" or "GIF89a" |
185 | 196 | $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 | } | |
187 | 202 | |
188 | 203 | # 4 bytes logical screen width and height (2 x 16 bit LSB first) |
189 | 204 | # 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 | |
191 | 206 | my($wg, $hg, $flags, $bgColorIndex, $aspect) = unpack('vvCCC', $buf); |
192 | 207 | |
193 | 208 | # flags numbered left to right 0-7: |
199 | 214 | my $colSize = 2**(($flags & 0x7)+1); # 2 - 256 entries |
200 | 215 | my $dict = PDFDict(); |
201 | 216 | $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)); | |
203 | 221 | $fh->read($dict->{' stream'}, 3*$colSize); # Global Color Table |
204 | 222 | } |
205 | 223 | |
210 | 228 | |
211 | 229 | if ($sep == 0x2C) { |
212 | 230 | # x2C = image block (separator, equals ASCII comma ',') |
213 | $fh->read($buf, 9); # image-descr. | |
231 | $fh->read($buf, 9); # image descriptor | |
214 | 232 | # image left (16 bits), image top (16 bits LSB first) |
215 | 233 | # image width (16 bits), image height (16 bits LSB first) |
216 | 234 | # flags (1 byte): |
229 | 247 | my $colSize = 2**(($flags & 0x7)+1); |
230 | 248 | my $dict = PDFDict(); |
231 | 249 | $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)); | |
233 | 254 | $fh->read($dict->{' stream'}, 3*$colSize); # Local Color Table |
234 | 255 | } |
235 | 256 | if ($flags & 0x40) { # need de-interlace |
236 | $inter = 1; # default to 0 earlier | |
257 | $interlaced = 1; # default to 0 earlier | |
237 | 258 | } |
238 | 259 | |
239 | 260 | # LZW Minimum Code Size |
252 | 273 | $len = unpack('C', $buf); |
253 | 274 | } |
254 | 275 | $self->{' stream'} = deGIF($sep+1, $stream); |
255 | $self->unInterlace() if $inter; | |
276 | $self->unInterlace() if $interlaced; | |
256 | 277 | # old (and current default) behavior is to quit processing at the |
257 | 278 | # end of the first Image Block. This means that any other blocks, |
258 | 279 | # including the Trailer, will not be processed. |
280 | 301 | } |
281 | 302 | my ($cFlags, $delay, $transIndex) = unpack('CvC', $stream); |
282 | 303 | if (($cFlags & 0x01) && !$opts{'-notrans'}) { |
283 | $self->{'Mask'} = PDFArray(PDFNum($transIndex), PDFNum($transIndex)); | |
304 | $self->{'Mask'} = PDFArray(PDFNum($transIndex), | |
305 | PDFNum($transIndex)); | |
284 | 306 | } |
285 | 307 | |
286 | 308 | } elsif ($tag == 0xFE) { |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use IO::File; |
11 | 11 | use PDF::Builder::Util; |
16 | 16 | |
17 | 17 | PDF::Builder::Resource::XObject::Image::JPEG - support routines for JPEG image library. Inherits from L<PDF::Builder::Resource::XObject::Image> |
18 | 18 | |
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 | ||
19 | 39 | =cut |
20 | 40 | |
21 | 41 | 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'}; } | |
23 | 47 | |
24 | 48 | my $fh = IO::File->new(); |
25 | 49 | |
26 | $class = ref($class) if ref $class; | |
50 | $class = ref($class) if ref($class); | |
27 | 51 | |
28 | 52 | my $self = $class->SUPER::new($pdf, $name || 'Jx' . pdfkey()); |
29 | 53 | $pdf->new_obj($self) unless $self->is_obj($pdf); |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use Compress::Zlib; |
11 | 11 | use POSIX qw(ceil floor); |
25 | 25 | |
26 | 26 | =over |
27 | 27 | |
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) | |
31 | 29 | |
32 | 30 | =item $res = PDF::Builder::Resource::XObject::Image::PNG->new($pdf, $file) |
33 | 31 | |
41 | 39 | used instead of the PNG library. In such a case, use of the PNG library may be |
42 | 40 | forced via the C<-nouseIPL> flag (see Builder documentation for C<image_png()>). |
43 | 41 | |
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 | |
48 | 56 | |
49 | 57 | =head2 Supported PNG types |
50 | 58 | |
99 | 107 | # TBD: gAMA (gamma) chunk, perhaps some others? |
100 | 108 | |
101 | 109 | 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'}; } | |
103 | 115 | |
104 | 116 | my $self; |
105 | 117 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use Compress::Zlib; |
11 | 11 | use POSIX qw(ceil floor); |
27 | 27 | |
28 | 28 | =over |
29 | 29 | |
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) | |
33 | 31 | |
34 | 32 | =item $res = PDF::Builder::Resource::XObject::Image::PNG_IPL->new($pdf, $file) |
35 | 33 | |
56 | 54 | |
57 | 55 | If the PNG source is 16bps, tell the libpng library to strip down all |
58 | 56 | 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. | |
59 | 61 | |
60 | 62 | =back |
61 | 63 | |
112 | 114 | # TBD: gAMA (gamma) chunk, perhaps some others? |
113 | 115 | |
114 | 116 | 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'}; } | |
116 | 122 | |
117 | 123 | my $self; |
118 | 124 |
5 | 5 | |
6 | 6 | use strict; |
7 | 7 | 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 | |
12 | 11 | |
13 | 12 | use IO::File; |
14 | 13 | use PDF::Builder::Util; |
15 | 14 | use PDF::Builder::Basic::PDF::Utils; |
16 | 15 | use Scalar::Util qw(weaken); |
17 | 16 | |
17 | # massively rewritten recently, so assuming nothing in PDF::API2 rewrite (2021) | |
18 | # should make any functional difference | |
19 | ||
18 | 20 | =head1 NAME |
19 | 21 | |
20 | 22 | PDF::Builder::Resource::XObject::Image::PNM - support routines for PNM (Portable aNy Map) image library. Inherits from L<PDF::Builder::Resource::XObject::Image> |
23 | 25 | |
24 | 26 | =over |
25 | 27 | |
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 | |
27 | 49 | |
28 | 50 | Returns an image in the PDF. PNM types 1 (ASCII/plain bi-level/PBM), |
29 | 51 | 2 (ASCII/plain grayscale/PGM), 3 (ASCII/plain RGB/PPM), |
38 | 60 | with 0 being full black. If the maximum sample value is 255 or smaller, three |
39 | 61 | bytes of raw binary data per pixel, otherwise six bytes. |
40 | 62 | |
41 | =back | |
42 | ||
43 | 63 | =cut |
44 | 64 | |
45 | 65 | # ------------------------------------------------------------------- |
46 | 66 | 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'}; } | |
48 | 72 | |
49 | 73 | my $self; |
50 | 74 | |
51 | $class = ref $class if ref $class; | |
75 | $class = ref($class) if ref($class); | |
52 | 76 | |
53 | 77 | $self = $class->SUPER::new($pdf, $name || 'Nx'.pdfkey()); |
54 | 78 | $pdf->new_obj($self) unless $self->is_obj($pdf); |
57 | 81 | weaken $self->{' apipdf'}; |
58 | 82 | |
59 | 83 | $self->read_pnm($pdf, $file); |
84 | ||
85 | if (defined $compress) { | |
86 | $self->filters('FlateDecode'); | |
87 | } else { | |
88 | $self->filters('ASCIIHexDecode'); | |
89 | } | |
60 | 90 | |
61 | 91 | return $self; |
62 | 92 | } |
68 | 98 | # extensively modified by Phil M Perry, copyright 2020 |
69 | 99 | # |
70 | 100 | sub readppmheader { |
101 | # renamed to _read_header() in PDF::API2 | |
71 | 102 | my ($gr, $buffer) = @_; # already-opened input file's filehandle |
72 | 103 | my %info; |
73 | 104 | $info{'error'} = undef; |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | use IO::File; |
9 | 9 |
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
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 | |
7 | 7 | |
8 | 8 | use IO::File; |
9 | 9 | use Graphics::TIFF ':all'; # already confirmed to be installed |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use Compress::Zlib; |
11 | 11 | |
22 | 22 | |
23 | 23 | =over |
24 | 24 | |
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) | |
26 | 26 | |
27 | 27 | =item $res = PDF::Builder::Resource::XObject::Image::TIFF->new($pdf, $file) |
28 | 28 | |
32 | 32 | instead of the TIFF library. In such a case, use of the TIFF library may be |
33 | 33 | forced via the C<-nouseGT> flag (see Builder documentation for C<image_tiff()>). |
34 | 34 | |
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 | ||
35 | 45 | =cut |
36 | 46 | |
37 | 47 | 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'}; } | |
39 | 53 | |
40 | 54 | my $self; |
41 | 55 | |
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); | |
43 | 57 | |
44 | 58 | # dump everything in tif except huge data streams |
45 | 59 | # foreach (sort keys %{ $tif }) { |
57 | 71 | # in case of problematic things |
58 | 72 | # proxy to other modules |
59 | 73 | |
60 | $class = ref($class) if ref $class; | |
74 | $class = ref($class) if ref($class); | |
61 | 75 | |
62 | 76 | $self = $class->SUPER::new($pdf, $name || 'Ix'.pdfkey()); |
63 | 77 | $pdf->new_obj($self) unless $self->is_obj($pdf); |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use Compress::Zlib; |
11 | 11 | |
24 | 24 | |
25 | 25 | =over |
26 | 26 | |
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) | |
30 | 28 | |
31 | 29 | =item $res = PDF::Builder::Resource::XObject::Image::TIFF_GT->new($pdf, $file) |
32 | 30 | |
45 | 43 | =item -notrans => 1 |
46 | 44 | |
47 | 45 | 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. | |
48 | 50 | |
49 | 51 | =back |
50 | 52 | |
71 | 73 | =cut |
72 | 74 | |
73 | 75 | 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'}; } | |
75 | 81 | |
76 | 82 | my $self; |
77 | 83 | |
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); | |
79 | 85 | |
80 | 86 | # in case of problematic things |
81 | 87 | # proxy to other modules |
82 | 88 | |
83 | $class = ref($class) if ref $class; | |
89 | $class = ref($class) if ref($class); | |
84 | 90 | |
85 | 91 | $self = $class->SUPER::new($pdf, $name || 'Ix'.pdfkey()); |
86 | 92 | $pdf->new_obj($self) unless $self->is_obj($pdf); |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Basic::PDF::Utils; |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Basic::PDF::Utils; |
11 | 11 |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | 6 | |
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 | |
9 | 9 | |
10 | 10 | use PDF::Builder::Util qw(pdfkey); |
11 | 11 | use PDF::Builder::Basic::PDF::Utils; # PDFName |
3 | 3 | use warnings; |
4 | 4 | #no warnings qw[ deprecated recursion uninitialized ]; |
5 | 5 | |
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 | |
8 | 8 | |
9 | 9 | =head1 NAME |
10 | 10 |
3 | 3 | use warnings; |
4 | 4 | #no warnings qw[ recursion uninitialized ]; |
5 | 5 | |
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 | |
8 | 8 | |
9 | 9 | # note: $a and $b are "Magic variables" according to perlcritic, and so it |
10 | 10 | # has conniptions over using them as variable names (even with "my"). so, I |
4 | 4 | |
5 | 5 | # $VERSION defined here so developers can run PDF::Builder from git. |
6 | 6 | # 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 | |
11 | 12 | my $LpngVersion = 0.57; # minimum version of Image::PNG::Libpng |
12 | 13 | |
13 | 14 | use Carp; |
162 | 163 | |
163 | 164 | The release distribution is on CPAN: https://metacpan.org/pod/PDF::Builder. |
164 | 165 | |
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. | |
168 | 174 | |
169 | 175 | =head1 LICENSE |
170 | 176 | |
171 | This software is Copyright (c) 2017-2021 by Phil M. Perry. | |
177 | This software is Copyright (c) 2017-2022 by Phil M. Perry. | |
172 | 178 | |
173 | 179 | This is free software, licensed under: |
174 | 180 | |
278 | 284 | $self->{'pages'} = PDF::Builder::Basic::PDF::Pages->new($self->{'pdf'}); |
279 | 285 | $self->{'pages'}->proc_set(qw(PDF Text ImageB ImageC ImageI)); |
280 | 286 | $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'}); | |
282 | 289 | $self->{'catalog'} = $self->{'pdf'}->{'Root'}; |
283 | 290 | weaken $self->{'catalog'}; |
284 | 291 | $self->{'fonts'} = {}; |
330 | 337 | |
331 | 338 | my $version = eval { $PDF::Builder::VERSION } || '(Unreleased Version)'; |
332 | 339 | #$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]"); | |
334 | 342 | |
335 | 343 | return $self; |
336 | 344 | } # end of new() |
406 | 414 | # ' version' should be the same as $outVer |
407 | 415 | if ($PDFver > $outVer) { |
408 | 416 | 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"; | |
410 | 419 | } |
411 | 420 | $outVer = $myself->{' version'} = $PDFver; |
412 | 421 | return 1; |
506 | 515 | } |
507 | 516 | if ($newVer > $currentVer) { |
508 | 517 | 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"; | |
510 | 521 | } else { |
511 | 522 | if (length($newVer) < length($currentVer)) { |
512 | 523 | # unlikely, but cover all the bases |
666 | 677 | $self->{'catalog'}->{'OpenAction'} = PDFArray($page, PDFName('FitBV'), PDFNum($args{'-fitbv'})); |
667 | 678 | } elsif (defined $args{'-fitr'}) { |
668 | 679 | 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'}}); | |
670 | 682 | } elsif (defined $args{'-xyz'}) { |
671 | 683 | 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'}}); | |
673 | 686 | } |
674 | 687 | } |
675 | 688 | $self->{'pdf'}->out_obj($self->{'catalog'}); |
851 | 864 | $self->{'pdf'}->new_obj($self->{'catalog'}->{'Metadata'}); |
852 | 865 | } else { |
853 | 866 | $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'}); | |
855 | 870 | delete $self->{'catalog'}->{'Metadata'}->{' nofilt'}; |
856 | 871 | delete $self->{'catalog'}->{'Metadata'}->{'Filter'}; |
857 | 872 | } |
871 | 886 | |
872 | 887 | =item $pdf->pageLabel($index, $options) |
873 | 888 | |
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. | |
875 | 897 | |
876 | 898 | B<Supported Options:> |
877 | 899 | |
879 | 901 | |
880 | 902 | =item -style |
881 | 903 | |
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). | |
883 | 908 | |
884 | 909 | =item -start |
885 | 910 | |
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>. | |
887 | 920 | |
888 | 921 | =item -prefix |
889 | 922 | |
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). | |
891 | 932 | |
892 | 933 | =back |
893 | 934 | |
894 | 935 | B<Example:> |
895 | 936 | |
896 | # Start with Roman Numerals | |
937 | # Start with lowercase Roman Numerals at the 1st page, starting with i (1) | |
897 | 938 | $pdf->pageLabel(0, { |
898 | 939 | -style => 'roman', |
899 | 940 | }); |
900 | 941 | |
901 | # Switch to Arabic | |
942 | # Switch to Arabic (decimal) at the 5th page, starting with 1 | |
902 | 943 | $pdf->pageLabel(4, { |
903 | 944 | -style => 'decimal', |
904 | 945 | }); |
905 | 946 | |
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,... | |
907 | 962 | $pdf->pageLabel(32, { |
908 | -start => 1, | |
963 | -start => 1, # unnecessary | |
909 | 964 | -prefix => 'A-' |
910 | 965 | }); |
911 | 966 | |
912 | # Numbering for Appendix B | |
967 | # Numbering for Appendix B at the 37th page, B-1, B-2,... | |
913 | 968 | $pdf->pageLabel( 36, { |
914 | -start => 1, | |
915 | 969 | -prefix => 'B-' |
916 | 970 | }); |
917 | 971 | |
918 | # Numbering for the Index | |
972 | # Numbering for the Index at the 41st page, Index I, Index II,... | |
919 | 973 | $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', | |
922 | 982 | -prefix => 'Index ' |
923 | 983 | }); |
924 | 984 | |
939 | 999 | |
940 | 1000 | my $d = PDFDict(); |
941 | 1001 | 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 | } | |
946 | 1011 | } else { |
1012 | # default to decimal counter if no -style given | |
947 | 1013 | $d->{'S'} = PDFName('D'); |
948 | 1014 | } |
949 | 1015 | |
950 | 1016 | if (defined $opts->{'-prefix'}) { |
1017 | # 'Content' supposedly treated differently | |
951 | 1018 | $d->{'P'} = PDFString($opts->{'-prefix'}, 's'); |
952 | 1019 | } |
953 | 1020 | |
1467 | 1534 | # This should never get past MediaBox, since it's a required object. |
1468 | 1535 | foreach my $k (qw(MediaBox ArtBox TrimBox BleedBox CropBox)) { |
1469 | 1536 | #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}); | |
1471 | 1539 | 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)); | |
1473 | 1542 | $xo->bbox(map { $_->val() } $box->elements()); |
1474 | 1543 | last; |
1475 | 1544 | } |
1485 | 1554 | $s_page->{$k}->{$sk}->realise() if ref($s_page->{$k}->{$sk}) =~ /Objind$/; |
1486 | 1555 | foreach my $ssk (keys %{$s_page->{$k}->{$sk}}) { |
1487 | 1556 | 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})); | |
1489 | 1559 | } |
1490 | 1560 | } |
1491 | 1561 | } |
1615 | 1685 | if (my $a = $s_pdf->{'pdf'}->{'Root'}->realise()->{'AcroForm'}) { |
1616 | 1686 | $a->realise(); |
1617 | 1687 | |
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)); | |
1619 | 1690 | } |
1620 | 1691 | my @Fields = (); |
1621 | 1692 | my @Annots = (); |
2151 | 2222 | |
2152 | 2223 | =over |
2153 | 2224 | |
2225 | =item $jpeg = $pdf->image_jpeg($file, %options) | |
2226 | ||
2154 | 2227 | =item $jpeg = $pdf->image_jpeg($file) |
2155 | 2228 | |
2156 | 2229 | Imports and returns a new JPEG image object. C<$file> may be either a filename |
2161 | 2234 | |
2162 | 2235 | =cut |
2163 | 2236 | |
2164 | # =item $jpeg = $pdf->image_jpeg($file, %options) no current options | |
2165 | ||
2166 | 2237 | sub image_jpeg { |
2167 | 2238 | my ($self, $file, %opts) = @_; |
2168 | 2239 | |
2169 | 2240 | 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); | |
2171 | 2242 | |
2172 | 2243 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2173 | 2244 | |
2174 | 2245 | return $obj; |
2175 | 2246 | } |
2176 | 2247 | |
2177 | =item $tiff = $pdf->image_tiff($file, %opts) | |
2248 | =item $tiff = $pdf->image_tiff($file, %options) | |
2178 | 2249 | |
2179 | 2250 | =item $tiff = $pdf->image_tiff($file) |
2180 | 2251 | |
2186 | 2257 | L<PDF::Builder::Resource::XObject::Image::TIFF_GT> for additional information |
2187 | 2258 | and C<examples/Content.pl> |
2188 | 2259 | 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. | |
2191 | 2264 | |
2192 | 2265 | =cut |
2193 | 2266 | |
2205 | 2278 | if ($rc == 1) { |
2206 | 2279 | # Graphics::TIFF (_GT suffix) available and to be used |
2207 | 2280 | 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); | |
2209 | 2282 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2210 | 2283 | } else { |
2211 | 2284 | # Graphics::TIFF not available, or is but is not to be used |
2212 | 2285 | 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); | |
2214 | 2287 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2215 | 2288 | |
2216 | 2289 | if ($rc == 0 && $MSG_COUNT[0]++ == 0) { |
2217 | 2290 | # give warning message once, unless silenced (-silent) or |
2218 | 2291 | # deliberately not using Graphics::TIFF (rc == -1) |
2219 | 2292 | 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"; | |
2221 | 2295 | # even if -silent only once, COUNT still incremented |
2222 | 2296 | } |
2223 | 2297 | } |
2263 | 2337 | return $rc; |
2264 | 2338 | } |
2265 | 2339 | |
2340 | =item $pnm = $pdf->image_pnm($file, %options) | |
2341 | ||
2266 | 2342 | =item $pnm = $pdf->image_pnm($file) |
2267 | 2343 | |
2268 | 2344 | Imports and returns a new PNM image object. C<$file> may be either a filename |
2269 | 2345 | or a filehandle. |
2270 | 2346 | |
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 | |
2278 | 2352 | |
2279 | 2353 | sub image_pnm { |
2280 | 2354 | my ($self, $file, %opts) = @_; |
2281 | 2355 | |
2356 | $opts{'-compress'} //= $self->{'forcecompress'}; | |
2357 | ||
2282 | 2358 | 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 | ||
2284 | 2361 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2285 | 2362 | |
2286 | 2363 | return $obj; |
2298 | 2375 | L<PDF::Builder::Resource::XObject::Image::PNG_IPL> for additional information |
2299 | 2376 | and C<examples/Content.pl> |
2300 | 2377 | 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. | |
2303 | 2383 | |
2304 | 2384 | =cut |
2305 | 2385 | |
2317 | 2397 | if ($rc == 1) { |
2318 | 2398 | # Image::PNG::Libpng (_IPL suffix) available and to be used |
2319 | 2399 | 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); | |
2321 | 2401 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2322 | 2402 | } else { |
2323 | 2403 | # Image::PNG::Libpng not available, or is but is not to be used |
2324 | 2404 | 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); | |
2326 | 2406 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2327 | 2407 | |
2328 | 2408 | if ($rc == 0 && $MSG_COUNT[1]++ == 0) { |
2329 | 2409 | # give warning message once, unless silenced (-silent) or |
2330 | 2410 | # deliberately not using Image::PNG::Libpng (rc == -1) |
2331 | 2411 | 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"; | |
2333 | 2414 | # even if -silent only once, COUNT still incremented |
2334 | 2415 | } |
2335 | 2416 | } |
2374 | 2455 | return $rc; |
2375 | 2456 | } |
2376 | 2457 | |
2458 | =item $gif = $pdf->image_gif($file, %options) | |
2459 | ||
2377 | 2460 | =item $gif = $pdf->image_gif($file) |
2378 | 2461 | |
2379 | 2462 | Imports and returns a new GIF image object. C<$file> may be either a filename |
2385 | 2468 | |
2386 | 2469 | =cut |
2387 | 2470 | |
2388 | # =item $gif = $pdf->image_gif($file, %options) no current options | |
2389 | ||
2390 | 2471 | sub image_gif { |
2391 | 2472 | my ($self, $file, %opts) = @_; |
2392 | 2473 | |
2403 | 2484 | |
2404 | 2485 | Imports and returns a new image object from Image::GD. |
2405 | 2486 | |
2406 | Valid %options are: | |
2407 | ||
2408 | =over | |
2409 | ||
2410 | =item -lossless => 1 | |
2411 | ||
2412 | Use lossless compression. | |
2413 | ||
2414 | =back | |
2415 | ||
2416 | 2487 | See L<PDF::Builder::Resource::XObject::Image::GD> for additional information |
2417 | 2488 | and C<examples/Content.pl> for some examples of placing an image on a page |
2418 | 2489 | (JPEG, but the principle is the same). |
2423 | 2494 | my ($self, $gd, %options) = @_; |
2424 | 2495 | |
2425 | 2496 | 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); | |
2427 | 2498 | $self->{'pdf'}->out_obj($self->{'pages'}); |
2428 | 2499 | |
2429 | 2500 | return $obj; |
2866 | 2937 | # first /Parent (should not be more) |
2867 | 2938 | $objList{$objKey}->[$idx_parent] = $Parent; |
2868 | 2939 | #} 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; | |
2870 | 2942 | #} |
2871 | 2943 | } |
2872 | 2944 | |
2895 | 2967 | @{$objList{$objKey}->[$idx_kid_list]} = @Kids; |
2896 | 2968 | $objList{$objKey}->[$idx_kid_cnt] = scalar(@Kids); |
2897 | 2969 | #} 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; | |
2899 | 2972 | #} |
2900 | 2973 | } |
2901 | 2974 | |
3026 | 3099 | $objList{$child}[$idx_par_clmd] = $thisObj; |
3027 | 3100 | } else { |
3028 | 3101 | # 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; | |
3030 | 3105 | } |
3031 | 3106 | # if no object defined for child, already flagged as missing |
3032 | 3107 | if ($objList{$child}[$idx_defined] == 1) { |
3033 | 3108 | # child should list thisObj as its Parent |
3034 | 3109 | 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; | |
3036 | 3112 | $objList{$child}[$idx_parent] = $thisObj; |
3037 | 3113 | } 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; | |
3039 | 3117 | } |
3040 | 3118 | } |
3041 | 3119 | } |
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 | } |
4 | 4 | use Test::More; |
5 | 5 | use File::Find; |
6 | 6 | |
7 | my $GrTFversion = 16; # minimum version of Graphics::TIFF | |
7 | my $GrTFversion = 17; # minimum version of Graphics::TIFF | |
8 | 8 | my $LpngVersion = 0.57; # minimum version of Image::PNG::Libpng |
9 | 9 | |
10 | 10 | # Test all of the modules to make sure that a simple "use Module" |
14 | 14 | |
15 | 15 | my $string = $pdf->stringify(); |
16 | 16 | 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 \]}, | |
18 | 18 | q{Text Annotation in a rectangle}); |
19 | 19 | |
20 | 20 | # [RT #118352] Crash if $page->annotation is called on a page with an |
38 | 38 | |
39 | 39 | $string = $pdf->stringify(); |
40 | 40 | 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 \]}, | |
42 | 42 | q{Add an annotation to an existing annotations array stored in an indirect object}); |
43 | 43 | |
44 | 44 | 1; |
6 | 6 | use File::Temp; |
7 | 7 | use version; |
8 | 8 | use Test::More tests => 19; |
9 | #use Test::More tests => 25; when TIFF changes in | |
9 | 10 | |
10 | 11 | use PDF::Builder; |
11 | 12 | # 0: allow use of Graphics::TIFF, 1: force non-GT usage |
353 | 354 | $height = 100; |
354 | 355 | } |
355 | 356 | |
356 | # 17 | |
357 | SKIP: { | |
358 | #skip "currently fails due to bug inherited from PDF::API2", 1; | |
357 | # 17 TODO | |
358 | SKIP: { | |
359 | 359 | skip "multi-strip lzw without GT is not currently supported", 1; |
360 | 360 | 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"); |
361 | 361 | # ---------- |
433 | 433 | |
434 | 434 | is($example, $expected, "bilevel and alpha when width not a whole number of bytes with GT") or show_diag(); |
435 | 435 | } |
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 | |
436 | 599 | |
437 | 600 | ############################################################## |
438 | 601 | # cleanup. all tests involving these files skipped? |
6 | 6 | use strict; |
7 | 7 | use warnings; |
8 | 8 | |
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 | |
11 | 11 | |
12 | 12 | # command line: |
13 | 13 | # -5 run perlcritic -5 . (should be clean) |
6 | 6 | use strict; |
7 | 7 | use warnings; |
8 | 8 | |
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 | |
11 | 11 | |
12 | 12 | # command line flags, mutually exclusive: |
13 | 13 | # -raw show full output of each t-test run |
14 | 14 | # -noOK exclude "ok" lines so can easily spot error lines DEFAULT |
15 | 15 | |
16 | # add after filter-lzwdecode | |
17 | # filter-ccittfaxdecode | |
16 | 18 | my @test_list = qw( |
17 | 19 | 00-all-usable |
18 | 20 | 01-basic |
31 | 33 | extgstate |
32 | 34 | filter-ascii85decode |
33 | 35 | filter-asciihexdecode |
36 | filter-lzwdecode | |
34 | 37 | filter-runlengthdecode |
35 | 38 | font-corefont |
36 | 39 | font-synfont |
6 | 6 | use strict; |
7 | 7 | use warnings; |
8 | 8 | |
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 | |
11 | 11 | |
12 | 12 | # dependent on optional packages: |
13 | 13 | my $HS_installed = 1; # HarfBuzz::Shaper IS installed and you want to use it. |
6 | 6 | use strict; |
7 | 7 | use warnings; |
8 | 8 | |
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 | |
11 | 11 | |
12 | 12 | # command line: |
13 | 13 | # |
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 | } |