1 # include "utilPsConfig.h"
2
3 # include <stdio.h>
4 # include <ctype.h>
5 # include <stdlib.h>
6
7 # include <locale.h>
8
9 # include "psPostScriptFontList.h"
10 # include "psReadWriteFontInfo.h"
11 # include <sioFileio.h>
12 # include <appSystem.h>
13
14 # include <appDebugon.h>
15
16 # ifdef __VMS
17 static const char * const afmExtension= "AFM";
18 # else
19 static const char * const afmExtension= "afm";
20 # endif
21
22 static const char * PS_LocalAfmDir= "localfonts";
23
24 typedef struct AfmCatalog
25 {
26 int acAfmFlags;
27 PostScriptFontList * acFontList;
28 } AfmCatalog;
29
30 /************************************************************************/
31 /* */
32 /* Make a catalog of postscript fonts for the font chooser. */
33 /* */
34 /* The code assumes that afmDirectory is some kind of a resource, that */
35 /* does not vary over different calls to the routine. */
36 /* */
37 /* A: Consume one file. */
38 /* B: Ignore errors in certain hopeless files. */
39 /* */
40 /************************************************************************/
41
42 # define FILEL 400
43
44 /* A */
psRememberAfmFile(const MemoryBuffer * filename,const AfmCatalog * ac)45 static int psRememberAfmFile( const MemoryBuffer * filename,
46 const AfmCatalog * ac )
47 {
48 int rval= 0;
49 SimpleInputStream * sisAfm= (SimpleInputStream *)0;
50 int res;
51
52 AfmFontInfo * afi= (AfmFontInfo *)0;
53
54 if ( utilMemoryBufferIsEmpty( filename ) )
55 { LDEB(filename->mbSize); rval= -1; goto ready; }
56
57 afi= (AfmFontInfo *)malloc( sizeof(AfmFontInfo) );
58 if ( ! afi )
59 { XDEB(afi); rval= -1; goto ready; }
60
61 psInitAfmFontInfo( afi );
62
63 sisAfm= sioInFileioOpen( filename );
64 if ( ! sisAfm )
65 {
66 SXDEB(utilMemoryBufferGetString(filename),sisAfm);
67 goto ready; /* no failure ! */
68 }
69
70 res= psAfmReadAfm( sisAfm, afi, ac->acAfmFlags );
71 if ( res < 0 )
72 {
73 SXDEB(utilMemoryBufferGetString(filename),sisAfm);
74 goto ready; /* no failure ! */
75 }
76
77 if ( utilCopyMemoryBuffer( &(afi->afiAfmFileName), filename ) )
78 { LDEB(1); goto ready; }
79
80 if ( psGetUnicodesFromGlyphNames( afi ) )
81 { SDEB(afi->afiFullName); }
82 if ( psGetAlternateGlyphs( afi ) )
83 { SDEB(afi->afiFullName); }
84 if ( psResolveFallbackGlyph( afi ) )
85 { SDEB(afi->afiFullName); }
86
87 /* Free memory: metrics are reread when the font is really used */
88 psRemoveMetricsFromInfo( afi );
89 afi->afiMetricsDeferred= 1;
90 afi->afiResolveMetrics= psGetDeferredMetrics;
91
92 if ( ! afi->afiFamilyName )
93 { XDEB(afi->afiFamilyName); goto ready; }
94
95 /*
96 if ( adaptNames )
97 { psMapVisibleNamesToBase35( afi ); }
98 */
99
100 if ( psPostScriptFontListAddInfo( ac->acFontList, afi ) )
101 { LDEB(1); rval= -1; goto ready; }
102 afi= (AfmFontInfo *)0; /* stolen */
103
104 ready:
105
106 if ( afi )
107 { psFreeAfmFontInfo( afi ); }
108 if ( sisAfm )
109 { sioInClose( sisAfm ); }
110
111 return rval;
112 }
113
psGotAfmFile(const MemoryBuffer * filename,void * through)114 static int psGotAfmFile( const MemoryBuffer * filename,
115 void * through )
116 {
117 return psRememberAfmFile( filename, (AfmCatalog *)through );
118 }
119
psGotLocalAfmFile(const MemoryBuffer * filename,void * through)120 static int psGotLocalAfmFile( const MemoryBuffer * filename,
121 void * through )
122 {
123 return psRememberAfmFile( filename, (AfmCatalog *)through );
124 }
125
126 /************************************************************************/
127
psLocalDirectoryName(MemoryBuffer * localDirectory,const MemoryBuffer * afmDirectory)128 static int psLocalDirectoryName( MemoryBuffer * localDirectory,
129 const MemoryBuffer * afmDirectory )
130 {
131 int rval= 0;
132 const int relativeIsFile= 0;
133
134 MemoryBuffer local;
135
136 utilInitMemoryBuffer( &local );
137
138 if ( utilMemoryBufferSetString( &local, PS_LocalAfmDir ) )
139 { LDEB(1); rval= -1; goto ready; }
140
141 if ( appAbsoluteName( localDirectory,
142 &local, relativeIsFile, afmDirectory ) < 0 )
143 { SDEB(PS_LocalAfmDir); rval= -1; goto ready; }
144
145 ready:
146
147 utilInitMemoryBuffer( &local );
148
149 return rval;
150 }
151
152 /************************************************************************/
153 /* */
154 /* Make a catalog of all the fonts for which an AFM file is found. */
155 /* */
156 /* 1) Collect the information from all AFM files. */
157 /* NOTE: Afm files are in the "C" locale. */
158 /* 2) Count families. */
159 /* NOTE: Width variants of the same family are treated like */
160 /* different families here. */
161 /* 3) Allocate space for the families. */
162 /* 4) Divide the faces over the families. */
163 /* */
164 /************************************************************************/
165
psFontCatalog(PostScriptFontList * psfl,int ignoreKerning,const MemoryBuffer * afmDirectory)166 int psFontCatalog( PostScriptFontList * psfl,
167 int ignoreKerning,
168 const MemoryBuffer * afmDirectory )
169 {
170 int rval= 0;
171 int j;
172
173 MemoryBuffer localDirectory;
174
175 AfmCatalog ac;
176
177 utilInitMemoryBuffer( &localDirectory );
178
179 ac.acFontList= psfl;
180 ac.acAfmFlags= PSflagDEFER_METRICS;
181 if ( ignoreKerning )
182 {
183 ac.acAfmFlags |= PSflagIGNORE_KERNING;
184 }
185
186 if ( psLocalDirectoryName( &localDirectory, afmDirectory ) )
187 { LDEB(1); rval= -1; goto ready; }
188
189 /* 1 */
190 setlocale( LC_NUMERIC, "C" );
191
192 if ( ! appTestDirectory( &localDirectory ) )
193 {
194 j= appForAllFiles( &localDirectory, afmExtension,
195 &ac, psGotLocalAfmFile );
196 if ( j )
197 { LDEB(j); }
198 }
199
200 j= appForAllFiles( afmDirectory, afmExtension, &ac, psGotAfmFile );
201
202 setlocale( LC_NUMERIC, "" );
203
204 if ( j )
205 { LDEB(j); rval= -1; goto ready; }
206
207 if ( psPostScriptFontListInfosToFamilies( psfl ) )
208 { LDEB(1); rval= -1; goto ready; }
209
210 ready:
211
212 utilCleanMemoryBuffer( &localDirectory );
213
214 return rval;
215 }
216
217 /************************************************************************/
218
psSaveAfms(const PostScriptFontList * psfl,int omitKernPairs,const MemoryBuffer * afmDirectory)219 int psSaveAfms( const PostScriptFontList * psfl,
220 int omitKernPairs,
221 const MemoryBuffer * afmDirectory )
222 {
223 int rval= 0;
224 int i;
225
226 MemoryBuffer localDirectory;
227
228 SimpleOutputStream * sosAfm= (SimpleOutputStream *)0;
229
230 utilInitMemoryBuffer( &localDirectory );
231
232 if ( psLocalDirectoryName( &localDirectory, afmDirectory ) )
233 { LDEB(1); rval= -1; goto ready; }
234
235 if ( appTestDirectory( &localDirectory ) &&
236 appMakeDirectory( &localDirectory ) )
237 { LDEB(1); rval= -1; goto ready; }
238
239 for ( i= 0; i < psfl->psflInfoCount; i++ )
240 {
241 AfmFontInfo * afi= psfl->psflInfos[i];
242
243 if ( ! afi || utilMemoryBufferIsEmpty( &(afi->afiAfmFileName ) ) )
244 { continue; }
245
246 sosAfm= sioOutFileioOpen( &(afi->afiAfmFileName) );
247 if ( ! sosAfm )
248 { XDEB(sosAfm); rval= -1; goto ready; }
249
250 if ( psWriteAfmFile( sosAfm, omitKernPairs, afi ) )
251 { SDEB(afi->afiFontName); rval= -1; goto ready; }
252
253 sioOutClose( sosAfm ); sosAfm= (SimpleOutputStream *)0;
254 }
255
256 ready:
257
258 if ( sosAfm )
259 { sioOutClose( sosAfm ); }
260
261 utilCleanMemoryBuffer( &localDirectory );
262
263 return rval;
264 }
265
psGetDeferredMetrics(AfmFontInfo * afi)266 int psGetDeferredMetrics( AfmFontInfo * afi )
267 {
268 int rval= 0;
269 SimpleInputStream * sisAfm= (SimpleInputStream *)0;
270 int afmFlags= 0;
271
272 int res;
273 AfmFontInfo afiMetrics;
274
275 psInitAfmFontInfo( &afiMetrics );
276
277 if ( afi->afiIgnoreKerning )
278 { afmFlags |= PSflagIGNORE_KERNING; }
279
280 if ( utilMemoryBufferIsEmpty( &(afi->afiAfmFileName) ) )
281 { LDEB(afi->afiAfmFileName.mbSize); rval= -1; goto ready; }
282
283 sisAfm= sioInFileioOpen( &(afi->afiAfmFileName) );
284 if ( ! sisAfm )
285 { XDEB(sisAfm); rval= -1; goto ready; }
286
287 setlocale( LC_NUMERIC, "C" );
288
289 res= psAfmReadAfm( sisAfm, &afiMetrics, afmFlags );
290 if ( res < 0 )
291 { LDEB(res); rval= -1; goto ready; }
292
293 psRemoveMetricsFromInfo( afi );
294 afi->afiMetrics= afiMetrics.afiMetrics;
295 afi->afiMetricCount= afiMetrics.afiMetricCount;
296 afi->afiNameToMetric= afiMetrics.afiNameToMetric;
297
298 afiMetrics.afiMetrics= (AfmCharMetric **)0;
299 afiMetrics.afiMetricCount= 0;
300 afiMetrics.afiNameToMetric= (void *)0;
301
302 afi->afiMetricsDeferred= 0;
303
304 if ( psGetUnicodesFromGlyphNames( afi ) )
305 { SDEB(afi->afiFullName); }
306 if ( psGetAlternateGlyphs( afi ) )
307 { SDEB(afi->afiFullName); }
308 if ( psResolveFallbackGlyph( afi ) )
309 { SDEB(afi->afiFullName); }
310
311 ready:
312
313 setlocale( LC_NUMERIC, "" );
314
315 psCleanAfmFontInfo( &afiMetrics );
316
317 if ( sisAfm )
318 { sioInClose( sisAfm ); }
319
320 return rval;
321 }
322
323