File: FontManager.pl

package info (click to toggle)
libpdf-builder-perl 3.027-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 23,992 kB
  • sloc: perl: 107,532; makefile: 10
file content (404 lines) | stat: -rw-r--r-- 16,090 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
#!/usr/bin/perl
# list a font file's contents
# outputs FontManager.pdf
# run without arguments to get help listing
# author: Phil M Perry

use strict;
use warnings;

our $VERSION = '3.027'; # VERSION
our $LAST_UPDATE = '3.027'; # manually update whenever code is changed

use PDF::Builder;
use utf8;
use Carp;

my $do_Georgia = 1;
   # Georgia is a Windows core font, which you may be able to install on your
   # system (as well as update the font path list, if necessary).
my $do_Script = 0;
   # TBD: selection of a default script font, depending on OS
my $do_noncore = 1; # do fonts not found in core
my @oddFonts = (1, 1, 1, 1);
   # See section demarcated by this flag to update paths and fonts, as this
   # section includes fonts not normally found by default in an installation,
   # including
   #   DejaVu Sans (TTF), 4 variants
   #   PalladioL (T1)
   #   Codec (Bdf), dot-matrix printer look
   #   Adobe GothicStandard-Light (OTF), a CJK font
   # Any of which is not available (including being on a different path) will 
   # have its output text omitted. Set @oddFonts array to control which are 
   # displayed. Also will certainly need to update @fontpaths (see later), as 
   # they are custom to my setup.
   
my $dump = 1; # debug dump of font data (LOTS of output)

my $name = $0;
$name =~ s/\.pl$/.pdf/; # write into examples directory

my ($page, $text, $grfx);
my $pdf = PDF::Builder->new('compress' => 'none');
# a font to use that doesn't hit anything in FontManager
#my $exmpl_font = $pdf->corefont('Helvetica');

# page 1
$page = $pdf->page();
$text = $page->text();
#$grfx = $page->gfx();

if ($dump) {
    print "=================================================================\n";
    print "=== dump initial state of FontManager before doing anything else.\n";
    # note that this prints to STDOUT, not to the PDF
    $pdf->dump_font_tables();
}

# we have the default core fonts loaded. put out a little text
my ($x,$y, $xcur, $word, $width, @textwords);
$x = 50; $y = 700;
my $colwidth = 400;
my $font_size = 20;
my $leading = 1.1 * $font_size;
$xcur = $x; # x,y is start of current line, xcur,y is where we are in line
my $space_w;

if ($dump) { print "**** Times Roman\n"; }
# should be current font (core, Times Roman)
$text->font($pdf->get_font('italic'=>0), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "Start out in normal text. Now switch";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Times Italic\n"; }
$text->font($pdf->get_font('italic'=>1), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "from normal to italic text.";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Times Roman\n"; }
# back to Roman. could add 'bold'=>0 to be certain
$text->font($pdf->get_font('italic'=>0), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "And back to Roman (normal).";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Times Bold\n"; }
$text->font($pdf->get_font('bold'=>1), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "Does BOLD get your attention?";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Times BoldItalic\n"; }
$text->font($pdf->get_font('italic'=>1), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "Then how about bold AND italic?";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Times Roman\n"; }
$text->font($pdf->get_font('italic'=>0, 'bold'=>0), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split ' ', "OK, too much excitement. Back to plain old Roman.";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

# start next paragraph
$y -= 3*$leading;
$xcur = $x;

if ($dump) {
    print "=================================================================\n";
    print "=== dump state of FontManager after playing with Times face.\n";
    # note that this prints to STDOUT, not to the PDF
    $pdf->dump_font_tables();
}

if ($dump) { print "**** Helvetica (sans serif)\n"; }
$text->font($pdf->get_font('face'=>'sans-serif', 'italic'=>0, 'bold'=>0), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "Take the default sans serif face, which is Helvetica.";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Courier\n"; }
$text->font($pdf->get_font('face'=>'Courier'), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "No? Then how about typewriter output (Courier)?";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Symbol\n"; }
$text->font($pdf->get_font('face'=>'Symbol'), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "Any idea what this says, like whazzup, dude?";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** Helvetica\n"; }
$text->font($pdf->get_font('face'=>'Helvetica'), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "And this looks like the signs in the NYC subway.";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

if ($dump) { print "**** default font\n"; }
$text->font($pdf->get_font('face'=>'default'), $font_size);
$space_w = $text->advancewidth(' ');
@textwords = split / /, "Back to the default face (Times).";
while (@textwords) {
    ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
}

# start next paragraph
$y -= 3*$leading;
$xcur = $x;

if ($do_Georgia) {
    if ($dump) { print "**** Georgia\n"; }
    $text->font($pdf->get_font('face'=>'Georgia'), $font_size);
    $space_w = $text->advancewidth(' ');
    @textwords = split / /, "And finally, I've got Georgia on my mind... a Windows core extension.";
    while (@textwords) {
        ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
    }
}

if ($do_Script) {
    if ($dump) { print "**** Script font\n"; }
    $text->font($pdf->get_font('face'=>'Script'), $font_size);
    $space_w = $text->advancewidth(' ');
    @textwords = split / /, "Let's try a script font. Default depends on OS.";
    while (@textwords) {
        ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
    }
}

# start next paragraph
$y -= 3*$leading;
$xcur = $x;

if ($dump) {
    print "=================================================================\n";
    print "=== dump state of FontManager after face switching.\n";
    # note that this prints to STDOUT, not to the PDF
    $pdf->dump_font_tables();
}

# now to load in some non-core fonts. you will need to update these!
if ($do_noncore) {
    # add [0] DejaVu Sans TTF (in /Windows/Fonts on Windows)
    if ($oddFonts[0] && 
	$pdf->add_font('face' => 'DejaVuSans', 'type' => 'ttf', 
		       'style' => 'sans-serif', 'width' => 'proportional', 
		       'settings' => { 'encode' => 'utf8' },
		       'file' => { 'roman' => 'DejaVuSans.ttf',
		                   'italic' => 'DejaVuSans-Oblique.ttf',
			           'bold' => 'DejaVuSans-Bold.ttf',
			           'bold-italic' => 'DejaVuSans-BoldOblique.ttf' } )) {
        carp "Something went sideways trying to add DejaVu fonts to list.";
	$oddFonts[0] = 0;
    }
    # add [1] URW PalladioL-Roma T1
    if ($oddFonts[1] && 
        $pdf->add_font('face' => 'Palladio', 'type' => 'type1', 
		       'style' => 'serif', 'width' => 'proportional', 
		       'settings' => { 'encode' => 'iso-8859-1',
		                       'afmfile' => 'URWPalladioL-Roma.afm' },
		       'file' => { 'roman' => 'URWPalladioL-Roma.pfb' } )) {
        carp "Something went sideways trying to add PalladioL font to list.";
	$oddFonts[1] = 0;
    }
    # add [2] codec BDF
    if ($oddFonts[2] && 
        $pdf->add_font('face' => 'Codec', 'type' => 'bdf', 
		       'style' => 'sans-serif', 'width' => 'constant', 
		       'settings' => { 'encode' => 'iso-8859-1' },
		       'file' => { 'roman' => 'codec/codec.bdf' } )) {
        carp "Something went sideways trying to add Codec font to list.";
	$oddFonts[2] = 0;
    }
    # add [3] Adobe Gothic Standard (Chinese) CJK
    if ($oddFonts[3] && 
        $pdf->add_font('face' => 'Chinese', 'type' => 'ttf', 
		       'style' => 'serif', 'width' => 'proportional', 
		       'settings' => { 'encode' => 'utf8' },
		       'file' => { 'roman' => '/Program Files/Adobe/Acrobat DC/Resource/CIDFont/AdobeGothicStd-Light.otf' } )) {
        carp "Something went sideways trying to add AdobeGothicStd font to list.";
	$oddFonts[3] = 0;
    }

    # and load some local font search paths. you will need to update these!
    # currently, these paths are NOT checked/validated upon entry!
    # Windows predefined /WINDOWS/Fonts for TTF
    my @fontpaths;

    # ==== type1 (PS)
    push @fontpaths, "C:/Users/Phil/fonts/T1fonts";  # Windows absolute path with drive letter
    # URW Bookman for MikTex (Windows)
    push @fontpaths, "/Program Files/MikTex 2.9/fonts/type1/urw/bookman";
    # URW Bookman for older versions of MikTex (Windows)
    push @fontpaths, "/Program Files (x86)/MikTex 2.9/fonts/type1/urw/bookman";
    # ==== BDF (bitmapped)
    push @fontpaths, "/Users/Phil/fonts/BDFfonts";
    # ==== CJK (Chinese)
    push @fontpaths, "/Program Files/Adobe/Acrobat DC/Resource/CIDFont";

    while (@fontpaths) {
        my $path = shift @fontpaths;
        if ($pdf->add_font_path($path)) {
            print "Something went wrong with adding path '$path'\n";
        }
    }

    if ($dump) {
        print "=================================================================\n";
        print "=== dump state of FontManager after adding more fonts.\n";
        # note that this prints to STDOUT, not to the PDF
        $pdf->dump_font_tables();
    }

    if ($dump) { print "**** default font\n"; }
    $text->font($pdf->get_font('face'=>'default'), $font_size);
    $space_w = $text->advancewidth(' ');
    @textwords = split / /, "Start with the default face (core Times). The following fonts need to be loaded first.";
    while (@textwords) {
        ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
    }

    my $font;
    if ($oddFonts[0]) { # use [0] DejaVu Sans TTF if available, all 4 variants
        if ($dump) { print "**** DejaVu Sans TTF font\n"; }
        $font=$pdf->get_font('face'=>'DejaVuSans');
	if ($font) {
            $text->font($pdf->get_font('face'=>'DejaVuSans'), $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "Switch to DejaVu Sans, also in";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
	}
        $font=$pdf->get_font('face'=>'DejaVuSans', 'italic'=>1);
	if ($font) {
            $text->font($font, $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "italic,";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
        }
        $font=$pdf->get_font('face'=>'DejaVuSans', 'italic'=>0, 'bold'=>1);
	if ($font) {
            $text->font($font, $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "bold,";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
        }
        $font=$pdf->get_font('face'=>'DejaVuSans', 'italic'=>1);
	if ($font) {
            $text->font($font, $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "and both.";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
        }
        # remember that both italic and bold flags are set
    }

    if ($oddFonts[1]) { # use [1] Palladio Type1 if available
        if ($dump) { print "**** Palladio Type1 font\n"; }
        my $font=$pdf->get_font('face'=>'Palladio', 'italic'=>0, 'bold'=>0);
	if ($font) {
            $text->font($font, $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "Now try out a Type 1 (PostScript) font named PalladioL, from URW.";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
        }
    }

    if ($oddFonts[2]) { # use [2] Codec BDF (bitmapped) if available
        if ($dump) { print "**** Codec BDF (bitmapped) font\n"; }
        my $font=$pdf->get_font('face'=>'Codec');
	if ($font) {
            $text->font($font, $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "This should be ugly: X11 bitmapped Codec font.";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
        }
    }

    if ($oddFonts[3]) { # use [3] Adobe Gothic CJK (Chinese) if available
        if ($dump) { print "**** Adobe Gothic CJK (Chinese) font\n"; }
        my $font=$pdf->get_font('face'=>'Chinese');
	if ($font) {
            $text->font($font, $font_size);
            $space_w = $text->advancewidth(' ');
            @textwords = split / /, "And finally, a sample of CJK (e.g., Chinese) text output: \x{4F7F}\x{7528}\x{9019}\x{500B}\x{FF08}\x{66F4}\x{767D}\x{7684}\x{7259}\x{9F52}\x{FF09}\x{3002}";
            while (@textwords) {
                ($xcur,$y, @textwords) = output($text, $xcur,$y, $x,$x+$colwidth, $space_w, $leading, @textwords);
            }
        }
    }

    if ($dump) {
        print "=================================================================\n";
        print "=== dump state of FontManager after non-core fonts used.\n";
        # note that this prints to STDOUT, not to the PDF
        $pdf->dump_font_tables();
    }
} # non-core samples, likely requiring manual updates

use Data::Dumper;  $Data::Dumper::Sortkeys = 1;
#print Dumper($text);
$pdf->saveas($name);

# output a stream of words on THIS line, returning unused portion.
# for now, not worrying about running off bottom of page!
sub output {
    my ($text, $xcur, $y, $x, $max_x, $space, $leading, @words) = @_;

    $text->translate($xcur,$y); # only need to do at start of string
    while (@words) {
	$word = shift @words;
        $width = $text->advancewidth($word);
        if ($xcur+$width > $max_x) {
            # need to split text. for now, just fit whole words
	    unshift @words, $word;
	    $y -= $leading; # for now, not checking if go off bottom!
	    $xcur = $x; # start of new line
            return ($xcur,$y, @words);
	}

	# there is room for at least one more word on this line
	# we will put down TRAILING space after a word. let's not worry
	# for now whether this space actually exceeds right margin, as
	# it's invisible anyway.
	$text->text($word.' ');
	$xcur += $width+$space;
    }

    # we used up all the words without filling the line? return
    return ($xcur,$y, @words);
}