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
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
|
#! perl -w
use strict;
$|++;
use constant TRUE => (0==0);
use constant FALSE => (0==1);
use Cwd;
use constant DEBUG => 1;
##
## Recherche de fichiers *.ttf dans le répertoire courrant
##
print STDERR "Looking for TTF fonts in the current directory\n" if DEBUG;
opendir(ROOT_DIR, '.') || die "Cannot read cirrent directory: $!";
while(my $file = readdir(ROOT_DIR)){
next unless $file =~ m/\.tt[fc]$/i;
print STDERR " Found font $file\n" if DEBUG;
process_font($file);
}
closedir(ROOT_DIR);
print STDERR "Finished looking for TTF fonts in the current directory\n" if DEBUG;
print STDERR "Look in the various directories that have been created.
You will find sample files (*.tex, which you can compile with latex
resp. lambda, *.dvi, which you may view and convert to Postscript with
xdvi and dvips, resp. oxdvi and odvips, *.ps which you may view with
Ghostview or print.
You will also find a `Makefile' file, that should install
the various files where they belong to (but you had better check
it before using it).\n\n";
##
## Trouve le nom complet de la fonte
##
sub get_font_name {
my $file = shift;
my $result = $file;
$result =~ s/\.tt[fc]$//;
open(AFM, "ttf2afm $file|") || die "Cannot run `ttf2afm $file': $!";
while(<AFM>){
if(m/^FontName\s+(.*)/){
$result = $1;
print STDERR " Font $file has name $result\n" if DEBUG;
last;
}
}
close AFM;
return $result;
}
##
## Crée quelques fichiers
##
sub create_file_from_script {
my ($file, $function, $before, $after) = @_;
print STDERR " Creating file $file\n" if DEBUG;
open(F, '>', $file) || die "cannot open $file for writing: $!";
my $a = &$function;
$a =~ s/$before/$after/g;
print F $a;
close(F);
}
sub create_a_few_files {
my $font = shift;
my @a = ('cyberb', $font);
create_file_from_script("Unicode.sfd", \&print_unicode_sdf, @a);
create_file_from_script("utf8_cjk.tex", \&print_utf8_cjk_tex, @a);
create_file_from_script("c70$font.fd", \&print_c70song_fd, @a);
create_file_from_script("utf8_omega.tex", \&print_utf8_omega_tex, @a);
create_file_from_script("Makefile", \&print_makefile, @a);
}
##
## Traitement d'un fichier TTF
##
sub process_font {
my $file = shift;
my $basename = $file;
$basename =~ s/\.ttf$//i;
my $font = get_font_name($file);
my $latex_font_name = $font;
$latex_font_name =~ s/[^a-zA-Z0-9]//g;
$latex_font_name =~ y/A-Z/a-z/;
print STDERR " Processing font $font ($latex_font_name) in file $file\n"
if DEBUG;
my $rep = "0_tmp_$basename";
mkdir $rep || die "Cannot mkdir $rep: $!";
my $olddir = cwd;
chdir $rep || die "Cannot chdir to $rep: $!";
symlink("../$file", "./$file");
create_a_few_files($latex_font_name);
print STDERR " Creating TeX metrics *.tfm with ttf2tfm\n" if DEBUG;
open(TTF2TFM, "ttf2tfm $file $latex_font_name\@Unicode\@|") ||
die "Cannot run ttf2tfm: $!";
my $last;
while(<TTF2TFM>){
$last = $_;
}
close TTF2TFM;
print STDERR " Adding the following line to ttfonts.map\n" if DEBUG;
print STDERR " $last" if DEBUG;
open(TTFONTS_MAP, '>', "ttfonts.map") ||
die "Cannot open ttfonts.map for writing: $!";
print TTFONTS_MAP $last;
close TTFONTS_MAP;
print STDERR " Precompiling the bitmaps at 10 and 12 points
These are the files, containing the actual picture of the
characters, used by dvips and xdvi.
They are automatically created by dvips or xdvi when
needed, but as it takes some time, it is better to precompute
them. You should go and get some coffee.\n" if DEBUG;
opendir(DIR, ".") || die "Cannot open current directory: $!";
while(my $f = readdir(DIR)){
next unless $f =~ s/\.tfm$//;
system("ttf2pk", "-q", $f, "720");
system("ttf2pk", "-q", $f, "600");
}
closedir(DIR);
print STDERR " Finished precompiling the bitmaps\n" if DEBUG;
print STDERR " Compiling a sample file with LaTeX+CJK
You should be able to view the result with
xdvi utf8_cjk.dvi
or
gv utf8_cjk.ps
The code is in the utf8_cjk.tex: to use LaTeX with CJK,
you just have to adapt it.\n" if DEBUG;
system(qw/latex --interaction=batchmode utf8_cjk.tex/);
system(qw/dvips -E -o utf8_cjk.ps utf8_cjk.dvi/);
print STDERR " Finished compiling a sample file with LaTeX+CJK\n" if DEBUG;
##
## Omega
##
print STDERR " So far, you may use the $font font with LaTeX+CJK\n" if DEBUG;
print STDERR " We shall now install the font for use under Omega\n" if DEBUG;
print STDERR " Making *.pl files from *.tfm files.
These file contain exactly the same thing, but
the former is human-readable\n" if DEBUG;
opendir(DIR, ".");
while(my $f = readdir(DIR)){
next unless $f =~ s/\.tfm$//;
system("tftopl", "$f.tfm", "$f.pl");
}
closedir(DIR);
print STDERR " Creating *.ovp file\n" if DEBUG;
my $data = "";
my $def = "";
my $head = "(VTITLE '$font' Omega font)
(OFMLEVEL H 1)
(FAMILY om". substr($latex_font_name, 0, 16) .")
(FACE F MRR)
(SEVENBITSAFEFLAG TRUE)";
my $head_done = FALSE;
# Lecture des 255 fichiers
# $i : numéro de la sous-fonte (il y a des trous dans cette manière de compter)
# $n : idem, sans trous
my $n = 0;
my $n_hex = sprintf("%02x", $n);
for(my $i=0; $i<255; $i++){
# On essaye d'ouvrir la sous-fonte
my $i_hex = sprintf("%02x", $i);
unless( open(PL, '<', "$latex_font_name$i_hex.pl") ){
print STDERR " skipping $latex_font_name$i_hex.pl: $!\n"
if DEBUG;
next;
}
local $/;
my $pl = <PL>;
# Si le fichier est là, on l'indique
$def .= "(MAPFONT D $n
(FONTNAME $latex_font_name$i_hex)
(FONTAT R 1.0)
(FONTDSIZE R 10.0)
)\n";
# Si c'est la première fois, on termine de construire l'en-tête
unless($head_done){
if( $pl =~ m/^(\(CODINGSCHEME.*?\))/m ){
my $a = "$1\n";
if( $pl =~ m/^(\(DESIGNSIZE.*?\))/m ){
$a .= "$1\n";
if( $pl =~ m/^(\(FONTDIMEN.*?^\s*\))/sm ){
$a .= "$1\n";
$head_done = TRUE;
$head .= $a;
}
}
}
}
$data .= "(COMMENT Begin om$latex_font_name$i_hex)\n";
# On regarde les caractères un par un
while( $pl =~ s/^\(CHARACTER ([OC]) ([^\s]+)(.*?)^\s*\)//sm ){
my($type, $value, $parameters) = ($1, $2, $3);
# Quel est le numéro (hexadécimal, unicode) du caractère ?
my $decimal;
if( $type eq "O" ){ $decimal = oct($value) }
else{ $decimal = ord($value) }
my $octal = sprintf("%o", $decimal);
my $hex = $i_hex . sprintf("%02x", $decimal);
$data .= "(CHARACTER H $hex$parameters (MAP
(SELECTFONT D $n)
(SETCHAR $type $value)
)
)\n";
}
$n++;
$n_hex = sprintf("%02x", $n);
}
open(OVP, '>', "om$latex_font_name.ovp") ||
die "Cannot open om$latex_font_name.ovp for writing";
print OVP $head;
print OVP $def;
print OVP $data;
close OVP;
print STDERR " Creating om$latex_font_name.ovf from om$latex_font_name.ovp\n" if DEBUG;
system("ovp2ovf om$latex_font_name");
print STDERR " Compiling sample file\n" if DEBUG;
system(qw/lambda utf8_omega.tex/);
system(qw/odvips -o utf8_omega.ps utf8_omega.dvi/);
chdir $olddir || die "Cannot chdir back to $olddir";
print STDERR " Finished processing font $font in file $file\n" if DEBUG;
print STDERR " There is a `Makefile' file in the directory.
You should check it if you want to use or install the font.\n" if DEBUG;
}
######################################################################
##
## Fichiers
##
sub print_utf8_cjk_tex {
'\documentclass[12pt]{article}
\usepackage{CJK}
\usepackage[T1]{fontenc}
% we want the Unicode font for normal text also
\DeclareFontFamily{T1}{cyberb}{}
\DeclareFontShape{T1}{cyberb}{m}{n}{<-> cyberb00}{}
\renewcommand\rmdefault{cyberb}
\pagestyle{empty}
\begin{document}
\begin{CJK}{UTF8}{cyberb}
Du texte accentué, en français.
これは日本語でのサンプル文章です。
\end{CJK}
\end{document}';
}
sub print_utf8_omega_tex {
'\ocp\TexUTF=inutf8
\InputTranslation currentfile \TexUTF
\documentclass[12pt]{article}
\usepackage[T1]{fontenc}
\DeclareFontFamily{T1}{cyberb}{}
\DeclareFontShape{T1}{cyberb}{m}{n}{<-> omcyberb}{}
\def\cyberb{\fontfamily{cyberb}\selectfont}
\pagestyle{empty}
\begin{document}
Du texte accentué, en français.
\begin{cyberb}
これは日本語でのサンプル文章です。
\end{cyberb}
\end{document}';
}
sub print_unicode_sdf {
'# Unicode.sfd
#
# subfont numbers for Unicode encoding and its corresponding code ranges
# to be used with the CJK package for LaTeX.
00 0x0_0xFF
01 0x100_0x1FF
02 0x200_0x2FF
03 0x300_0x3FF
04 0x400_0x4FF
05 0x500_0x5FF
06 0x600_0x6FF
07 0x700_0x7FF
08 0x800_0x8FF
09 0x900_0x9FF
0a 0xA00_0xAFF
0b 0xB00_0xBFF
0c 0xC00_0xCFF
0d 0xD00_0xDFF
0e 0xE00_0xEFF
0f 0xF00_0xFFF
10 0x1000_0x10FF
11 0x1100_0x11FF
12 0x1200_0x12FF
13 0x1300_0x13FF
14 0x1400_0x14FF
15 0x1500_0x15FF
16 0x1600_0x16FF
17 0x1700_0x17FF
18 0x1800_0x18FF
19 0x1900_0x19FF
1a 0x1A00_0x1AFF
1b 0x1B00_0x1BFF
1c 0x1C00_0x1CFF
1d 0x1D00_0x1DFF
1e 0x1E00_0x1EFF
1f 0x1F00_0x1FFF
20 0x2000_0x20FF
21 0x2100_0x21FF
22 0x2200_0x22FF
23 0x2300_0x23FF
24 0x2400_0x24FF
25 0x2500_0x25FF
26 0x2600_0x26FF
27 0x2700_0x27FF
28 0x2800_0x28FF
29 0x2900_0x29FF
2a 0x2A00_0x2AFF
2b 0x2B00_0x2BFF
2c 0x2C00_0x2CFF
2d 0x2D00_0x2DFF
2e 0x2E00_0x2EFF
2f 0x2F00_0x2FFF
30 0x3000_0x30FF
31 0x3100_0x31FF
32 0x3200_0x32FF
33 0x3300_0x33FF
34 0x3400_0x34FF
35 0x3500_0x35FF
36 0x3600_0x36FF
37 0x3700_0x37FF
38 0x3800_0x38FF
39 0x3900_0x39FF
3a 0x3A00_0x3AFF
3b 0x3B00_0x3BFF
3c 0x3C00_0x3CFF
3d 0x3D00_0x3DFF
3e 0x3E00_0x3EFF
3f 0x3F00_0x3FFF
40 0x4000_0x40FF
41 0x4100_0x41FF
42 0x4200_0x42FF
43 0x4300_0x43FF
44 0x4400_0x44FF
45 0x4500_0x45FF
46 0x4600_0x46FF
47 0x4700_0x47FF
48 0x4800_0x48FF
49 0x4900_0x49FF
4a 0x4A00_0x4AFF
4b 0x4B00_0x4BFF
4c 0x4C00_0x4CFF
4d 0x4D00_0x4DFF
4e 0x4E00_0x4EFF
4f 0x4F00_0x4FFF
50 0x5000_0x50FF
51 0x5100_0x51FF
52 0x5200_0x52FF
53 0x5300_0x53FF
54 0x5400_0x54FF
55 0x5500_0x55FF
56 0x5600_0x56FF
57 0x5700_0x57FF
58 0x5800_0x58FF
59 0x5900_0x59FF
5a 0x5A00_0x5AFF
5b 0x5B00_0x5BFF
5c 0x5C00_0x5CFF
5d 0x5D00_0x5DFF
5e 0x5E00_0x5EFF
5f 0x5F00_0x5FFF
60 0x6000_0x60FF
61 0x6100_0x61FF
62 0x6200_0x62FF
63 0x6300_0x63FF
64 0x6400_0x64FF
65 0x6500_0x65FF
66 0x6600_0x66FF
67 0x6700_0x67FF
68 0x6800_0x68FF
69 0x6900_0x69FF
6a 0x6A00_0x6AFF
6b 0x6B00_0x6BFF
6c 0x6C00_0x6CFF
6d 0x6D00_0x6DFF
6e 0x6E00_0x6EFF
6f 0x6F00_0x6FFF
70 0x7000_0x70FF
71 0x7100_0x71FF
72 0x7200_0x72FF
73 0x7300_0x73FF
74 0x7400_0x74FF
75 0x7500_0x75FF
76 0x7600_0x76FF
77 0x7700_0x77FF
78 0x7800_0x78FF
79 0x7900_0x79FF
7a 0x7A00_0x7AFF
7b 0x7B00_0x7BFF
7c 0x7C00_0x7CFF
7d 0x7D00_0x7DFF
7e 0x7E00_0x7EFF
7f 0x7F00_0x7FFF
80 0x8000_0x80FF
81 0x8100_0x81FF
82 0x8200_0x82FF
83 0x8300_0x83FF
84 0x8400_0x84FF
85 0x8500_0x85FF
86 0x8600_0x86FF
87 0x8700_0x87FF
88 0x8800_0x88FF
89 0x8900_0x89FF
8a 0x8A00_0x8AFF
8b 0x8B00_0x8BFF
8c 0x8C00_0x8CFF
8d 0x8D00_0x8DFF
8e 0x8E00_0x8EFF
8f 0x8F00_0x8FFF
90 0x9000_0x90FF
91 0x9100_0x91FF
92 0x9200_0x92FF
93 0x9300_0x93FF
94 0x9400_0x94FF
95 0x9500_0x95FF
96 0x9600_0x96FF
97 0x9700_0x97FF
98 0x9800_0x98FF
99 0x9900_0x99FF
9a 0x9A00_0x9AFF
9b 0x9B00_0x9BFF
9c 0x9C00_0x9CFF
9d 0x9D00_0x9DFF
9e 0x9E00_0x9EFF
9f 0x9F00_0x9FFF
a0 0xA000_0xA0FF
a1 0xA100_0xA1FF
a2 0xA200_0xA2FF
a3 0xA300_0xA3FF
a4 0xA400_0xA4FF
a5 0xA500_0xA5FF
a6 0xA600_0xA6FF
a7 0xA700_0xA7FF
a8 0xA800_0xA8FF
a9 0xA900_0xA9FF
aa 0xAA00_0xAAFF
ab 0xAB00_0xABFF
ac 0xAC00_0xACFF
ad 0xAD00_0xADFF
ae 0xAE00_0xAEFF
af 0xAF00_0xAFFF
b0 0xB000_0xB0FF
b1 0xB100_0xB1FF
b2 0xB200_0xB2FF
b3 0xB300_0xB3FF
b4 0xB400_0xB4FF
b5 0xB500_0xB5FF
b6 0xB600_0xB6FF
b7 0xB700_0xB7FF
b8 0xB800_0xB8FF
b9 0xB900_0xB9FF
ba 0xBA00_0xBAFF
bb 0xBB00_0xBBFF
bc 0xBC00_0xBCFF
bd 0xBD00_0xBDFF
be 0xBE00_0xBEFF
bf 0xBF00_0xBFFF
c0 0xC000_0xC0FF
c1 0xC100_0xC1FF
c2 0xC200_0xC2FF
c3 0xC300_0xC3FF
c4 0xC400_0xC4FF
c5 0xC500_0xC5FF
c6 0xC600_0xC6FF
c7 0xC700_0xC7FF
c8 0xC800_0xC8FF
c9 0xC900_0xC9FF
ca 0xCA00_0xCAFF
cb 0xCB00_0xCBFF
cc 0xCC00_0xCCFF
cd 0xCD00_0xCDFF
ce 0xCE00_0xCEFF
cf 0xCF00_0xCFFF
d0 0xD000_0xD0FF
d1 0xD100_0xD1FF
d2 0xD200_0xD2FF
d3 0xD300_0xD3FF
d4 0xD400_0xD4FF
d5 0xD500_0xD5FF
d6 0xD600_0xD6FF
d7 0xD700_0xD7FF
# Surrogates
#
# d8 0xD800_0xD8FF
# d9 0xD900_0xD9FF
# da 0xDA00_0xDAFF
# db 0xDB00_0xDBFF
dc 0xDC00_0xDCFF
dd 0xDD00_0xDDFF
de 0xDE00_0xDEFF
df 0xDF00_0xDFFF
e0 0xE000_0xE0FF
e1 0xE100_0xE1FF
e2 0xE200_0xE2FF
e3 0xE300_0xE3FF
e4 0xE400_0xE4FF
e5 0xE500_0xE5FF
e6 0xE600_0xE6FF
e7 0xE700_0xE7FF
e8 0xE800_0xE8FF
e9 0xE900_0xE9FF
ea 0xEA00_0xEAFF
eb 0xEB00_0xEBFF
ec 0xEC00_0xECFF
ed 0xED00_0xEDFF
ee 0xEE00_0xEEFF
ef 0xEF00_0xEFFF
f0 0xF000_0xF0FF
f1 0xF100_0xF1FF
f2 0xF200_0xF2FF
f3 0xF300_0xF3FF
f4 0xF400_0xF4FF
f5 0xF500_0xF5FF
f6 0xF600_0xF6FF
f7 0xF700_0xF7FF
f8 0xF800_0xF8FF
f9 0xF900_0xF9FF
fa 0xFA00_0xFAFF
fb 0xFB00_0xFBFF
fc 0xFC00_0xFCFF
fd 0xFD00_0xFDFF
fe 0xFE00_0xFEFF
ff 0xFF00_0xFFFF
# eof';
}
sub print_c70song_fd {
'\ProvidesFile{c70cyberb.fd}
% character set: Unicode U+0080 - U+FFFD
% font encoding: Unicode
\DeclareFontFamily{C70}{cyberb}{\hyphenchar \font\m@ne}
\DeclareFontShape{C70}{cyberb}{m}{n}{<-> CJK * cyberb}{}
\DeclareFontShape{C70}{cyberb}{bx}{n}{<-> CJKb * cyberb}{\CJKbold}
\endinput';
}
sub print_makefile {
'all:
latex utf8_cjk.tex
-xdvi utf8_cjk.dvi
dvips -E -o utf8_cjk.ps utf8_cjk.dvi
gv utf8_cjk.ps
lambda utf8_omega.tex
-oxdvi utf8_omega.dvi
odvips -o utf8_omega.ps utf8_omega.dvi
gv utf8_omega.ps
install:
TEXMF=/usr/local/lib/texmf
mkdir $TEXMF/fonts/tfm/font_install_unicode
cp *.tfm $TEXMF/fonts/tfm/font_install_unicode/
mkdir $TEXMF/tex/generic/font_install_unicode
cp *.fd $TEXMF/tex/generic/font_install_unicode/
cp -H *.ttf $TEXMF/tex/fonts/truetype/
cp ttfonts.map $TEXMF/tex/fonts/truetype/cyberb.map
cat ttfonts.map >> $TEXMF/tex/fonts/truetype/ttfonts.map
mkdir $TEXMF/fonts/ofm/public/font_install_unicode
cp *.ofm $TEXMF/fonts/ofm/public/font_install_unicode/
mkdir $TEXMF/fonts/ovp/public/font_install_unicode
cp *.ovp $TEXMF/fonts/ovp/public/font_install_unicode/
';
}
|