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