| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package PDF::Make::Builder::Font; |
|
2
|
42
|
|
|
42
|
|
212
|
use strict; |
|
|
42
|
|
|
|
|
54
|
|
|
|
42
|
|
|
|
|
1212
|
|
|
3
|
42
|
|
|
42
|
|
179
|
use warnings; |
|
|
42
|
|
|
|
|
52
|
|
|
|
42
|
|
|
|
|
1460
|
|
|
4
|
42
|
|
|
42
|
|
148
|
use Object::Proto; |
|
|
42
|
|
|
|
|
46
|
|
|
|
42
|
|
|
|
|
1905
|
|
|
5
|
42
|
|
|
42
|
|
199
|
use PDF::Make::Page qw(:fonts); |
|
|
42
|
|
|
|
|
57
|
|
|
|
42
|
|
|
|
|
5477
|
|
|
6
|
42
|
|
|
42
|
|
15950
|
use PDF::Make::Font (); |
|
|
42
|
|
|
|
|
108
|
|
|
|
42
|
|
|
|
|
1611
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
BEGIN { |
|
9
|
42
|
|
|
42
|
|
1834
|
Object::Proto::define('PDF::Make::Builder::Font', |
|
10
|
|
|
|
|
|
|
'colour:Str:default(#000)', |
|
11
|
|
|
|
|
|
|
'size:Num:default(9)', |
|
12
|
|
|
|
|
|
|
'family:Str:default(Helvetica)', |
|
13
|
|
|
|
|
|
|
'bold:Bool:default(0)', |
|
14
|
|
|
|
|
|
|
'italic:Bool:default(0)', |
|
15
|
|
|
|
|
|
|
'line_height:Num', |
|
16
|
|
|
|
|
|
|
'loaded:HashRef:default({})', |
|
17
|
|
|
|
|
|
|
); |
|
18
|
42
|
|
|
|
|
39089
|
Object::Proto::import_accessors('PDF::Make::Builder::Font'); |
|
19
|
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Standard 14 font family mapping: family => { variant => page constant } |
|
22
|
|
|
|
|
|
|
my %STD14 = ( |
|
23
|
|
|
|
|
|
|
Times => { |
|
24
|
|
|
|
|
|
|
normal => TIMES_ROMAN, |
|
25
|
|
|
|
|
|
|
bold => TIMES_BOLD, |
|
26
|
|
|
|
|
|
|
italic => TIMES_ITALIC, |
|
27
|
|
|
|
|
|
|
bolditalic => TIMES_BOLDITALIC, |
|
28
|
|
|
|
|
|
|
}, |
|
29
|
|
|
|
|
|
|
Helvetica => { |
|
30
|
|
|
|
|
|
|
normal => HELVETICA, |
|
31
|
|
|
|
|
|
|
bold => HELVETICA_BOLD, |
|
32
|
|
|
|
|
|
|
italic => HELVETICA_OBLIQUE, |
|
33
|
|
|
|
|
|
|
bolditalic => HELVETICA_BOLDOBLIQUE, |
|
34
|
|
|
|
|
|
|
}, |
|
35
|
|
|
|
|
|
|
Courier => { |
|
36
|
|
|
|
|
|
|
normal => COURIER, |
|
37
|
|
|
|
|
|
|
bold => COURIER_BOLD, |
|
38
|
|
|
|
|
|
|
italic => COURIER_OBLIQUE, |
|
39
|
|
|
|
|
|
|
bolditalic => COURIER_BOLDOBLIQUE, |
|
40
|
|
|
|
|
|
|
}, |
|
41
|
|
|
|
|
|
|
Symbol => { normal => SYMBOL }, |
|
42
|
|
|
|
|
|
|
ZapfDingbats => { normal => ZAPFDINGBATS }, |
|
43
|
|
|
|
|
|
|
); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# Map family+variant to PDF BaseFont name for XS Font |
|
46
|
|
|
|
|
|
|
my %BASEFONT = ( |
|
47
|
|
|
|
|
|
|
'Times_normal' => 'Times-Roman', |
|
48
|
|
|
|
|
|
|
'Times_bold' => 'Times-Bold', |
|
49
|
|
|
|
|
|
|
'Times_italic' => 'Times-Italic', |
|
50
|
|
|
|
|
|
|
'Times_bolditalic' => 'Times-BoldItalic', |
|
51
|
|
|
|
|
|
|
'Helvetica_normal' => 'Helvetica', |
|
52
|
|
|
|
|
|
|
'Helvetica_bold' => 'Helvetica-Bold', |
|
53
|
|
|
|
|
|
|
'Helvetica_italic' => 'Helvetica-Oblique', |
|
54
|
|
|
|
|
|
|
'Helvetica_bolditalic' => 'Helvetica-BoldOblique', |
|
55
|
|
|
|
|
|
|
'Courier_normal' => 'Courier', |
|
56
|
|
|
|
|
|
|
'Courier_bold' => 'Courier-Bold', |
|
57
|
|
|
|
|
|
|
'Courier_italic' => 'Courier-Oblique', |
|
58
|
|
|
|
|
|
|
'Courier_bolditalic' => 'Courier-BoldOblique', |
|
59
|
|
|
|
|
|
|
'Symbol_normal' => 'Symbol', |
|
60
|
|
|
|
|
|
|
'ZapfDingbats_normal' => 'ZapfDingbats', |
|
61
|
|
|
|
|
|
|
); |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# Cache for PDF::Make::Font XS objects (exact per-glyph metrics) |
|
64
|
|
|
|
|
|
|
my %_xs_font_cache; |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub _xs_font { |
|
67
|
15490
|
|
|
15490
|
|
18290
|
my ($self, $variant) = @_; |
|
68
|
15490
|
|
33
|
|
|
30015
|
$variant //= $self->_default_variant; |
|
69
|
15490
|
|
|
|
|
17881
|
my $fam = family $self; |
|
70
|
15490
|
|
|
|
|
17148
|
my $key = "${fam}_${variant}"; |
|
71
|
15490
|
100
|
|
|
|
27964
|
return $_xs_font_cache{$key} if $_xs_font_cache{$key}; |
|
72
|
34
|
|
|
|
|
78
|
my $basefont = $BASEFONT{$key}; |
|
73
|
34
|
50
|
|
|
|
103
|
return undef unless $basefont; |
|
74
|
34
|
|
|
|
|
1783
|
$_xs_font_cache{$key} = PDF::Make::Font->standard14($basefont); |
|
75
|
34
|
|
|
|
|
106
|
return $_xs_font_cache{$key}; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub _default_variant { |
|
79
|
15902
|
|
|
15902
|
|
18602
|
my ($self) = @_; |
|
80
|
15902
|
100
|
100
|
|
|
24202
|
return 'bolditalic' if bold($self) && italic($self); |
|
81
|
15898
|
100
|
|
|
|
21261
|
return 'bold' if bold($self); |
|
82
|
15884
|
100
|
|
|
|
20967
|
return 'italic' if italic($self); |
|
83
|
15875
|
|
|
|
|
32654
|
return 'normal'; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub effective_line_height { |
|
87
|
402
|
|
|
402
|
1
|
507
|
my ($self) = @_; |
|
88
|
402
|
|
|
|
|
455
|
my $lh = line_height $self; |
|
89
|
402
|
100
|
66
|
|
|
1220
|
return defined $lh && $lh > 0 ? $lh : size $self; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub measure_text { |
|
93
|
15476
|
|
|
15476
|
1
|
19638
|
my ($self, $text) = @_; |
|
94
|
15476
|
|
|
|
|
19101
|
my $xs = $self->_xs_font; |
|
95
|
15476
|
50
|
|
|
|
120484
|
return $xs->string_width($text, size $self) if $xs; |
|
96
|
|
|
|
|
|
|
# Fallback for unknown fonts |
|
97
|
0
|
|
|
|
|
0
|
return length($text) * 0.52 * (size $self); |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub measure_word { |
|
101
|
5
|
|
|
5
|
1
|
9
|
my ($self, $word) = @_; |
|
102
|
5
|
|
|
|
|
12
|
my $xs = $self->_xs_font; |
|
103
|
5
|
50
|
|
|
|
26
|
return $xs->string_width($word, size $self) if $xs; |
|
104
|
0
|
|
|
|
|
0
|
return length($word) * 0.52 * (size $self); |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub space_width { |
|
108
|
9
|
|
|
9
|
1
|
153667
|
my ($self) = @_; |
|
109
|
9
|
|
|
|
|
27
|
my $xs = $self->_xs_font; |
|
110
|
9
|
50
|
|
|
|
112
|
return $xs->string_width(' ', size $self) if $xs; |
|
111
|
0
|
|
|
|
|
0
|
return 0.28 * (size $self); |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub hex_to_rgb { |
|
115
|
505
|
|
|
505
|
1
|
2612
|
my ($self, $hex) = @_; |
|
116
|
505
|
|
|
|
|
1395
|
$hex =~ s/^#//; |
|
117
|
505
|
|
|
|
|
643
|
my ($r, $g, $b); |
|
118
|
505
|
100
|
|
|
|
806
|
if (length($hex) == 3) { |
|
|
|
100
|
|
|
|
|
|
|
119
|
448
|
|
|
|
|
928
|
($r, $g, $b) = map { hex($_.$_) / 255.0 } split //, $hex; |
|
|
1344
|
|
|
|
|
2484
|
|
|
120
|
|
|
|
|
|
|
} elsif (length($hex) == 6) { |
|
121
|
54
|
|
|
|
|
142
|
$r = hex(substr($hex, 0, 2)) / 255.0; |
|
122
|
54
|
|
|
|
|
103
|
$g = hex(substr($hex, 2, 2)) / 255.0; |
|
123
|
54
|
|
|
|
|
99
|
$b = hex(substr($hex, 4, 2)) / 255.0; |
|
124
|
|
|
|
|
|
|
} else { |
|
125
|
3
|
|
|
|
|
11
|
return (0, 0, 0); |
|
126
|
|
|
|
|
|
|
} |
|
127
|
502
|
|
|
|
|
1062
|
return ($r, $g, $b); |
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
sub resource_name { |
|
131
|
12
|
|
|
12
|
1
|
14
|
my ($self, $variant) = @_; |
|
132
|
12
|
|
33
|
|
|
38
|
$variant //= $self->_default_variant; |
|
133
|
12
|
|
|
|
|
13
|
my $fam = family $self; |
|
134
|
12
|
|
|
|
|
22
|
return "F_${fam}_${variant}"; |
|
135
|
|
|
|
|
|
|
} |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub ensure_loaded { |
|
138
|
426
|
|
|
426
|
1
|
630
|
my ($self, $xs_page, $variant) = @_; |
|
139
|
426
|
|
66
|
|
|
1066
|
$variant //= $self->_default_variant; |
|
140
|
426
|
|
|
|
|
511
|
my $fam = family $self; |
|
141
|
426
|
|
|
|
|
583
|
my $key = "${fam}_${variant}"; |
|
142
|
426
|
|
|
|
|
524
|
my $res_name = "F_${key}"; |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Cache is per-page (keyed by page pointer address) to handle overflow |
|
145
|
426
|
|
|
|
|
864
|
my $page_id = "$xs_page"; # stringified ref = unique per page |
|
146
|
426
|
|
|
|
|
501
|
my $ld = loaded $self; |
|
147
|
426
|
100
|
|
|
|
1028
|
return $res_name if $ld->{"${key}_${page_id}"}; |
|
148
|
|
|
|
|
|
|
|
|
149
|
182
|
|
|
|
|
267
|
my $family_map = $STD14{$fam}; |
|
150
|
182
|
50
|
|
|
|
300
|
die "PDF::Make::Builder::Font: unknown font family '$fam'" unless $family_map; |
|
151
|
182
|
|
|
|
|
289
|
my $font_id = $family_map->{$variant}; |
|
152
|
182
|
50
|
|
|
|
316
|
die "PDF::Make::Builder::Font: unknown variant '$variant' for '$fam'" unless defined $font_id; |
|
153
|
|
|
|
|
|
|
|
|
154
|
182
|
|
|
|
|
1840
|
$xs_page->add_std14_font($res_name, $font_id); |
|
155
|
182
|
|
|
|
|
519
|
$ld->{"${key}_${page_id}"} = 1; |
|
156
|
182
|
|
|
|
|
240
|
loaded $self, $ld; |
|
157
|
182
|
|
|
|
|
495
|
return $res_name; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
|
|
160
|
1
|
|
|
1
|
1
|
522
|
sub families { return keys %STD14 } |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
1; |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
__END__ |