File Coverage

blib/lib/Text/PDF/SFont.pm
Criterion Covered Total %
statement 22 50 44.0
branch 2 16 12.5
condition 0 3 0.0
subroutine 6 10 60.0
pod 4 5 80.0
total 34 84 40.4


line stmt bran cond sub pod time code
1             package Text::PDF::SFont;
2              
3             # use strict;
4 1     1   486 use vars qw(@ISA %widths @encodings);
  1         1  
  1         52  
5             @ISA = qw(Text::PDF::Dict);
6              
7 1     1   4 use Text::PDF::Utils;
  1         1  
  1         51  
8 1     1   3 use Compress::Zlib;
  1         1  
  1         410  
9             # no warnings qw(uninitialized);
10              
11             =head1 NAME
12              
13             Text::PDF::SFont - PDF Standard inbuilt font resource object. Inherits from
14             L
15              
16             =head1 METHODS
17              
18             =head2 Text::PDF::SFont->new($parent, $name, $pdfname)
19              
20             Creates a new font object with given parent and name. The name must be from
21             one of the core 14 base fonts included with PDF. These are:
22              
23             Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique
24             Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic
25             Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique
26             Symbol, ZapfDingbats
27              
28             The $pdfname is the name that this particular font object will be referenced
29             by throughout the PDF file. If you want to play silly games with naming, then
30             you can write the code to do it!
31              
32             All fonts in this system are full PDF objects.
33              
34             =head1 BUGS
35              
36             Currently no width support for Symbol or ZapfDingbats, I haven't
37             got my head around the AFMs yet.
38              
39             MacExpertEncoding not supported yet (I don't have the width info for any
40             of the fonts)
41              
42             =cut
43              
44             BEGIN
45             {
46 1     1   2 @encodings = ('WinAnsiEncoding', 'MacRomanEncoding');
47 1         459 %enc_map = (
48             'WinAnsiEncoding' => [0 .. 126, 128, 160, 128, 145,134, 140,
49             131, 129, 130, 26, 139, 151, 136, 150, 128, 153, 128, 128, 143,
50             144, 141, 142, 128, 133, 132, 31, 146, 157, 137, 156, 128, 158,
51             152, 32, 161 .. 255],
52             'MacRomanEncoding' => [0 .. 127, 196, 197, 199, 201, 209, 214,
53             220, 225, 224, 226, 228, 227, 229, 231, 233, 232, 234, 235, 237,
54             236, 238, 239, 241, 243, 242, 244, 246, 245, 250, 249, 251, 252,
55             129, 176, 162, 163, 128, 182, 223, 174, 169, 146, 180, 168, 0,
56             198, 216, 0, 177, 0, 0, 165, 181, 0, 0, 0, 0, 0, 186, 169, 0,
57             230, 248, 192, 161, 172, 0, 134, 0, 0, 171, 187, 131, 32, 192,
58             195, 213, 150, 156, 133, 132, 141 .. 144, 247, 0, 255, 152, 135,
59             164, 136, 137, 147, 148, 130, 183, 145, 140, 139, 194, 202, 200,
60             205, 206, 207, 204, 211, 212, 0, 210, 218, 219, 217, 154, 26,
61             31, 175, 24, 27, 30, 184, 28, 29, 25],
62             'PDFDocEncoding' => [0 .. 255],
63             'AdobeStandardEncoding' => [
64             0 .. 38, 144, 40 .. 95, 143, 97 .. 126, 0, 0, 0, 0, 0, 0, 0,
65             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66             0, 0, 0, 0, 0, 0, 0, 161, 162, 163, 135, 165, 134, 167, 164,
67             39, 141, 171, 136, 137, 147, 148, 0, 133, 129, 130, 183, 0,
68             182, 128, 145, 140, 142, 187, 131, 139, 0, 191, 0, 96, 180,
69             26, 31,175, 24, 27, 168, 0, 30, 231, 0, 28, , 25, 29, 132,
70             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 170,
71             0, 0, 0, 0, 149, 216, 150, 186, 0, 0, 0, 0, 0, 230, 0, 0, 0,
72             154, 0, 0, 155, 248, 156, 223, 0, 0, 0, 0],
73             );
74             }
75              
76             sub new
77             {
78 1     1 1 7 my ($class, $parent, $name, $pdfname, $encoding) = @_;
79 1         5 my ($self) = $class->SUPER::new;
80              
81 1 50       3 return undef unless exists $width_data{$name};
82 1         3 $self->{'Type'} = PDFName("Font");
83 1         8 $self->{'Subtype'} = PDFName("Type1");
84 1         3 $self->{'BaseFont'} = PDFName($name);
85 1         2 $self->{'Name'} = PDFName($pdfname);
86 1 50       2 $self->{'Encoding'} = PDFName($encodings[$encoding-1]) if ($encoding);
87 1         3 $parent->new_obj($self);
88 1         1 $self;
89             }
90              
91             =head2 $f->width($text)
92              
93             Returns the width of the text in em.
94              
95             =cut
96              
97             sub getBase
98             {
99 0     0 0   my ($self) = @_;
100              
101 0 0         unless (defined $widths{$self->{'BaseFont'}->val})
102 0           { @{$widths{$self->{'BaseFont'}->val}} = unpack("n*",
103 0           uncompress(unpack("u", $width_data{$self->{'BaseFont'}->val}))); }
104 0           $self;
105             }
106              
107             sub width
108             {
109 0     0 1   my ($self, $text) = @_;
110 0           my ($width);
111 0           my ($str) = $self->{'BaseFont'}->val;
112 0           my ($enc);
113 0 0         $enc = $self->{'Encoding'}->val if defined $self->{'Encoding'};
114            
115 0           $self->getBase;
116 0           foreach (unpack("C*", $text))
117 0 0 0       { $width += $widths{$str}[(defined $enc and $enc ne "") ? $enc_map{$enc}[$_] : $_]; }
118 0           $width / 1000;
119             }
120              
121             =head2 $f->trim($text, $len)
122              
123             Trims the given text to the given length (in em) returning the trimmed
124             text
125              
126             =cut
127              
128             sub trim
129             {
130 0     0 1   my ($self, $text, $len) = @_;
131 0           my ($width, $i);
132 0           my ($str) = $self->{'BaseFont'}->val;
133 0           my ($enc);
134 0 0         $enc = $self->{'Encoding'}->val if defined $self->{'Encoding'};
135            
136 0           $self->getBase;
137 0           $len *= 1000;
138            
139 0           foreach (unpack("C*", $text))
140             {
141 0 0         $width += $widths{$str}[$enc ne "" ? $enc_map{$enc}[$_] : $_];
142 0 0         last if ($width > $len);
143 0           $i++;
144             }
145 0           return substr($text, 0, $i);
146             }
147              
148             =head2 $f->out_text($text)
149              
150             Acknowledges the text to be output for subsetting purposes, etc.
151              
152             =cut
153              
154             sub out_text
155             {
156 0     0 1   my ($self, $text) = @_;
157              
158 0           return PDFStr($text)->as_pdf;
159             }
160              
161             BEGIN
162             {
163 1     1   22 %width_data = (
164             'Courier' => <<'EOT',
165             8>)QC8"`-,$4,)TB9?_"%Q]`(*0`U#D_/
166             EOT
167              
168             'Courier-Bold' => <<'EOT',
169             8>)QC8"`-,$4,)TB9?_"%Q]`(*0`U#D_/
170             EOT
171              
172             'Courier-BoldOblique' => <<'EOT',
173             8>)QC8"`-,$4,)TB9?_"%Q]`(*0`U#D_/
174             EOT
175              
176             'Courier-Oblique' => <<'EOT',
177             8>)QC8"`-,$4,)TB9?_"%Q]`(*0`U#D_/
178             EOT
179              
180             'Helvetica' => <<'EOT',
181             M>)R54#$.PC`,C.U.?4`E_I!/P)2E?0)+9Q:V/H"=/0]@[0_X0R362FQ]0"16
182             MSFY+4<5"3HJ
183             M*3DAFQ%[V7/".RJG.;VEM^K6IE;T8.\&4\R3KMYN<`-E-Z!_F5=3UARJ$B)%
184             M0P4U'+#/T?X^RFB]-_T_!QFG[50+<59]5,RSP?7*37Y\IA0ZB9]TQ@O*B&JZ
185             MP@E3`KN@P$YQ!?33$L_[5>J+E`OPK]*<2G-E^^VJ=),+B\,_W`]K
186             )A]92?@,9KULP
187             EOT
188              
189             'Helvetica-Bold' => <<'EOT',
190             M>)R54"L6PC`0S&Y<#Y#70^02H&IZ!4PT!L
191             MZNB\-)O]S>PZ]]\G_08!YZY1HS]K=D_Z!NWH#Q(LLH7E:$
192             M&?9.,]ZC^2QF?S_!@EUX41^9GAG_2P9I327F.5#[
193             M[&>[W;5H\S-R#.B%"+O@+MSFFZQ+V4>=JB7+0TYXH3.L7B[8!/=$?8'V$7Q[
194             G`V>J0/],!L`X.(?YFP70U:RV-7+N"LS[W?!2GW[0K6QN[`T)B%=1
195             EOT
196              
197             'Helvetica-BoldOblique' => <<'EOT',
198             M>)R54"L6PC`0S&Y<#Y#70^02H&IZ!4PT!L
199             MZNB\-)O]S>PZ]]\G_08!YZY1HS]K=D_Z!NWH#Q(LLH7E:$
200             M&?9.,]ZC^2QF?S_!@EUX41^9GAG_2P9I327F.5#[
201             M[&>[W;5H\S-R#.B%"+O@+MSFFZQ+V4>=JB7+0TYXH3.L7B[8!/=$?8'V$7Q[
202             G`V>J0/],!L`X.(?YFP70U:RV-7+N"LS[W?!2GW[0K6QN[`T)B%=1
203             EOT
204              
205             'Helvetica-Oblique' => <<'EOT',
206             M>)R54#$.PC`,C.U.?4`E_I!/P)2E?0)+9Q:V/H"=/0]@[0_X0R362FQ]0"16
207             MSFY+4<5"3HJ
208             M*3DAFQ%[V7/".RJG.;VEM^K6IE;T8.\&4\R3KMYN<`-E-Z!_F5=3UARJ$B)%
209             M0P4U'+#/T?X^RFB]-_T_!QFG[50+<59]5,RSP?7*37Y\IA0ZB9]TQ@O*B&JZ
210             MP@E3`KN@P$YQ!?33$L_[5>J+E`OPK]*<2G-E^^VJ=),+B\,_W`]K
211             )A]92?@,9KULP
212             EOT
213              
214             'Times-Bold' => <<'EOT',
215             M>)R54#$.PC`,C)T%Y0&9^`%Y0;<.+$C]`DO?DJ43>S<65AZ05W3F`960F#(Q
216             M<78"+6(BI]B.[=@^&_/?H>X;YDD=[RA3MK-MR:LW
217             M$5=D;YUU%.%U/-HK3]#P(19*CIU+)BJ@$^^U5N9`26ZU)0)I6TB\-1+5EWG2
218             M_HD&95+T#-)?M?3VY%$G4JK[J*Q0$?E\IZ#\#:R.
219             M3N`8`'3GK>P$]@'QAT#F6:#
220             (93.47Q0]@OL`
221             EOT
222              
223             'Times-BoldItalic' => <<'EOT',
224             M>)R54+L1@S`,E>2.`;Q$F,`5&8`-.!I/P0#NTS-`V@S`%-09@+O
225             MXH1+%=Z!]?/3XQ']]W"_!STXR8$S9W=T#7NK9@FH:\]KYP>8D:#`K4YFPUJ^
226             MX$BX/TMT$VJK1.NTY40-'8E@\,IA7,JXV*N;6W1TJW<-XK(O`1[9(K/-)1[H
227             MR@-4$H^F?7.;GG0V;6/)BE*W83OVNXNIB,HOJW*:'^G]5V#$O-RX@8J1"%'/
228             M)VAL@5XZ3,`3R[+<%?:?%>"OL2D&S($/PE>L2G:N0M-2X5_(U0.=")H7%,>>
229             $ZZB'L0``
230             EOT
231              
232             'Times-Italic' => <<'EOT',
233             M>)R54#L.PC`,C9T-1E`W;N"9O0?H%5AZBAX@>T
234             M[*;0BHD^)?ZES_9S[K^/JCG<"_>1$B5?^H6[639QU#Q.H94?X`U'!?[:
235             MN#?;5'I$+6T
236             MHI8WV&=GLS>^4>O.PVS^KEW0!Y&_:@7S7&P*47[P@-/T")\N*YV&G[2V_1V\
237             M"CTB"8EILC2MA+;P'PK8^@O?8-_LC^IB9]5@1)SXHJI,D7<;4&3,7\1)9(J]
238             %`8H]BK$`
239             EOT
240              
241             'Times-Roman' => <<'EOT',
242             M>)R542L2PC`0S6Y<-1/'#2(S>`[0*V!Z"@Z`1\+D`%@$,I89=`=\916J@D'Q
243             M=IMV6E#T3;9]N]NWGQCSWT/E'.8->Z"..KNVA;FHM^,@?APGD1\X
244             M:XY`S15[V!K_[X39K3#U1=A*F#VKKT*.PWE`JZ0$VY]R4!=KB[$>%/M.H-YI
245             M9F-NU/`2\VRT]]:V\C8GZ9\#6%*`V3NJ>^W':VWIOH9BROO(5:"(2ORBA
246             M\%72'C-Z0+*NNBM/*\2?`DHZ30;T(Z94#-N=QH$P8UXG&<%QPES&;._HY>LF
247             %/HNICN<`
248             EOT
249              
250             'Symbol' => <<'EOT',
251             M>)RED*%/PV`0Q;_W#C-D1
252             MVID9DAF^A&0)R3"\:TT3+(F5W;)1J40E4X>2#'
253             M\1]RY)PY>%/N6"ENN>(/(SOYW:NN[4&YL\`/7G$I]16-JF>;
254             MNU-"PPDJ1A1R
255             MZ($7S5;U<[3Z[_NPMZYUD'[@VN;:=&H["V+N65..\-IR\:A.OVJK[>+(/Z'H
256             3]4S^3R/20`@HD+%V_NJ_?N9DIP``
257             EOT
258              
259             'ZapfDingbats' => <<'EOT',
260             M>)RMD#M+`T$4A>>>TZ3TD4V,51K!3CO!!R$B@LTV%M:2*BFUL1!+"19:F2)9
261             MB"AIM)`$B6D$14%,D11:^@,DJ(46NT8$#_X"0>?CFPYOS1+L\$H^
262             MH$N/"2;1X"5/,,85[K$FZ^S@G3[Z^,`,:OA$A!!O]HIQI)#%&8<8%PFF.,I)
263             M3BG.DOJLYAE6\(1[O&AW!.>,T6D,<8T;'.."TYS0:4_K4[105Z1AW#')09G7
264             M>WT1(N2FB'/`FF['/*M:T8H($"C_;3$GXN)+E*WL>JYGOOF_JP`>D4::NZCH
265             M7Q%C6$83:S\_^D^VN,C(VGAF($NL\D#,,\]9!F*?ASRR+M>Y('+,J1XM%IQC
266             405DU2*[*#=[*C&Y5V6;I&TT<5J(`
267             EOT
268             );
269             }
270              
271             1;
272