1 #   include	"utilPsConfig.h"
2 
3 #   include	<stdlib.h>
4 #   include	<string.h>
5 #   include	<ctype.h>
6 
7 #   include	"psFontInfo.h"
8 #   include	"psGlyphs.h"
9 #   include	<utilTree.h>
10 #   include	<uniAlternatives.h>
11 
12 #   include	<appDebugon.h>
13 
14 /************************************************************************/
15 /*									*/
16 /*  Bookkeeping and management of AFM information.			*/
17 /*									*/
18 /************************************************************************/
19 
psInitAfmCodeList(AfmCodeList * acl)20 static void psInitAfmCodeList(	AfmCodeList *	acl )
21     {
22     acl->aclCodes= (unsigned short int *)0;
23     acl->aclCodeCount= 0;
24     }
25 
psInitAfmCharMetric(AfmCharMetric * acm)26 static void psInitAfmCharMetric(	AfmCharMetric *	acm )
27     {
28     psInitAfmCodeList( &(acm->acmDefaultCodeList) );
29     psInitAfmCodeList( &(acm->acmUnicodeCodeList) );
30 
31     acm->acmWX= 0;;
32     geoInitRectangle ( &(acm->acmBBox) );
33     acm->acmN= (char *)0;
34     acm->acmKernPairs= (AfmKerningPair *)0;
35     acm->acmKernPairCount= 0;
36     acm->acmGlyphIndex= -1;
37     }
38 
psCleanAfmCodeList(AfmCodeList * acl)39 static void psCleanAfmCodeList(	AfmCodeList *	acl )
40     {
41     if  ( acl->aclCodes )
42 	{ free( acl->aclCodes );	}
43     }
44 
psFreeAfmCharMetric(AfmCharMetric * acm)45 static void psFreeAfmCharMetric(	AfmCharMetric *	acm )
46     {
47     psCleanAfmCodeList( &(acm->acmDefaultCodeList) );
48     psCleanAfmCodeList( &(acm->acmUnicodeCodeList) );
49 
50     if  ( acm->acmN )
51 	{ free( acm->acmN );		}
52     if  ( acm->acmKernPairs )
53 	{ free( acm->acmKernPairs );	}
54 
55     free( acm );
56     }
57 
psFontMetricAddCodeToList(AfmCodeList * acl,AfmFontInfo * afi,int C)58 static int psFontMetricAddCodeToList(	AfmCodeList *		acl,
59 					AfmFontInfo *		afi,
60 					int			C )
61     {
62     int			i;
63     unsigned short *	fresh;
64 
65     if  ( C < 0 )
66 	{ LDEB(C); return -1;	}
67 
68     for ( i= 0; i < acl->aclCodeCount; i++ )
69 	{
70 	if  ( acl->aclCodes[i] == C )
71 	    { return 0;	}
72 	}
73 
74     fresh= (unsigned short *)realloc( acl->aclCodes,
75 			    ( acl->aclCodeCount+ 1 )* sizeof(unsigned short) );
76     if  ( ! fresh )
77 	{ LXDEB(acl->aclCodeCount,fresh); return -1;	}
78     acl->aclCodes= fresh;
79 
80     acl->aclCodes[acl->aclCodeCount++]= C;
81 
82     return 0;
83     }
84 
85 /************************************************************************/
86 
psGetUnicodesFromGlyphNames(AfmFontInfo * afi)87 int psGetUnicodesFromGlyphNames(	AfmFontInfo *	afi )
88     {
89     int		glyphIndex;
90     int		rval= 0;
91 
92     IndexMapping *	tgm= &(afi->afiUnicodeToGlyphMapping);
93 
94     for ( glyphIndex= 0; glyphIndex < afi->afiMetricCount; glyphIndex++ )
95 	{
96 	AfmCharMetric *	acm= afi->afiMetrics[glyphIndex];
97 	if  ( acm && acm->acmN )
98 	    {
99 	    int		code= psGlyphNameToUnicode( acm->acmN );
100 
101 	    if  ( code < 0 )
102 		{ /*SDEB(acm->acmN);*/ continue;	}
103 
104 	    if  ( psFontMetricAddCodeToList( &(acm->acmUnicodeCodeList),
105 								afi, code ) )
106 		{ LDEB(code); return -1;	}
107 
108 	    if  ( utilIndexMappingGet( tgm, code ) < 0 )
109 		{
110 		utilIndexMappingPut( tgm, code, glyphIndex );
111 
112 		if  ( utilIndexSetAdd( &(afi->afiUnicodesProvided), code ) )
113 		    { LDEB(code);	}
114 		}
115 	    }
116 	}
117 
118     return rval;
119     }
120 
psGetAlternateGlyphs(AfmFontInfo * afi)121 int psGetAlternateGlyphs(	AfmFontInfo *	afi )
122     {
123     if  ( uniMapToAlternatives( &(afi->afiUnicodeToGlyphMapping) ) )
124 	{ SDEB(afi->afiFullName);	}
125 
126     if  ( uniIncludeWithAlternatives( &(afi->afiUnicodesProvided) ) )
127 	{ SDEB(afi->afiFullName);	}
128 
129     return 0;
130     }
131 
psResolveFallbackGlyph(AfmFontInfo * afi)132 int psResolveFallbackGlyph(	AfmFontInfo *	afi )
133     {
134     IndexMapping *	tgm= &(afi->afiUnicodeToGlyphMapping);
135     int			space;
136 
137     if  ( afi->afiFallbackGlyph >= 0 )
138 	{ return 0;	}
139 
140     space= utilIndexMappingGet( tgm, ' ' );
141     if  ( space >= 0 )
142 	{ afi->afiFallbackGlyph= space; return 0;	}
143 
144     SDEB(afi->afiFullName); return -1;
145     }
146 
147 /************************************************************************/
148 /*									*/
149 /*  Initialise an AfmFontInfo						*/
150 /*									*/
151 /************************************************************************/
152 
psInitAfmFontInfo(AfmFontInfo * afi)153 void psInitAfmFontInfo(	AfmFontInfo *	afi )
154     {
155     afi->afiFaceNumber= -1;
156 
157     afi->afiFontName= (char *)0;
158     afi->afiFullName= (char *)0;
159     afi->afiNotice= (char *)0;
160     afi->afiVersion= (char *)0;
161     afi->afiFamilyName= (char *)0;
162     afi->afiFamilyName_Orig= (char *)0;
163     afi->afiWeightStr= (char *)0;
164     afi->afiWeightInt= FONTweightREGULAR;
165     afi->afiWidthStr= (char *)0;
166     afi->afiWidthInt= FONTwidthNORMAL;
167 
168     afi->afiItalicAngle= 0.0;
169     afi->afiTanItalicAngle= 0.0;
170 
171     afi->afiIsFixedPitch= 0;
172     geoInitRectangle( &(afi->afiFontBBox) );
173     afi->afiUnderlinePosition= 0;
174     afi->afiUnderlineThickness= 0;
175     afi->afiEncodingScheme= (char *)0;
176     afi->afiCapHeight= 0;
177     afi->afiXHeight= 0;
178     afi->afiAscender= 0;
179     afi->afiDescender= 0;
180     afi->afiCharacterSet= (char *)0;
181     afi->afiVendor= (char *)0;
182 
183     afi->afiResourceName= (char *)0;
184     utilInitMemoryBuffer( &(afi->afiFontFileName) );
185     afi->afiFontFileIndex= 0;
186 
187     utilInitMemoryBuffer( &(afi->afiAfmFileName) );
188     afi->afiMetricsDeferred= 0;
189     afi->afiIgnoreKerning= 0;
190     afi->afiMetricCount= 0;
191     afi->afiMetrics= (AfmCharMetric **)0;
192     afi->afiNameToMetric= (void *)0;
193     afi->afiFallbackGlyph= 0;
194 
195     afi->afiX11FontCount= 0;
196     afi->afiX11Fonts= (char **)0;
197 
198     utilInitIndexMapping( &(afi->afiUnicodeToGlyphMapping) );
199     utilInitIndexSet( &(afi->afiUnicodesProvided) );
200 
201     /**/
202     afi->afiStyle= (char *)0;
203 
204     afi->afiResolveMetrics= (ResolveFontMetrics)0;
205 
206     return;
207     }
208 
psRemoveMetricsFromInfo(AfmFontInfo * afi)209 void psRemoveMetricsFromInfo(	AfmFontInfo *	afi )
210     {
211     int		i;
212 
213     for ( i= 0; i < afi->afiMetricCount; i++ )
214 	{
215 	if  ( afi->afiMetrics[i] )
216 	    { psFreeAfmCharMetric( afi->afiMetrics[i] );	}
217 	}
218 
219     if  ( afi->afiMetrics )
220 	{ free( afi->afiMetrics );}
221 
222     afi->afiMetricCount= 0;
223     afi->afiMetrics= (AfmCharMetric **)0;
224 
225     if  ( afi->afiNameToMetric )
226 	{
227 	utilTreeFreeTree( afi->afiNameToMetric,
228 					(UTIL_TREE_CALLBACK)0, (void *)0 );
229 	afi->afiNameToMetric= (void *)0;
230 	}
231 
232     return;
233     }
234 
psCleanAfmFontInfo(AfmFontInfo * afi)235 void psCleanAfmFontInfo(	AfmFontInfo *	afi )
236     {
237     int		i;
238 
239     if  ( afi->afiFontName )
240 	{ free( afi->afiFontName );	}
241     if  ( afi->afiFullName )
242 	{ free( afi->afiFullName );	}
243     if  ( afi->afiNotice )
244 	{ free( afi->afiNotice );	}
245     if  ( afi->afiVersion )
246 	{ free( afi->afiVersion );	}
247     if  ( afi->afiFamilyName )
248 	{ free( afi->afiFamilyName );	}
249     if  ( afi->afiFamilyName_Orig )
250 	{ free( afi->afiFamilyName_Orig );	}
251     if  ( afi->afiWeightStr )
252 	{ free( afi->afiWeightStr );	}
253     if  ( afi->afiWidthStr )
254 	{ free( afi->afiWidthStr );	}
255     if  ( afi->afiEncodingScheme )
256 	{ free( afi->afiEncodingScheme );}
257     if  ( afi->afiCharacterSet )
258 	{ free( afi->afiCharacterSet );}
259     if  ( afi->afiVendor )
260 	{ free( afi->afiVendor );}
261     if  ( afi->afiResourceName )
262 	{ free( afi->afiResourceName );}
263 
264     utilCleanMemoryBuffer( &(afi->afiFontFileName) );
265     utilCleanMemoryBuffer( &(afi->afiAfmFileName) );
266 
267     for ( i= 0; i < afi->afiX11FontCount; i++ )
268 	{
269 	if  ( afi->afiX11Fonts[i] )
270 	    { free( afi->afiX11Fonts[i] );	}
271 	}
272 
273     if  ( afi->afiX11Fonts )
274 	{ free( afi->afiX11Fonts );}
275 
276     psRemoveMetricsFromInfo( afi );
277 
278     /* afi->afiStyle is a reference to another string */
279 
280     utilCleanIndexMapping( &(afi->afiUnicodeToGlyphMapping) );
281     utilCleanIndexSet( &(afi->afiUnicodesProvided) );
282 
283     return;
284     }
285 
psFreeAfmFontInfo(AfmFontInfo * afi)286 void psFreeAfmFontInfo(	AfmFontInfo *	afi )
287     {
288     psCleanAfmFontInfo(	afi );
289     free( afi );
290     }
291 
292 /************************************************************************/
293 /*									*/
294 /*  Add one code for the default encoding to a char metric.		*/
295 /*									*/
296 /************************************************************************/
297 
psFontMetricAddCode(AfmCharMetric * acm,AfmFontInfo * afi,int C)298 static int psFontMetricAddCode(		AfmCharMetric *		acm,
299 					AfmFontInfo *		afi,
300 					int			C )
301     {
302     if  ( psFontMetricAddCodeToList( &(acm->acmDefaultCodeList), afi, C ) )
303 	{ LDEB(C); return -1;	}
304 
305     return 0;
306     }
307 
308 /************************************************************************/
309 /*									*/
310 /*  Add one metic to a font info.					*/
311 /*									*/
312 /************************************************************************/
313 
psFontInfoAddMetric(AfmFontInfo * afi,int C,int WX,const char * N,const DocumentRectangle * abb)314 int psFontInfoAddMetric(		AfmFontInfo *			afi,
315 					int				C,
316 					int				WX,
317 					const char *			N,
318 					const DocumentRectangle *	abb )
319     {
320     AfmCharMetric **	fresh;
321     AfmCharMetric *	acm;
322     int			duplicate= 0;
323 
324     if  ( ! afi->afiNameToMetric )
325 	{
326 	const int	ownKeys= 0;
327 
328 	afi->afiNameToMetric= utilTreeMakeTree( ownKeys );
329 	if  ( ! afi->afiNameToMetric )
330 	    { XDEB(afi->afiNameToMetric); return -1;	}
331 	}
332 
333     if  ( N && N[0] )
334 	{
335 	acm= (AfmCharMetric *)utilTreeGetEQ( afi->afiNameToMetric, (const char **)0, N );
336 
337 	if  ( acm )
338 	    {
339 	    if  ( C >= 0 && psFontMetricAddCode( acm, afi, C ) )
340 		{ LDEB(C); return -1;	}
341 
342 	    duplicate= 1;
343 	    }
344 	}
345 
346     fresh= (AfmCharMetric **)realloc( afi->afiMetrics,
347 			( afi->afiMetricCount+ 1 )* sizeof(AfmCharMetric *) );
348     if  ( ! fresh )
349 	{ LXDEB(C,fresh); return -1;	}
350     afi->afiMetrics= fresh;
351 
352     fresh[afi->afiMetricCount]= acm= (AfmCharMetric *)malloc(
353 						    sizeof(AfmCharMetric) );
354     if  ( ! acm )
355 	{ XDEB(acm); return -1;	}
356 
357     psInitAfmCharMetric( acm );
358 
359     acm->acmWX= (int)WX;
360     if  ( N && ! duplicate )
361 	{
362 	acm->acmN= strdup( N );
363 
364 	if  ( utilTreeStoreValue( afi->afiNameToMetric,
365 					    (void **)0, (const char **)0,
366 					    acm->acmN, acm ) )
367 	    { LDEB(afi->afiMetricCount);	}
368 	}
369 
370     acm->acmBBox= *abb;
371     acm->acmGlyphIndex= afi->afiMetricCount++;
372 
373     if  ( C >= 0 && psFontMetricAddCode( acm, afi, C ) )
374 	{ LDEB(C); return -1;	}
375 
376     return 0;
377     }
378 
379 /************************************************************************/
380 /*									*/
381 /*  Set/Add the default encoding for a glyph.				*/
382 /*  As this is the wrong way round in the AFM file format, more than	*/
383 /*  one code can map to the same glyph.					*/
384 /*									*/
385 /************************************************************************/
386 
psFontInfoSetGlyphCode(AfmFontInfo * afi,int glyphIndex,int C)387 int psFontInfoSetGlyphCode(	AfmFontInfo *		afi,
388 				int			glyphIndex,
389 				int			C )
390     {
391     if  ( glyphIndex < 0			||
392 	  glyphIndex >= afi->afiMetricCount	||
393 	  ! afi->afiMetrics[glyphIndex]		)
394 	{ LLDEB(glyphIndex,afi->afiMetricCount); return -1;	}
395 
396     if  ( psFontMetricAddCode( afi->afiMetrics[glyphIndex], afi, C ) )
397 	{ LDEB(C); return -1;	}
398 
399     return 0;
400     }
401 
psFontInfoSetGlyphUnicode(AfmFontInfo * afi,int glyphIndex,int code)402 int psFontInfoSetGlyphUnicode(	AfmFontInfo *		afi,
403 				int			glyphIndex,
404 				int			code )
405     {
406     AfmCharMetric *	acm;
407     IndexMapping *	tgm= &(afi->afiUnicodeToGlyphMapping);
408 
409     if  ( glyphIndex < 0			||
410 	  glyphIndex >= afi->afiMetricCount	||
411 	  ! afi->afiMetrics[glyphIndex]		)
412 	{ LLDEB(glyphIndex,afi->afiMetricCount); return -1;	}
413 
414     acm= afi->afiMetrics[glyphIndex];
415 
416     if  ( psFontMetricAddCodeToList( &(acm->acmUnicodeCodeList), afi, code ) )
417 	{ LDEB(code); return -1;	}
418 
419     if  ( utilIndexMappingGet( tgm, code ) < 0 )
420 	{
421 	utilIndexMappingPut( tgm, code, glyphIndex );
422 
423 	if  ( utilIndexSetAdd( &(afi->afiUnicodesProvided), code ) )
424 	    { LDEB(code);	}
425 	}
426 
427     return 0;
428     }
429 
430 /************************************************************************/
431 /*									*/
432 /*  Remember the name of a glyph.					*/
433 /*									*/
434 /************************************************************************/
435 
psFontInfoSetGlyphName(AfmFontInfo * afi,int glyphIndex,const char * glyphName)436 int psFontInfoSetGlyphName(	AfmFontInfo *		afi,
437 				int			glyphIndex,
438 				const char *		glyphName )
439     {
440     if  ( glyphIndex < 0			||
441 	  glyphIndex >= afi->afiMetricCount	||
442 	  ! afi->afiMetrics[glyphIndex]		)
443 	{ LLDEB(glyphIndex,afi->afiMetricCount); return -1;	}
444 
445     if  ( afi->afiMetrics[glyphIndex]->acmN )
446 	{
447 	utilTreeDeleteEQ( afi->afiNameToMetric,
448 				afi->afiMetrics[glyphIndex]->acmN,
449 				(UTIL_TREE_CALLBACK)0, (void *)0 );
450 	free( afi->afiMetrics[glyphIndex]->acmN );
451 	}
452 
453     afi->afiMetrics[glyphIndex]->acmN= strdup( glyphName );
454     if  ( ! afi->afiMetrics[glyphIndex]->acmN )
455 	{ XDEB(afi->afiMetrics[glyphIndex]->acmN); return -1;	}
456 
457     if  ( utilTreeStoreValue( afi->afiNameToMetric,
458 					(void **)0, (const char **)0,
459 					afi->afiMetrics[glyphIndex]->acmN,
460 					afi->afiMetrics[glyphIndex] ) )
461 	{ LDEB(afi->afiMetricCount);	}
462 
463     return 0;
464     }
465 
psFontInfoGetGlyphName(const AfmFontInfo * afi,int glyphIndex)466 const char * psFontInfoGetGlyphName(	const AfmFontInfo *	afi,
467 					int			glyphIndex )
468     {
469     if  ( glyphIndex < 0			||
470 	  glyphIndex >= afi->afiMetricCount	||
471 	  ! afi->afiMetrics[glyphIndex]		)
472 	{ LLDEB(glyphIndex,afi->afiMetricCount); return (const char *)0; }
473 
474     return afi->afiMetrics[glyphIndex]->acmN;
475     }
476 
psFontInfoGetGlyphIndex(const AfmFontInfo * afi,const char * glyphName)477 int psFontInfoGetGlyphIndex(	const AfmFontInfo *	afi,
478 				const char *		glyphName )
479     {
480     AfmCharMetric *	acm;
481 
482     if  ( ! afi->afiNameToMetric )
483 	{
484 	if  ( afi->afiMetricCount > 0 )
485 	    { LXDEB(afi->afiMetricCount,afi->afiNameToMetric);	}
486 
487 	return -1;
488 	}
489 
490     acm= (AfmCharMetric *)utilTreeGetEQ( afi->afiNameToMetric,
491 						(const char **)0, glyphName );
492     if  ( ! acm )
493 	{ return -1;	}
494 
495     return acm->acmGlyphIndex;
496     }
497 
498 /************************************************************************/
499 /*									*/
500 /*  Add one metic to a font info.					*/
501 /*									*/
502 /************************************************************************/
503 
psAddX11FontToInfo(AfmFontInfo * afi,const char * fontName)504 int psAddX11FontToInfo(		AfmFontInfo *			afi,
505 				const char *			fontName )
506     {
507     int		i;
508     char **	fresh;
509 
510     for ( i= 0; i < afi->afiX11FontCount; i++ )
511 	{
512 	if  ( ! strcmp( afi->afiX11Fonts[i], fontName ) )
513 	    { return 0;	}
514 	}
515 
516     fresh= (char **)realloc( afi->afiX11Fonts,
517 			( afi->afiX11FontCount+ 1 )* sizeof(char *) );
518     if  ( ! fresh )
519 	{ XDEB(fresh); return -1;	}
520     afi->afiX11Fonts= fresh;
521 
522     fresh[afi->afiX11FontCount]= strdup( fontName );
523     if  ( ! fresh[afi->afiX11FontCount] )
524 	{ XDEB(fresh[afi->afiX11FontCount]); return -1;	}
525 
526     afi->afiX11FontCount++;
527 
528     return 0;
529     }
530 
531