File Coverage

blib/lib/PDF/Builder/Basic/PDF/Utils.pm
Criterion Covered Total %
statement 56 61 91.8
branch 6 8 75.0
condition n/a
subroutine 21 22 95.4
pod 10 10 100.0
total 93 101 92.0


line stmt bran cond sub pod time code
1             #=======================================================================
2             #
3             # THIS IS A REUSED PERL MODULE, FOR PROPER LICENCING TERMS SEE BELOW:
4             #
5             # Copyright Martin Hosken <Martin_Hosken@sil.org>
6             #
7             # No warranty or expression of effectiveness, least of all regarding
8             # anyone's safety, is implied in this software or documentation.
9             #
10             # This specific module is licensed under the Perl Artistic License.
11             # Effective 28 January 2021, the original author and copyright holder,
12             # Martin Hosken, has given permission to use and redistribute this module
13             # under the MIT license.
14             #
15             #=======================================================================
16             package PDF::Builder::Basic::PDF::Utils;
17              
18 42     42   7759 use strict;
  42         140  
  42         1851  
19 42     42   224 use warnings;
  42         87  
  42         3900  
20              
21             our $VERSION = '3.028'; # VERSION
22             our $LAST_UPDATE = '3.027'; # manually update whenever code is changed
23              
24             =head1 NAME
25              
26             PDF::Builder::Basic::PDF::Utils - Utility functions for PDF library
27              
28             =head1 DESCRIPTION
29              
30             A set of utility functions to save the fingers of the PDF library users!
31              
32             =head1 METHODS
33              
34             =cut
35              
36 42     42   24131 use PDF::Builder::Basic::PDF::Array;
  42         196  
  42         1824  
37 42     42   22816 use PDF::Builder::Basic::PDF::Bool;
  42         143  
  42         1531  
38 42     42   26822 use PDF::Builder::Basic::PDF::Dict;
  42         245  
  42         2149  
39 42     42   323 use PDF::Builder::Basic::PDF::Name;
  42         88  
  42         1081  
40 42     42   24045 use PDF::Builder::Basic::PDF::Null;
  42         152  
  42         1775  
41 42     42   25615 use PDF::Builder::Basic::PDF::Number;
  42         152  
  42         1581  
42 42     42   274 use PDF::Builder::Basic::PDF::String;
  42         86  
  42         1037  
43 42     42   23317 use PDF::Builder::Basic::PDF::Literal;
  42         158  
  42         1638  
44              
45 42     42   307 use Exporter;
  42         93  
  42         2388  
46 42     42   264 use vars qw(@EXPORT @ISA);
  42         77  
  42         27346  
47             @ISA = qw(Exporter);
48             @EXPORT = qw(PDFBool PDFArray PDFDict PDFName PDFNull
49             PDFNum PDFString PDFStr PDFStrHex PDFUtf);
50              
51             =head2 PDFBool
52              
53             PDFBool()
54              
55             =over
56              
57             Creates a Bool via PDF::Builder::Basic::PDF::Bool->new()
58              
59             =back
60              
61             =cut
62              
63             sub PDFBool {
64 5     5 1 53 return PDF::Builder::Basic::PDF::Bool->new(@_);
65             }
66              
67             =head2 PDFArray
68              
69             PDFArray()
70              
71             =over
72              
73             Creates an array via PDF::Builder::Basic::PDF::Array->new()
74              
75             =back
76              
77             =cut
78              
79             sub PDFArray {
80 1163     1163 1 5728 return PDF::Builder::Basic::PDF::Array->new(@_);
81             }
82              
83             =head2 PDFDict
84              
85             PDFDict()
86              
87             =over
88              
89             Creates a dict via PDF::Builder::Basic::PDF::Dict->new()
90              
91             =back
92              
93             =cut
94              
95             sub PDFDict {
96 1396     1396 1 8235 return PDF::Builder::Basic::PDF::Dict->new(@_);
97             }
98              
99             =head2 PDFName
100              
101             PDFName()
102              
103             =over
104              
105             Creates a name via PDF::Builder::Basic::PDF::Name->new()
106              
107             =back
108              
109             =cut
110              
111             sub PDFName {
112 13625     13625 1 39182 return PDF::Builder::Basic::PDF::Name->new(@_);
113             }
114              
115             =head2 PDFNull
116              
117             PDFNull()
118              
119             =over
120              
121             Creates a null via PDF::Builder::Basic::PDF::Null->new()
122              
123             =back
124              
125             =cut
126              
127             sub PDFNull {
128 12     12 1 55 return PDF::Builder::Basic::PDF::Null->new(@_);
129             }
130              
131             =head2 PDFNum
132              
133             PDFNum()
134              
135             =over
136              
137             Creates a number via PDF::Builder::Basic::PDF::Number->new()
138              
139             =back
140              
141             =cut
142              
143             sub PDFNum {
144 10694     10694 1 27497 return PDF::Builder::Basic::PDF::Number->new(@_);
145             }
146              
147             =head2 PDFString
148              
149             PDFString($text, $usage)
150              
151             =over
152              
153             Returns either PDFStr($text) or PDFUtf($text), depending on whether C<$text>
154             is already in UTF-8 and whether the C<$usage> permits UTF-8. If UTF-8 is I<not>
155             permitted, C<downgrade> will be called on a UTF-8 formatted C<$text>.
156              
157             C<$usage> is a single character string indicating the use for which C<$text>
158             is to be applied. Some uses permit UTF-8, while others (currently) forbid it:
159              
160             =over
161              
162             =item 's'
163              
164             An ordinary B<string>, where UTF-8 text is permitted.
165              
166             =item 'n'
167              
168             A B<named destination>, where UTF-8 text is permitted.
169              
170             =item 'o'
171              
172             An B<outline title>, where UTF-8 text is permitted.
173              
174             =item 'p'
175              
176             A B<popup title>, where UTF-8 text is permitted.
177              
178             =item 'm'
179              
180             B<metadata>, where UTF-8 text is permitted.
181              
182             =item 'f'
183              
184             A B<file path and/or name>, where UTF-8 text is currently B<not> permitted.
185              
186             =item 'u'
187              
188             A B<URL>, where UTF-8 text is currently B<not> permitted.
189              
190             =item 'x'
191              
192             Any other usage where UTF-8 text is B<not> permitted.
193              
194             =back
195              
196             =back
197              
198             =cut
199              
200             sub PDFString {
201 254     254 1 777 my ($text, $usage) = @_;
202              
203             # some old code also checked valid(), but that seems to always give a true
204             # return on non-UTF-8 text
205             #my $isUTF8 = utf8::is_utf8($text) || utf8::valid($text);
206 254         1009 my $isUTF8 = utf8::is_utf8($text);
207 254         494 my $isPermitted = 0; # default NO
208             # someone is bound to forget whether it's upper or lowercase!
209 254 100       1385 if ($usage =~ m/^[snopm]/i) {
210 244         551 $isPermitted = 1;
211             }
212              
213 254 100       745 if ($isPermitted) {
214 244 50       951 if ($isUTF8) {
215 0         0 return PDFUtf($text);
216             } else {
217 244         789 return PDFStr($text);
218             }
219             } else {
220 10 50       29 if ($isUTF8) {
221 0         0 utf8::downgrade($text); # force 7 bit ASCII
222             }
223 10         28 return PDFStr($text);
224             }
225             }
226              
227             =head2 PDFStr
228              
229             PDFStr()
230              
231             =over
232              
233             Creates a string via PDF::Builder::Basic::PDF::String->new()
234              
235             B<DEPRECATED.> It is preferable that you use C<PDFString> instead.
236              
237             =back
238              
239             =cut
240              
241             sub PDFStr {
242 259     259 1 1866 return PDF::Builder::Basic::PDF::String->new(@_);
243             }
244              
245             =head2 PDFStrHex
246              
247             PDFStrHex()
248              
249             =over
250              
251             Creates a hex-string via PDF::Builder::Basic::PDF::String->new()
252              
253             =back
254              
255             =cut
256              
257             sub PDFStrHex {
258 1     1 1 2 my $string = PDF::Builder::Basic::PDF::String->new(@_);
259 1         75 $string->{' ishex'} = 1;
260 1         3 return $string;
261             }
262              
263             =head2 PDFUtf
264              
265             PDFUtf()
266              
267             =over
268              
269             Creates a utf8-string via PDF::Builder::Basic::PDF::String->new()
270              
271             B<DEPRECATED.> It is preferable that you use C<PDFString> instead.
272              
273             =back
274              
275             =cut
276              
277             sub PDFUtf {
278 0     0 1   my $string = PDF::Builder::Basic::PDF::String->new(@_);
279 0           $string->{' isutf'} = 1;
280 0           return $string;
281             }
282              
283             1;