1 /************************************************************************/
2 /* */
3 /* Utility routines to build font configuration. */
4 /* */
5 /************************************************************************/
6
7 # include "utilPsConfig.h"
8
9 # include <stdio.h>
10 # include <stdlib.h>
11 # include <string.h>
12 # include <ctype.h>
13
14 # include <locale.h>
15
16 # include <reg.h>
17
18 # include <sioFileio.h>
19 # include <sioPfb.h>
20 # include <sioPipe.h>
21 # include <appSystem.h>
22 # include <utilMemoryBuffer.h>
23 # include <utilMemoryBufferPrintf.h>
24 # include "psTtf.h"
25 # include "psBuildConfigFiles.h"
26 # include "psReadWriteFontInfo.h"
27
28 # include <appDebugon.h>
29
30 # ifdef __VMS
31 static const char * const afmExtension= "AFM";
32 static const char * const pfbExtension= "PFB";
33 static const char * const pfaExtension= "PFA";
34 # else
35 static const char * const afmExtension= "afm";
36 static const char * const pfbExtension= "pfb";
37 static const char * const pfaExtension= "pfa";
38 # endif
39 static const char * const ttfExtension= "ttf";
40 static const char * const TTFExtension= "TTF";
41
42 static const char * PS_FontNamePattern=
43 "^/FontName[ \t]*/([^ \t]*)[ \t][ \t]*def";
44
45 static const char * PS_LocalAfmDir= "localfonts";
46
47 /************************************************************************/
48
49 typedef struct AfmDirBuilder
50 {
51 MemoryBuffer adbAfmDirectory;
52 MemoryBuffer adbAfmCommand;
53 MemoryBuffer adbCwd;
54 regProg * adbFontNameProg;
55 /**
56 * Owned by the caller. To be
57 * augmented here.
58 */
59 PostScriptFontList * adbPostScriptFontList;
60 int adbAfmFlags;
61 } AfmDirBuilder;
62
psInitAfmDirBuilder(AfmDirBuilder * adb)63 static void psInitAfmDirBuilder( AfmDirBuilder * adb )
64 {
65 utilInitMemoryBuffer( &(adb->adbAfmDirectory) );
66 utilInitMemoryBuffer( &(adb->adbAfmCommand) );
67 utilInitMemoryBuffer( &(adb->adbCwd) );
68 adb->adbFontNameProg= (regProg *)0;
69 adb->adbPostScriptFontList= (PostScriptFontList *)0;
70 adb->adbAfmFlags= 0;
71 }
72
psCleanAfmDirBuilder(AfmDirBuilder * adb)73 static void psCleanAfmDirBuilder( AfmDirBuilder * adb )
74 {
75 utilCleanMemoryBuffer( &(adb->adbAfmDirectory) );
76 utilCleanMemoryBuffer( &(adb->adbAfmCommand) );
77 utilCleanMemoryBuffer( &(adb->adbCwd) );
78
79 if ( adb->adbFontNameProg )
80 { regFree( adb->adbFontNameProg ); }
81 }
82
psStartAfmDirBuilder(AfmDirBuilder * adb,PostScriptFontList * psfl,int ignoreKerning,const MemoryBuffer * afmDirectory,const MemoryBuffer * psDirectory)83 static int psStartAfmDirBuilder( AfmDirBuilder * adb,
84 PostScriptFontList * psfl,
85 int ignoreKerning,
86 const MemoryBuffer * afmDirectory,
87 const MemoryBuffer * psDirectory )
88 {
89 int rval= 0;
90 const int relativeIsFile= 0;
91 const int options= 0;
92
93 const char * afmBase= "gs -sthefont=%s -q %s/gsfontmetrics.ps -c quit";
94
95 MemoryBuffer local;
96
97 utilInitMemoryBuffer( &local );
98
99 adb->adbPostScriptFontList= psfl;
100
101 if ( ignoreKerning )
102 { adb->adbAfmFlags |= PSflagIGNORE_KERNING; }
103
104 if ( utilMemoryBufferSetString( &local, PS_LocalAfmDir ) )
105 { LDEB(1); rval= -1; goto ready; }
106
107 if ( afmDirectory )
108 {
109 if ( appAbsoluteName( &(adb->adbAfmDirectory),
110 &local, relativeIsFile, afmDirectory ) < 0 )
111 { SDEB(PS_LocalAfmDir); rval= -1; goto ready; }
112 }
113
114 adb->adbFontNameProg= regCompile( PS_FontNamePattern, options );
115 if ( ! adb->adbFontNameProg )
116 { XDEB(adb->adbFontNameProg); rval= -1; goto ready; }
117
118 if ( psDirectory )
119 {
120 utilMemoryBufferPrintf( &(adb->adbAfmCommand), afmBase, "%s",
121 utilMemoryBufferGetString( psDirectory ) );
122 }
123
124 if ( appCurrentDirectory( &(adb->adbCwd) ) < 0 )
125 { LDEB(1); rval= -1; goto ready; }
126
127 ready:
128
129 utilCleanMemoryBuffer( &local );
130
131 return rval;
132 }
133
psGetNameExt(MemoryBuffer * file,MemoryBuffer * extension,const AfmDirBuilder * adb,const char * fontFileName)134 static int psGetNameExt( MemoryBuffer * file,
135 MemoryBuffer * extension,
136 const AfmDirBuilder * adb,
137 const char * fontFileName )
138 {
139 int rval= 0;
140 MemoryBuffer filename;
141
142 utilInitMemoryBuffer( &filename );
143
144 if ( utilMemoryBufferSetString( &filename, fontFileName ) )
145 { SDEB(fontFileName); rval= -1; goto ready; }
146
147 if ( appFileGetFileExtension( extension, &filename ) < 0 )
148 { LDEB(1); rval= -1; goto ready; }
149 if ( utilMemoryBufferIsEmpty( extension ) )
150 { rval= -1; rval= 1; goto ready; }
151
152 if ( ! appFileNameIsAbsolute( fontFileName ) )
153 {
154 int l;
155 const int relativeIsFile= 0;
156
157 l= appAbsoluteName( file, &filename, relativeIsFile, &(adb->adbCwd) );
158 if ( l < 0 )
159 { LDEB(l); rval= -1; rval= 1; goto ready; }
160 }
161 else{
162 if ( utilCopyMemoryBuffer( file, &filename ) )
163 { LDEB(1); }
164 }
165
166 ready:
167
168 utilCleanMemoryBuffer( &filename );
169
170 return rval;
171 }
172
173 /************************************************************************/
174 /* */
175 /* Find the font name for a Postcript type 1 font. */
176 /* */
177 /************************************************************************/
178
psFontNameFromPf(MemoryBuffer * fontname,SimpleInputStream * sisFont,regProg * prog)179 static int psFontNameFromPf( MemoryBuffer * fontname,
180 SimpleInputStream * sisFont,
181 regProg * prog )
182 {
183 int rval= 1;
184 char scratch[550+1];
185
186 while( sioInGetString( scratch, sizeof(scratch)-1, sisFont ) )
187 {
188 ExpressionMatch em;
189
190 scratch[sizeof(scratch)-1]= '\0';
191
192 if ( regFindLeftToRight( &em, prog, scratch, 0, strlen( scratch ) ) )
193 {
194 int from;
195 int past;
196
197 regGetMatch( &from, &past, &em, 0 );
198
199 if ( utilMemoryBufferSetBytes( fontname,
200 (unsigned char *)scratch+ from, past- from ) )
201 { LLDEB(past,from); rval= -1; break; }
202
203 rval= 0; break;
204 }
205 }
206
207 if ( rval )
208 { LDEB(rval); }
209
210 return rval;
211 }
212
psFillAfiForPf(SimpleInputStream * sisFont,const AfmDirBuilder * adb,const MemoryBuffer * filename)213 static AfmFontInfo * psFillAfiForPf(
214 SimpleInputStream * sisFont,
215 const AfmDirBuilder * adb,
216 const MemoryBuffer * filename )
217 {
218 int rval= 0;
219
220 MemoryBuffer fontname;
221 MemoryBuffer command;
222
223 SimpleInputStream * sisCmd= (SimpleInputStream *)0;
224 AfmFontInfo * afi= (AfmFontInfo *)0;
225
226 utilInitMemoryBuffer( &fontname );
227 utilInitMemoryBuffer( &command );
228
229 afi= (AfmFontInfo *)malloc( sizeof(AfmFontInfo) );
230 if ( ! afi )
231 { XDEB(afi); rval= -1; goto ready; }
232 psInitAfmFontInfo( afi );
233
234 if ( psFontNameFromPf( &fontname, sisFont, adb->adbFontNameProg ) )
235 { LDEB(1); rval= -1; goto ready; }
236
237 utilMemoryBufferPrintf( &command,
238 utilMemoryBufferGetString( &(adb->adbAfmCommand) ),
239 utilMemoryBufferGetString( &fontname ) );
240
241 sisCmd= sioInPipeOpen( &command );
242 if ( ! sisCmd )
243 {
244 SXDEB(utilMemoryBufferGetString(&command),sisCmd);
245 rval= -1; goto ready;
246 }
247
248 rval= psAfmReadAfm( sisCmd, afi, adb->adbAfmFlags );
249 if ( rval )
250 {
251 SLDEB(utilMemoryBufferGetString(&command),rval); rval= -1;
252 rval= -1; goto ready;
253 }
254
255 if ( utilCopyMemoryBuffer( &(afi->afiFontFileName), filename ) )
256 { LDEB(1); rval= -1; goto ready; }
257
258 if ( psGetUnicodesFromGlyphNames( afi ) )
259 { SDEB(afi->afiFullName); }
260 if ( psGetAlternateGlyphs( afi ) )
261 { SDEB(afi->afiFullName); }
262 if ( psResolveFallbackGlyph( afi ) )
263 { SDEB(afi->afiFullName); }
264
265 ready:
266
267 if ( rval && afi )
268 {
269 psFreeAfmFontInfo( afi );
270 afi= (AfmFontInfo *)0;
271 }
272
273 utilCleanMemoryBuffer( &fontname );
274 utilCleanMemoryBuffer( &command );
275
276 if ( sisCmd )
277 { sioInClose( sisCmd ); }
278
279 return afi;
280 }
281
psFontNameFromPfa(MemoryBuffer * fontname,regProg * prog,const MemoryBuffer * filename)282 static int psFontNameFromPfa( MemoryBuffer * fontname,
283 regProg * prog,
284 const MemoryBuffer * filename )
285 {
286 int rval= 0;
287 SimpleInputStream * sisFile= (SimpleInputStream *)0;
288
289 sisFile= sioInFileioOpen( filename );
290 if ( ! sisFile )
291 { XDEB(sisFile); rval= -1; goto ready; }
292
293 rval= psFontNameFromPf( fontname, sisFile, prog );
294 if ( rval )
295 { LDEB(rval); }
296
297 ready:
298
299 if ( sisFile )
300 { sioInClose( sisFile ); }
301
302 return rval;
303 }
304
psFillAfiForPfa(const AfmDirBuilder * adb,const MemoryBuffer * filename)305 static AfmFontInfo * psFillAfiForPfa( const AfmDirBuilder * adb,
306 const MemoryBuffer * filename )
307 {
308 AfmFontInfo * afi= (AfmFontInfo *)0;
309 SimpleInputStream * sisFile= (SimpleInputStream *)0;
310
311 sisFile= sioInFileioOpen( filename );
312 if ( ! sisFile )
313 { XDEB(sisFile); goto ready; }
314
315 afi= psFillAfiForPf( sisFile, adb, filename );
316 if ( ! afi )
317 { XDEB(afi); }
318
319 ready:
320
321 if ( sisFile )
322 { sioInClose( sisFile ); }
323
324 return afi;
325 }
326
psFontNameFromPfb(MemoryBuffer * fontname,regProg * prog,const MemoryBuffer * filename)327 static int psFontNameFromPfb( MemoryBuffer * fontname,
328 regProg * prog,
329 const MemoryBuffer * filename )
330 {
331 int rval= 0;
332 SimpleInputStream * sisFile= (SimpleInputStream *)0;
333 SimpleInputStream * sisFont= (SimpleInputStream *)0;
334
335 sisFile= sioInFileioOpen( filename );
336 if ( ! sisFile )
337 { XDEB(sisFile); goto ready; }
338
339 sisFont= sioInPfbOpen( sisFile );
340 if ( ! sisFont )
341 { XDEB(sisFont); goto ready; }
342
343 rval= psFontNameFromPf( fontname, sisFont, prog );
344 if ( rval )
345 { LDEB(rval); }
346
347 ready:
348
349 if ( sisFont )
350 { sioInClose( sisFont ); }
351 if ( sisFile )
352 { sioInClose( sisFile ); }
353
354 return rval;
355 }
356
psFillAfiForPfb(const AfmDirBuilder * adb,const MemoryBuffer * filename)357 static AfmFontInfo * psFillAfiForPfb( const AfmDirBuilder * adb,
358 const MemoryBuffer * filename )
359 {
360 AfmFontInfo * afi= (AfmFontInfo *)0;
361 SimpleInputStream * sisFile= (SimpleInputStream *)0;
362 SimpleInputStream * sisFont= (SimpleInputStream *)0;
363
364 sisFile= sioInFileioOpen( filename );
365 if ( ! sisFile )
366 { XDEB(sisFile); goto ready; }
367
368 sisFont= sioInPfbOpen( sisFile );
369 if ( ! sisFont )
370 { XDEB(sisFont); goto ready; }
371
372 afi= psFillAfiForPf( sisFont, adb, filename );
373 if ( ! afi )
374 { XDEB(afi); }
375
376 ready:
377 if ( sisFont )
378 { sioInClose( sisFont ); }
379 if ( sisFile )
380 { sioInClose( sisFile ); }
381
382 return afi;
383 }
384
385 /************************************************************************/
386 /* */
387 /* Find the font name for a TTF file. This is an expensive way. That */
388 /* is not a problem as we rarely do this. */
389 /* */
390 /************************************************************************/
391
psFillAfiForTtf(const MemoryBuffer * filename)392 static AfmFontInfo * psFillAfiForTtf( const MemoryBuffer * filename )
393 {
394 int rval= 0;
395 AfmFontInfo * afi= (AfmFontInfo *)0;
396 SimpleInputStream * sisFile= (SimpleInputStream *)0;
397
398 afi= (AfmFontInfo *)malloc( sizeof(AfmFontInfo) );
399 if ( ! afi )
400 { XDEB(afi); rval= -1; goto ready; }
401 psInitAfmFontInfo( afi );
402
403 sisFile= sioInFileioOpen( filename );
404 if ( ! sisFile )
405 { XDEB(sisFile); rval= -1; goto ready; }
406
407 if ( psTtfToAfi( afi, filename, sisFile ) )
408 { LDEB(1); rval= -1; goto ready; }
409
410 ready:
411
412 if ( rval && afi )
413 {
414 psFreeAfmFontInfo( afi );
415 afi= (AfmFontInfo *)0;
416 }
417
418 if ( sisFile )
419 { sioInClose( sisFile ); }
420
421 return afi;
422 }
423
psFillAfiForAfm(int afmFlags,const MemoryBuffer * filename)424 static AfmFontInfo * psFillAfiForAfm( int afmFlags,
425 const MemoryBuffer * filename )
426 {
427 int rval= 0;
428 AfmFontInfo * afi= (AfmFontInfo *)0;
429 SimpleInputStream * sisAfm= (SimpleInputStream *)0;
430
431 afi= (AfmFontInfo *)malloc( sizeof(AfmFontInfo) );
432 if ( ! afi )
433 { XDEB(afi); rval= -1; goto ready; }
434 psInitAfmFontInfo( afi );
435
436 sisAfm= sioInFileioOpen( filename );
437 if ( ! sisAfm )
438 { XDEB(sisAfm); rval= -1; goto ready; }
439
440 if ( psAfmReadAfm( sisAfm, afi, afmFlags ) )
441 { SDEB(utilMemoryBufferGetString(filename)); rval= -1; goto ready; }
442
443 ready:
444
445 if ( rval && afi )
446 {
447 psFreeAfmFontInfo( afi );
448 afi= (AfmFontInfo *)0;
449 }
450
451 if ( sisAfm )
452 { sioInClose( sisAfm ); }
453
454 return afi;
455 }
456
psFontNameFromTtf(MemoryBuffer * fontname,const MemoryBuffer * filename)457 static int psFontNameFromTtf( MemoryBuffer * fontname,
458 const MemoryBuffer * filename )
459 {
460 int rval= 0;
461 AfmFontInfo * afi= (AfmFontInfo*)0;
462
463 afi= psFillAfiForTtf( filename );
464 if ( ! afi )
465 { XDEB(afi); goto ready; }
466
467 if ( utilMemoryBufferSetString( fontname, afi->afiFontName ) )
468 { LDEB(1); rval= -1; }
469
470 ready:
471
472 if ( afi )
473 { psFreeAfmFontInfo( afi ); }
474
475 return rval;
476 }
477
psFontNameFromAfm(MemoryBuffer * fontname,MemoryBuffer * filename)478 static int psFontNameFromAfm( MemoryBuffer * fontname,
479 MemoryBuffer * filename )
480 {
481 int rval= 0;
482 AfmFontInfo * afi= (AfmFontInfo*)0;
483
484 const int afmFlags= PSflagDEFER_METRICS | PSflagIGNORE_KERNING;
485
486 afi= psFillAfiForAfm( afmFlags, filename );
487 if ( ! afi )
488 { SDEB(utilMemoryBufferGetString(filename)); rval= -1; goto ready; }
489
490 if ( utilMemoryBufferSetString( fontname, afi->afiFontName ) )
491 { LDEB(1); rval= -1; }
492
493 if ( utilCopyMemoryBuffer( filename, &(afi->afiFontFileName) ) )
494 { LDEB(1); rval= -1; }
495
496 ready:
497
498 if ( afi )
499 { psFreeAfmFontInfo( afi ); }
500
501 return rval;
502 }
503
504 /************************************************************************/
505 /* */
506 /* Scan a list of files and issue GhostScript compatible Fontmap lines */
507 /* that can be added to a GhostScript Fontmap file. The purpose of */
508 /* this function is to make the fonts known to GhostScript. This means */
509 /* that we cannot use GhostScript yet. */
510 /* */
511 /************************************************************************/
512
psFontmapForFiles(SimpleOutputStream * sosOut,int fileCount,const char * const * fileNames)513 int psFontmapForFiles( SimpleOutputStream * sosOut,
514 int fileCount,
515 const char * const * fileNames )
516 {
517 int rval= 0;
518 int f;
519
520 const int ignoreKerning= 1;
521
522 AfmDirBuilder adb;
523 MemoryBuffer file;
524 MemoryBuffer extension;
525 MemoryBuffer fontname;
526
527 utilInitMemoryBuffer( &file );
528 utilInitMemoryBuffer( &extension );
529 utilInitMemoryBuffer( &fontname );
530
531 psInitAfmDirBuilder( &adb );
532
533 if ( psStartAfmDirBuilder( &adb, (PostScriptFontList *)0, ignoreKerning,
534 (const MemoryBuffer *)0,
535 (const MemoryBuffer *)0 ) )
536 { LDEB(1); rval= -1; goto ready; }
537
538 for ( f= 0; f < fileCount; f++ )
539 {
540 int ret;
541
542 utilEmptyMemoryBuffer( &fontname );
543
544 ret= psGetNameExt( &file, &extension, &adb, fileNames[f] );
545 if ( ret )
546 { LDEB(ret); rval= -1; goto ready; }
547
548 if ( appFileGetFileExtension( &extension, &file ) < 0 )
549 { LDEB(1); rval= -1; goto ready; }
550 if ( utilMemoryBufferIsEmpty( &extension ) )
551 { SDEB(fileNames[f]); rval= -1; continue; }
552
553 if ( utilMemoryBufferEqualsString( &extension, pfaExtension ) )
554 {
555 if ( psFontNameFromPfa( &fontname, adb.adbFontNameProg, &file ) )
556 { SDEB(fileNames[f]); rval= -1; }
557 }
558
559 if ( utilMemoryBufferEqualsString( &extension, pfbExtension ) )
560 {
561 if ( psFontNameFromPfb( &fontname, adb.adbFontNameProg, &file ) )
562 { SDEB(fileNames[f]); rval= -1; }
563 }
564
565 if ( utilMemoryBufferEqualsString( &extension, afmExtension ) )
566 {
567 if ( psFontNameFromAfm( &fontname, &file ) )
568 { SDEB(fileNames[f]); rval= -1; }
569 }
570
571 if ( utilMemoryBufferEqualsString( &extension, ttfExtension ) ||
572 utilMemoryBufferEqualsString( &extension, TTFExtension ) )
573 {
574 if ( psFontNameFromTtf( &fontname, &file ) )
575 { SDEB(fileNames[f]); rval= -1; }
576 }
577
578 /* Note that the afm reader potentially modifies the file name */
579
580 if ( ! utilMemoryBufferIsEmpty( &fontname ) &&
581 ! utilMemoryBufferIsEmpty( &file ) )
582 {
583 sioOutPrintf( sosOut, "/%s (%s) ;\n",
584 utilMemoryBufferGetString( &fontname ),
585 utilMemoryBufferGetString( &file ) );
586 }
587 }
588
589 ready:
590
591 psCleanAfmDirBuilder( &adb );
592
593 utilCleanMemoryBuffer( &file );
594 utilCleanMemoryBuffer( &extension );
595 utilCleanMemoryBuffer( &fontname );
596
597 return rval;
598 }
599
600 /************************************************************************/
601
psSaveAfmFile(AfmFontInfo * afi,AfmDirBuilder * adb)602 static int psSaveAfmFile( AfmFontInfo * afi,
603 AfmDirBuilder * adb )
604 {
605 int rval= 0;
606 const int relativeIsFile= 0;
607 unsigned char * s;
608
609 MemoryBuffer relative;
610
611 utilInitMemoryBuffer( &relative );
612
613 if ( utilMemoryBufferSetString( &relative, afi->afiFontName ) )
614 { LDEB(1); rval= -1; goto ready; }
615 if ( utilMemoryBufferAppendBytes( &relative,
616 (const unsigned char *)".afm", 4 ) )
617 { LDEB(4); rval= -1; goto ready; }
618
619 s= relative.mbBytes;
620 while( *s )
621 {
622 if ( isspace( *s ) )
623 { *s= '-'; }
624 s++;
625 }
626 if ( appAbsoluteName( &(afi->afiAfmFileName), &relative,
627 relativeIsFile, &(adb->adbAfmDirectory) ) < 0 )
628 { LDEB(1); rval= -1; goto ready; }
629
630 if ( psPostScriptFontListAddInfo( adb->adbPostScriptFontList, afi ) )
631 { LDEB(1); rval= -1; goto ready; }
632
633 ready:
634
635 utilCleanMemoryBuffer( &relative );
636
637 return rval;
638 }
639
psAfmFromPfaFile(const MemoryBuffer * filename,void * through)640 static int psAfmFromPfaFile( const MemoryBuffer * filename,
641 void * through )
642 {
643 int rval= 0;
644 AfmDirBuilder * adb= (AfmDirBuilder *)through;
645 AfmFontInfo * afi= (AfmFontInfo *)0;
646
647 /* Broken symlinks */
648 if ( appTestFileExists( filename ) )
649 { goto ready; }
650
651 afi= psFillAfiForPfa( adb, filename );
652 if ( ! afi )
653 { XDEB(afi); goto ready; } /* do not fail */
654
655 if ( psSaveAfmFile( afi, adb ) )
656 { LDEB(1); rval= -1; goto ready; }
657
658 afi= (AfmFontInfo *)0; /* steal */
659
660 ready:
661
662 if ( afi )
663 { psFreeAfmFontInfo( afi ); }
664
665 return rval;
666 }
667
psAfmFromPfbFile(const MemoryBuffer * filename,void * through)668 static int psAfmFromPfbFile( const MemoryBuffer * filename,
669 void * through )
670 {
671 int rval= 0;
672 AfmDirBuilder * adb= (AfmDirBuilder *)through;
673 AfmFontInfo * afi= (AfmFontInfo *)0;
674
675 /* Broken symlinks */
676 if ( appTestFileExists( filename ) )
677 { goto ready; }
678
679 afi= psFillAfiForPfb( adb, filename );
680 if ( ! afi )
681 { XDEB(afi); goto ready; } /* do not fail */
682
683 if ( psSaveAfmFile( afi, adb ) )
684 { LDEB(1); rval= -1; goto ready; }
685
686 afi= (AfmFontInfo *)0; /* steal */
687
688 ready:
689
690 if ( afi )
691 { psFreeAfmFontInfo( afi ); }
692
693 return rval;
694 }
695
psAfmFromTtfFile(const MemoryBuffer * filename,void * through)696 static int psAfmFromTtfFile( const MemoryBuffer * filename,
697 void * through )
698 {
699 int rval= 0;
700 AfmDirBuilder * adb= (AfmDirBuilder *)through;
701
702 AfmFontInfo * afi= (AfmFontInfo *)0;
703
704 /* Broken symlinks */
705 if ( appTestFileExists( filename ) )
706 { goto ready; }
707
708 afi= psFillAfiForTtf( filename );
709 if ( ! afi )
710 { XDEB(afi); goto ready; } /* do not fail */
711
712 if ( psSaveAfmFile( afi, adb ) )
713 { LDEB(1); rval= -1; goto ready; }
714
715 afi= (AfmFontInfo *)0;
716
717 ready:
718
719 if ( afi )
720 { psFreeAfmFontInfo( afi ); }
721
722 return rval;
723 }
724
psAfmFromAfmFile(const MemoryBuffer * filename,void * through)725 static int psAfmFromAfmFile( const MemoryBuffer * filename,
726 void * through )
727 {
728 int rval= 0;
729 AfmDirBuilder * adb= (AfmDirBuilder *)through;
730
731 AfmFontInfo * afi= (AfmFontInfo *)0;
732
733 /* Broken symlinks */
734 if ( appTestFileExists( filename ) )
735 { goto ready; }
736
737 afi= psFillAfiForAfm( adb->adbAfmFlags, filename );
738 if ( ! afi )
739 { LDEB(1); goto ready; } /* do not fail */
740
741 if ( psSaveAfmFile( afi, adb ) )
742 { LDEB(1); rval= -1; goto ready; }
743
744 afi= (AfmFontInfo *)0;
745
746 ready:
747
748 if ( afi )
749 { psFreeAfmFontInfo( afi ); }
750
751 return rval;
752 }
753
754 /************************************************************************/
755 /* */
756 /* Build an afm directory: Include all fonts that are on the */
757 /* GhostScript library path. */
758 /* */
759 /************************************************************************/
760
psGSLibAfmDirectory(PostScriptFontList * psfl,int ignoreKerning,const MemoryBuffer * afmDirectory,const MemoryBuffer * psDirectory)761 int psGSLibAfmDirectory( PostScriptFontList * psfl,
762 int ignoreKerning,
763 const MemoryBuffer * afmDirectory,
764 const MemoryBuffer * psDirectory )
765 {
766 int rval= 0;
767 SimpleInputStream * sisCmd= (SimpleInputStream *)0;
768
769 AfmDirBuilder adb;
770 MemoryBuffer dir;
771 MemoryBuffer libCommand;
772
773 char scratch[500+1];
774
775 const char * libBase= "gs -q %s/gslibpath.ps -c quit";
776
777 utilInitMemoryBuffer( &dir );
778 utilInitMemoryBuffer( &libCommand );
779
780 psInitAfmDirBuilder( &adb );
781
782 if ( psStartAfmDirBuilder( &adb, psfl, ignoreKerning,
783 afmDirectory, psDirectory ) )
784 { LDEB(1); rval= -1; goto ready; }
785
786 utilMemoryBufferPrintf( &libCommand, libBase,
787 utilMemoryBufferGetString( psDirectory ) );
788
789 sisCmd= sioInPipeOpen( &libCommand );
790 if ( ! sisCmd )
791 { SXDEB(libBase,sisCmd); rval= -1; goto ready; }
792
793 setlocale( LC_NUMERIC, "C" );
794
795 while( sioInGetString( scratch, sizeof(scratch)- 1, sisCmd ) )
796 {
797 int l;
798
799 scratch[sizeof(scratch)- 1]= '\0';
800 l= strlen( scratch );
801 if ( l < 2 )
802 { LDEB(l); rval= -1; goto ready; }
803 if ( scratch[l-1] != '\n' )
804 { SDEB(scratch); rval= -1; goto ready; }
805 scratch[l-1]= '\0';
806
807 if ( utilMemoryBufferSetString( &dir, scratch ) )
808 { LDEB(1); rval= -1; goto ready; }
809
810 if ( ! appFileNameIsAbsolute( scratch ) )
811 { continue; }
812 if ( appTestDirectory( &dir ) )
813 { continue; }
814
815 l= appForAllFiles( &dir, pfaExtension, &adb, psAfmFromPfaFile );
816 if ( l )
817 { SDEB(scratch); rval= -1; }
818 l= appForAllFiles( &dir, pfbExtension, &adb, psAfmFromPfbFile );
819 if ( l )
820 { SDEB(scratch); rval= -1; }
821 l= appForAllFiles( &dir, ttfExtension, &adb, psAfmFromTtfFile );
822 if ( l )
823 { SDEB(scratch); rval= -1; }
824 l= appForAllFiles( &dir, TTFExtension, &adb, psAfmFromTtfFile );
825 if ( l )
826 { SDEB(scratch); rval= -1; }
827 }
828
829 ready:
830
831 setlocale( LC_NUMERIC, "" );
832
833 if ( sisCmd )
834 { sioInClose( sisCmd ); }
835
836 psCleanAfmDirBuilder( &adb );
837
838 utilCleanMemoryBuffer( &dir );
839 utilCleanMemoryBuffer( &libCommand );
840
841 return rval;
842 }
843
844 /************************************************************************/
845 /* */
846 /* Build afm directory files for a list of font files. */
847 /* */
848 /************************************************************************/
849
psAfmForFontFiles(PostScriptFontList * psfl,int ignoreKerning,int fileCount,char ** fileNames,const MemoryBuffer * afmDirectory,const MemoryBuffer * psDirectory)850 int psAfmForFontFiles( PostScriptFontList * psfl,
851 int ignoreKerning,
852 int fileCount,
853 char ** fileNames,
854 const MemoryBuffer * afmDirectory,
855 const MemoryBuffer * psDirectory )
856 {
857 int rval= 0;
858 int f;
859
860
861 AfmDirBuilder adb;
862 MemoryBuffer file;
863 MemoryBuffer extension;
864
865 utilInitMemoryBuffer( &file );
866 utilInitMemoryBuffer( &extension );
867
868 psInitAfmDirBuilder( &adb );
869
870 if ( psStartAfmDirBuilder( &adb, psfl, ignoreKerning,
871 afmDirectory, psDirectory ) )
872 { LDEB(1); rval= -1; goto ready; }
873
874 setlocale( LC_NUMERIC, "C" );
875
876 for ( f= 0; f < fileCount; f++ )
877 {
878 int ret;
879
880 ret= psGetNameExt( &file, &extension, &adb, fileNames[f] );
881 if ( ret < 0 )
882 { LDEB(ret); rval= -1; goto ready; }
883 if ( ret > 0 )
884 { LDEB(ret); rval= -1; continue; }
885
886 if ( utilMemoryBufferEqualsString( &extension, pfaExtension ) )
887 {
888 if ( psAfmFromPfaFile( &file, &adb ) )
889 { SDEB(fileNames[f]); rval= -1; }
890
891 continue;
892 }
893
894 if ( utilMemoryBufferEqualsString( &extension, pfbExtension ) )
895 {
896 if ( psAfmFromPfbFile( &file, &adb ) )
897 { SDEB(fileNames[f]); rval= -1; }
898
899 continue;
900 }
901
902 if ( utilMemoryBufferEqualsString( &extension, afmExtension ) )
903 {
904 if ( psAfmFromAfmFile( &file, &adb ) )
905 { SDEB(fileNames[f]); rval= -1; }
906
907 continue;
908 }
909
910 if ( utilMemoryBufferEqualsString( &extension, ttfExtension ) ||
911 utilMemoryBufferEqualsString( &extension, TTFExtension ) )
912 {
913 if ( psAfmFromTtfFile( &file, &adb ) )
914 { SDEB(fileNames[f]); rval= -1; }
915
916 continue;
917 }
918
919 SDEB(fileNames[f]); rval= -1; continue;
920 }
921
922 ready:
923
924 setlocale( LC_NUMERIC, "" );
925
926 psCleanAfmDirBuilder( &adb );
927
928 utilCleanMemoryBuffer( &file );
929 utilCleanMemoryBuffer( &extension );
930
931 return rval;
932 }
933
psAfmToGSFontmap(SimpleOutputStream * sosFontDir,const char * afmFileName)934 int psAfmToGSFontmap( SimpleOutputStream * sosFontDir,
935 const char * afmFileName )
936 {
937 return psFontmapForFiles( sosFontDir, 1, &(afmFileName) );
938 }
939
psFontFileToAfm(SimpleOutputStream * sosAfm,int omitKernPairs,const char * fontFileName,const MemoryBuffer * psDirectory)940 int psFontFileToAfm( SimpleOutputStream * sosAfm,
941 int omitKernPairs,
942 const char * fontFileName,
943 const MemoryBuffer * psDirectory )
944 {
945 int rval= 0;
946 int ret;
947 AfmFontInfo * afi= (AfmFontInfo *)0;
948
949 AfmDirBuilder adb;
950 MemoryBuffer file;
951 MemoryBuffer extension;
952
953 utilInitMemoryBuffer( &file );
954 utilInitMemoryBuffer( &extension );
955
956 psInitAfmDirBuilder( &adb );
957
958 if ( psStartAfmDirBuilder( &adb, (PostScriptFontList *)0, omitKernPairs,
959 (const MemoryBuffer *)0, psDirectory ) )
960 { LDEB(1); rval= -1; goto ready; }
961
962 setlocale( LC_NUMERIC, "C" );
963
964 ret= psGetNameExt( &file, &extension, &adb, fontFileName );
965 if ( ret < 0 )
966 { LDEB(ret); rval= -1; goto ready; }
967 if ( ret > 0 )
968 { LDEB(ret); rval= -1; goto ready; }
969
970 if ( utilMemoryBufferEqualsString( &extension, pfaExtension ) )
971 {
972 afi= psFillAfiForPfa( &adb, &file );
973 if ( ! afi )
974 { SXDEB(fontFileName,afi); rval= -1; goto ready; }
975 }
976
977 if ( utilMemoryBufferEqualsString( &extension, pfbExtension ) )
978 {
979 afi= psFillAfiForPfb( &adb, &file );
980 if ( ! afi )
981 { SXDEB(fontFileName,afi); rval= -1; goto ready; }
982 }
983
984 if ( utilMemoryBufferEqualsString( &extension, afmExtension ) )
985 {
986 afi= psFillAfiForAfm( adb.adbAfmFlags, &file );
987 if ( ! afi )
988 { SXDEB(fontFileName,afi); rval= -1; goto ready; }
989 }
990
991 if ( utilMemoryBufferEqualsString( &extension, ttfExtension ) ||
992 utilMemoryBufferEqualsString( &extension, TTFExtension ) )
993 {
994 afi= psFillAfiForTtf( &file );
995 if ( ! afi )
996 { SXDEB(fontFileName,afi); rval= -1; goto ready; }
997 }
998
999 if ( ! afi )
1000 { XDEB(afi); rval= -1; goto ready; }
1001
1002 if ( psWriteAfmFile( sosAfm, adb.adbAfmFlags, afi ) )
1003 { LDEB(1); rval= -1; goto ready; }
1004
1005 ready:
1006
1007 setlocale( LC_NUMERIC, "" );
1008
1009 psCleanAfmDirBuilder( &adb );
1010
1011 utilCleanMemoryBuffer( &file );
1012 utilCleanMemoryBuffer( &extension );
1013
1014 if ( afi )
1015 { psFreeAfmFontInfo( afi ); }
1016
1017 return rval;
1018 }
1019