1 /************************************************************************/
2 /*									*/
3 /*  Management of X11 fonts: Translation of understandable fonts to	*/
4 /*  X11 structures.							*/
5 /*									*/
6 /************************************************************************/
7 
8 #   include	"appFrameConfig.h"
9 #   include	"appGuiBase.h"
10 #   include	"appScreenFont.h"
11 #   include	"drawDrawingSurfaceImpl.h"
12 #   include	<utilLongestCommonSubstring.h>
13 #   include	<uniLegacyEncoding.h>
14 #   include	<uniLegacyMapping.h>
15 #   include	"appFindX11Fonts.h"
16 #   include	"drawImpl.h"
17 
18 typedef struct XFontFaceSize
19     {
20     short int	xffsPixelSize;
21     short int	xffsListIndex;
22     } XFontFaceSize;
23 
24 #   ifdef	USE_X11_FONTS
25 
26 #   include	<stdlib.h>
27 #   include	<stdio.h>
28 #   include	<ctype.h>
29 #   include	<string.h>
30 
31 #   include	<appDebugon.h>
32 #   include	<psFontName.h>
33 #   include	<utilTree.h>
34 #   include	<psCompareFontInfo.h>
35 
36 #   ifdef USE_GTK
37 #	include	<gdk/gdkx.h>
38 #   endif
39 
40 #   include	<bitmap.h>
41 
42 /************************************************************************/
43 /*									*/
44 /*  Strings used for the analysis of X11 font names.			*/
45 /*									*/
46 /*  1)  The asterisk to insert in a font name for all properties that	*/
47 /*	we consider to be irrelevant.					*/
48 /*  2)  The templete/format to make X11 font names.			*/
49 /*  3)  A series of encodings with information on the X11 encoding	*/
50 /*	strings and on the encodings for which they can be used.	*/
51 /*  4)  This is the combination of character set and encoding. Given	*/
52 /*	a particular value, XDrawString() draws the same string with	*/
53 /*	the same array of characters.					*/
54 /*									*/
55 /************************************************************************/
56 
57 /*  1  */
58 static const char *	EditFontAnyTemplate= "*";
59 static const char *	EditFontAnyRegistry_EncodingTemplate= "*-*";
60 
61 /*  2  */
62 # define	EditFontFamilyTemplate \
63 			    "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s"
64 
appInitXFontFaceSize(XFontFaceSize * xffs)65 static void appInitXFontFaceSize(	XFontFaceSize *	xffs )
66     {
67     xffs->xffsPixelSize= 0;
68     xffs->xffsListIndex= -1;
69     }
70 
71 # define appCleanXFontFaceSize( xffs ) /* nothing */
72 
73 typedef struct XFontTypeface
74     {
75     char *		xftWeightStr;
76     char *		xftSlantStr;
77     unsigned char	xftWeight;
78     unsigned char	xftIsBold;
79     unsigned char	xftIsSlanted;
80     unsigned char	xftIsScalable;
81     unsigned char	xftIsFixedWidth;
82 
83     XFontFaceSize *	xftFaceSizes;
84     int			xftFaceSizeCount;
85     int			xftScalableListIndex;
86     } XFontTypeface;
87 
appInitXFontTypeface(XFontTypeface * xft)88 static void appInitXFontTypeface(	XFontTypeface *	xft )
89     {
90     xft->xftWeightStr= (char *)0;
91     xft->xftSlantStr= (char *)0;
92     xft->xftWeight= FONTweightMEDIUM;
93     xft->xftIsBold= 0;
94     xft->xftIsSlanted= 0;
95     xft->xftIsScalable= 0;
96     xft->xftIsFixedWidth= 0;
97 
98     xft->xftFaceSizes= (XFontFaceSize *)0;
99     xft->xftFaceSizeCount= 0;
100 
101     xft->xftScalableListIndex= -1;
102 
103     return;
104     }
105 
appCleanXFontTypeface(XFontTypeface * xft)106 static void appCleanXFontTypeface(	XFontTypeface *	xft )
107     {
108     int		i;
109 
110     if  ( xft->xftWeightStr )
111 	{ free( xft->xftWeightStr );	}
112     if  ( xft->xftSlantStr )
113 	{ free( xft->xftSlantStr );	}
114 
115     for ( i= 0; i < xft->xftFaceSizeCount; i++ )
116 	{ appCleanXFontFaceSize( &(xft->xftFaceSizes[i]) );	}
117 
118     if  ( xft->xftFaceSizes )
119 	{ free( xft->xftFaceSizes );	}
120 
121     return;
122     }
123 
124 typedef struct XFontFamily
125     {
126     char *		xffFamily;
127     char *		xffFamilyLower;
128     char *		xffFoundry;
129     int			xffSwdth;
130 
131     XFontTypeface *	xffFaces;
132     int			xffFaceCount;
133     } XFontFamily;
134 
appInitXFontFamily(XFontFamily * xff)135 static void appInitXFontFamily(	XFontFamily *	xff )
136     {
137     xff->xffFamily= (char *)0;
138     xff->xffFamilyLower= (char *)0;
139     xff->xffFoundry= (char *)0;
140     xff->xffSwdth= FONTwidthNORMAL;
141 
142     xff->xffFaces= (XFontTypeface *)0;
143     xff->xffFaceCount= 0;
144     }
145 
appCleanXFontFamily(XFontFamily * xff)146 static void appCleanXFontFamily(	XFontFamily *	xff )
147     {
148     int		i;
149 
150     if  ( xff->xffFamily )
151 	{ free( xff->xffFamily );	}
152     if  ( xff->xffFamilyLower )
153 	{ free( xff->xffFamilyLower );	}
154 
155     if  ( xff->xffFoundry )
156 	{ free( xff->xffFoundry );	}
157 
158     for ( i= 0; i < xff->xffFaceCount; i++ )
159 	{ appCleanXFontTypeface( &(xff->xffFaces[i]) ); }
160 
161     if  ( xff->xffFaces )
162 	{ free( xff->xffFaces );	}
163     }
164 
165 /*  3  */
166 typedef struct AppFontEncoding
167     {
168     const char *	feX11Reg_Enc;
169     int			feBytesPerChar;
170     const int *		feGlyphUnicodes;
171 
172     int			feX11Reg_Enc_Strlen;
173     IndexMapping	feSymbolToByteMapping;
174     IndexSet		feSymbolSet;
175 
176     XFontFamily *	afeXfontFamilies;
177     int			afeXfontFamilyCount;
178     char **		afeXFontList;	/* from XListFonts()		*/
179     int			afeXFontCount;	/* from XListFonts()		*/
180     } AppFontEncoding;
181 
182 static AppFontEncoding	AppFontXEncodings[]=
183 {
184 
185     { "iso10646-1",		2, },
186 
187     { "iso8859-15",		1, uniIso8859_15GlyphUnicodes,	},
188     { "iso8859-2",		1, uniIso8859_2GlyphUnicodes,	},
189     { "iso8859-5",		1, uniIso8859_5GlyphUnicodes,	},
190     { "iso8859-7",		1, uniIso8859_7GlyphUnicodes,	},
191     { "iso8859-9",		1, uniIso8859_9GlyphUnicodes,	},
192     { "iso8859-13",		1, uniIso8859_13GlyphUnicodes,	},
193     { "koi8-u",			1, uniKoi8RGlyphUnicodes,	},
194     { "koi8-r",			1, uniKoi8RGlyphUnicodes,	},
195     { "iso8859-1",		1, uniIso8859_1GlyphUnicodes,	},
196     { "adobe-fontspecific",	1, },
197     { "urw-fontspecific",	1, },
198 
199 };
200 
201 static const int AppFontXEncodingCount=
202 			    sizeof(AppFontXEncodings)/sizeof(AppFontEncoding);
203 
204 /************************************************************************/
205 /*									*/
206 /*  Make a font query string.						*/
207 /*									*/
208 /************************************************************************/
209 
appFontQueryString(char * target,const char * foundry,const char * family,const char * weight,const char * slant,const char * swdth,const char * pxlsz,const char * registry_encoding)210 static void appFontQueryString(	char *		target,
211 				const char *	foundry,
212 				const char *	family,
213 				const char *	weight,
214 				const char *	slant,
215 				const char *	swdth,
216 				const char *	pxlsz,
217 				const char *	registry_encoding )
218     {
219     const char *	anySizeTemplate= EditFontAnyTemplate;
220 
221     /*  Cope with silly Xlib */
222     if  ( ! strcmp( pxlsz, "0" ) )
223 	{ anySizeTemplate= "0";	}
224 
225     sprintf( target, EditFontFamilyTemplate,
226 		foundry,
227 		family,
228 		weight,
229 		slant,
230 		swdth,			/* swdth		*/
231 		EditFontAnyTemplate,	/* adstyl		*/
232 		pxlsz,
233 		anySizeTemplate,	/* ptsz			*/
234 		anySizeTemplate,	/* resx			*/
235 		anySizeTemplate,	/* resy			*/
236 		EditFontAnyTemplate,	/* spacing		*/
237 		EditFontAnyTemplate,	/* average width	*/
238 		registry_encoding );
239 
240     return;
241     }
242 
243 /************************************************************************/
244 /*									*/
245 /*  Extract properties from an X font selection string.			*/
246 /*									*/
247 /************************************************************************/
248 
appFontExtractString(const char * s,const char ** pPast,char * target)249 static int appFontExtractString(	const char *	s,
250 					const char **	pPast,
251 					char *		target )
252     {
253     if  ( *s != '-' )
254 	{ SDEB(s); return -1;	}
255     s++;
256     while( *s && *s != '-' )
257 	{ *(target++)= *(s++); }
258     *target= '\0';
259 
260     *pPast= s; return 0;
261     }
262 
appFontSkipString(const char * s,const char ** pPast)263 static int appFontSkipString(	const char *	s,
264 				const char **	pPast )
265     {
266     if  ( *s != '-' )
267 	{ SDEB(s); return -1;	}
268     s++;
269     while( *s && *s != '-' )
270 	{ s++; }
271 
272     *pPast= s; return 0;
273     }
274 
appFontSplitXFont(const char * fontname,char * foundry,char * family,char * weight,char * slant,char * swdth,char * pxlszStr,char * spacing,char * avgwdth,char * registry,char * encoding)275 static int appFontSplitXFont(	const char *	fontname,
276 				char *		foundry,
277 				char *		family,
278 				char *		weight,
279 				char *		slant,
280 				char *		swdth,
281 				char *		pxlszStr,
282 				char *		spacing,
283 				char *		avgwdth,
284 				char *		registry,
285 				char *		encoding )
286     {
287     const char *	s;
288 
289     s= fontname;
290 
291     if  ( appFontExtractString( s, &s, foundry ) )
292 	{ SDEB(fontname); return -1;	}
293 
294     if  ( appFontExtractString( s, &s, family ) )
295 	{ SDEB(fontname); return -1;	}
296 
297     if  ( appFontExtractString( s, &s, weight ) )
298 	{ SDEB(fontname); return -1;	}
299 
300     if  ( appFontExtractString( s, &s, slant ) )
301 	{ SDEB(fontname); return -1;	}
302 
303     if  ( appFontExtractString( s, &s, swdth ) )
304 	{ SDEB(fontname); return -1;	}
305 
306     if  ( appFontSkipString( s, &s ) ) /* adstyl */
307 	{ SDEB(fontname); return -1;	}
308 
309     if  ( appFontExtractString( s, &s, pxlszStr ) )
310 	{ SDEB(fontname); return -1;	}
311 
312     if  ( appFontSkipString( s, &s ) ) /* ptsz */
313 	{ SDEB(fontname); return -1;	}
314 
315     if  ( appFontSkipString( s, &s ) ) /* resx */
316 	{ SDEB(fontname); return -1;	}
317 
318     if  ( appFontSkipString( s, &s ) ) /* resy */
319 	{ SDEB(fontname); return -1;	}
320 
321     if  ( appFontExtractString( s, &s, spacing ) )
322 	{ SDEB(fontname); return -1;	}
323 
324     if  ( appFontExtractString( s, &s, avgwdth ) )
325 	{ SDEB(fontname); return -1;	}
326 
327     if  ( appFontExtractString( s, &s, registry ) )
328 	{ SDEB(fontname); return -1;	}
329 
330     if  ( appFontExtractString( s, &s, encoding ) )
331 	{ SDEB(fontname); return -1;	}
332 
333     if  ( s[0] )
334 	{ SSDEB(fontname,s); return -1;	}
335 
336     return 0;
337     }
338 
339 /************************************************************************/
340 /*									*/
341 /*  Make a catalog of X11 fonts.					*/
342 /*									*/
343 /************************************************************************/
344 
appCmpFacePixelSizes(const void * vxffs1,const void * vxffs2)345 static int appCmpFacePixelSizes(	const void *	vxffs1,
346 					const void *	vxffs2 )
347     {
348     const XFontFaceSize *	xffs1= (const XFontFaceSize *)vxffs1;
349     const XFontFaceSize *	xffs2= (const XFontFaceSize *)vxffs2;
350 
351     if  ( xffs1->xffsPixelSize > xffs2->xffsPixelSize )
352 	{ return  1; }
353 
354     if  ( xffs1->xffsPixelSize < xffs2->xffsPixelSize )
355 	{ return -1; }
356 
357     return 0;
358     }
359 
appFontXCatalog(Display * display,AppFontEncoding * afe)360 static int appFontXCatalog(	Display *		display,
361 				AppFontEncoding *	afe )
362     {
363     char			fontFormat[120];
364 
365     int				idx;
366 
367     XFontFamily *		xff;
368     XFontTypeface *		xft;
369     int				fam;
370     int				face;
371 
372     if  ( afe->afeXFontList )
373 	{ return 0;	}
374 
375     appFontQueryString( fontFormat,
376 		EditFontAnyTemplate,	/* foundry,		*/
377 		EditFontAnyTemplate,	/* family,		*/
378 		EditFontAnyTemplate,	/* weight,		*/
379 		EditFontAnyTemplate,	/* slant,		*/
380 		EditFontAnyTemplate,	/* swdth,		*/
381 		EditFontAnyTemplate,	/* pxlsz,		*/
382 		afe->feX11Reg_Enc );	/* registry,encoding	*/
383 
384     afe->afeXFontList= XListFonts( display, fontFormat,
385 						4000, &(afe->afeXFontCount) );
386     if  ( afe->afeXFontCount == 4000 )
387 	{ LLDEB(afe->afeXFontCount,4000);	}
388 
389     for ( idx= 0; idx < afe->afeXFontCount; idx++ )
390 	{
391 	char			foundry[40];
392 	char			family[40];
393 
394 	char			weightStr[40];
395 	char			slantStr[40];
396 	char			swdthStr[40];
397 
398 	char			ignore[40];
399 	char			spacing[40];
400 	char			avgwdth[40];
401 
402 	char			pxlszStr[40];
403 	int			pxlsz;
404 	int			swdth;
405 
406 	if  ( strlen( afe->afeXFontList[idx] ) >= X_FONTNAME_MAX )
407 	    { SDEB(afe->afeXFontList[idx]); continue; }
408 
409 	if  ( appFontSplitXFont( afe->afeXFontList[idx],
410 					foundry,
411 					family,
412 					weightStr,
413 					slantStr,
414 					swdthStr,
415 					pxlszStr,
416 					spacing,
417 					avgwdth,
418 					ignore,		/*  registry  */
419 					ignore ) )	/*  encoding  */
420 	    { LSDEB(idx,afe->afeXFontList[idx]); continue;	}
421 
422 	if  ( strcmp( spacing, "m" ) && strcmp( spacing, "p" ) )
423 	    {
424 	    if  ( strcmp( spacing, "c" ) )
425 		{ SSDEB(spacing,afe->afeXFontList[idx]);	}
426 
427 	    continue;
428 	    }
429 
430 	if  ( strcmp( pxlszStr, "0" ) && ! strcmp( avgwdth, "0" ) )
431 	    { /*SSDEB(pxlszStr,avgwdth);*/ continue;	}
432 
433 	if  ( psFontGetWidth( &swdth, swdthStr ) )
434 	    { SSDEB(swdthStr,afe->afeXFontList[idx]); continue;	}
435 
436 	xff= afe->afeXfontFamilies;
437 	for ( fam= 0; fam < afe->afeXfontFamilyCount; xff++, fam++ )
438 	    {
439 	    if  ( ! strcmp( xff->xffFamily, family )	&&
440 		  ! strcmp( xff->xffFoundry, foundry )	&&
441 		  xff->xffSwdth == swdth		)
442 		{ break;	}
443 	    }
444 
445 	if  ( fam >= afe->afeXfontFamilyCount )
446 	    {
447 	    char *	s;
448 
449 	    xff= (XFontFamily *)realloc( afe->afeXfontFamilies,
450 			(afe->afeXfontFamilyCount+1)* sizeof(XFontFamily) );
451 	    if  ( ! xff )
452 		{ LXDEB(afe->afeXfontFamilyCount,xff); return -1;	}
453 	    afe->afeXfontFamilies= xff;
454 
455 	    xff += afe->afeXfontFamilyCount;
456 
457 	    appInitXFontFamily( xff );
458 
459 	    xff->xffFamily= strdup( family );
460 	    xff->xffFamilyLower= strdup( family );
461 	    xff->xffFoundry= strdup( foundry );
462 	    xff->xffSwdth= swdth;
463 
464 	    if  ( ! xff->xffFamily	||
465 		  ! xff->xffFoundry	||
466 		  ! xff->xffFamilyLower	)
467 		{
468 		XXDEB(xff->xffFamily,xff->xffFoundry);
469 		appCleanXFontFamily( xff );
470 		return -1;
471 		}
472 
473 	    s= xff->xffFamilyLower;
474 	    while( *s )
475 		{ *s= tolower( *s ); s++;	}
476 
477 	    afe->afeXfontFamilyCount++;
478 	    }
479 
480 	xft= xff->xffFaces;
481 	for ( face= 0; face < xff->xffFaceCount; xft++, face++ )
482 	    {
483 	    if  ( ! strcmp( xft->xftWeightStr, weightStr )	&&
484 		  ! strcmp( xft->xftSlantStr, slantStr )	)
485 		{ break;	}
486 	    }
487 
488 	if  ( face >= xff->xffFaceCount )
489 	    {
490 	    xft= (XFontTypeface *)realloc( xff->xffFaces,
491 				(xff->xffFaceCount+1)* sizeof(XFontTypeface) );
492 	    if  ( ! xft )
493 		{ LXDEB(xff->xffFaceCount,xft); return -1;	}
494 	    xff->xffFaces= xft;
495 
496 	    xft += xff->xffFaceCount;
497 
498 	    appInitXFontTypeface( xft );
499 
500 	    if  ( psFontGetWeight( &(xft->xftWeight), weightStr ) )
501 		{ SSDEB(afe->afeXFontList[idx],weightStr); continue;	}
502 
503 	    if  ( xft->xftWeight > FONTweightMEDIUM )
504 		{ xft->xftIsBold= 1;	}
505 	    else{ xft->xftIsBold= 0;	}
506 
507 	    if  ( strcmp( slantStr, "r" )	)
508 		{
509 		if  ( ! strcmp( slantStr, "i" )	||
510 		      ! strcmp( slantStr, "o" )	)
511 		    { xft->xftIsSlanted= 1;	}
512 		else{ SDEB(slantStr); continue;		}
513 		}
514 
515 	    xft->xftIsScalable= 0;
516 	    xft->xftIsFixedWidth= ! strcmp( spacing, "m" );
517 
518 	    xft->xftWeightStr= strdup( weightStr );
519 	    xft->xftSlantStr= strdup( slantStr );
520 	    if  ( ! xft->xftWeightStr || ! xft->xftSlantStr )
521 		{
522 		XXDEB(xft->xftWeightStr,xft->xftSlantStr);
523 		appCleanXFontTypeface( xft );
524 		return -1;
525 		}
526 
527 	    xff->xffFaceCount++;
528 	    }
529 
530 	pxlsz= atoi( pxlszStr );
531 	if  ( pxlsz == 0 )
532 	    {
533 	    xft->xftIsScalable= 1;
534 	    xft->xftScalableListIndex= idx;
535 	    }
536 	else{
537 	    XFontFaceSize *	xffs= xft->xftFaceSizes;
538 	    int			sz;
539 
540 	    for ( sz= 0; sz < xft->xftFaceSizeCount; xffs++, sz++ )
541 		{
542 		if  ( xffs->xffsPixelSize == pxlsz )
543 		    { break;	}
544 		}
545 
546 	    /* duplicate? */
547 	    if  ( sz < xft->xftFaceSizeCount )
548 		{
549 		/*
550 		SLLSDEB("DUPLICATE",idx,sz,afe->afeXFontList[idx]);
551 		LSDEB(xffs->xffsListIndex,
552 				afe->afeXFontList[xffs->xffsListIndex]);
553 		*/
554 		continue;
555 		}
556 
557 	    xffs= (XFontFaceSize *)realloc( xft->xftFaceSizes,
558 			( xft->xftFaceSizeCount+ 1 )* sizeof( XFontFaceSize ) );
559 	    if  ( ! xffs )
560 		{ LXDEB(xft->xftFaceSizeCount,xffs); return -1;	}
561 	    xft->xftFaceSizes= xffs;
562 
563 	    xffs += xft->xftFaceSizeCount;
564 
565 	    appInitXFontFaceSize( xffs );
566 
567 	    xffs->xffsPixelSize= pxlsz;
568 	    xffs->xffsListIndex= idx;
569 
570 	    xft->xftFaceSizeCount++;
571 	    }
572 	}
573 
574     xff= afe->afeXfontFamilies;
575     for ( fam= 0; fam < afe->afeXfontFamilyCount; xff++, fam++ )
576 	{
577 	xft= xff->xffFaces;
578 	for ( face= 0; face < xff->xffFaceCount; xft++, face++ )
579 	    {
580 	    if  ( xft->xftFaceSizeCount > 1 )
581 		{
582 		qsort( xft->xftFaceSizes, xft->xftFaceSizeCount,
583 				sizeof(XFontFaceSize), appCmpFacePixelSizes );
584 		}
585 	    }
586 	}
587 
588     /* NO! XFreeFontNames( afe->afeXFontList ); */
589 
590     return 0;
591     }
592 
593 /************************************************************************/
594 /*									*/
595 /*  Find an X11 font with a postscript style font.			*/
596 /*									*/
597 /*  1)  Obtain a list of the available X11 fonts.			*/
598 /*  2)  Try to find an almost exact match on the family name.		*/
599 /*	Have a preference for fonts with a foundry.			*/
600 /*  3)  Do not rely too much on scalable fonts. They look ugly and do	*/
601 /*	not always work transparently with remote displays.		*/
602 /*									*/
603 /*  a)  Scalable fonts tend to be a little wider than the corresponding	*/
604 /*	PostScript fonts. Just subtract a pixel.			*/
605 /*									*/
606 /************************************************************************/
607 
appFontXFontUsingQuery(char * target,const char * queryFormat,int pixelSize)608 static int appFontXFontUsingQuery(	char *			target,
609 					const char *		queryFormat,
610 					int			pixelSize )
611     {
612     const char *	before= queryFormat;
613     const char *	after;
614     int			beforeSize;
615     int			afterSize;
616     int			i;
617 
618     /*  a  */
619     if  ( 0 && pixelSize > 10 )
620 	{ pixelSize--;	}
621 
622     if  ( *before != '-' )
623 	{ SDEB(queryFormat); return -1; }
624 
625     for ( i= 0; i < 6; i++ )
626 	{
627 	before= strchr( before+ 1, '-' );
628 	if  ( ! before )
629 	    { SDEB(queryFormat); return -1;	}
630 	}
631 
632     after= strchr( before+ 1, '-' );
633     if  ( ! after )
634 	{ SDEB(queryFormat); return -1;	}
635 
636     beforeSize= before- queryFormat+ 1;
637     afterSize= strlen( after );
638     if  ( beforeSize+ 3+ afterSize >= X_FONTNAME_MAX )
639 	{ SDEB(queryFormat); return -1;	}
640 
641     memcpy( target, queryFormat, beforeSize );
642     sprintf( target+ beforeSize, "%d", pixelSize );
643     strcpy( target+ strlen( target ), after );
644 
645     return 0;
646     }
647 
648 /************************************************************************/
649 /*									*/
650 /*  Make an estimate of the similarity of an X11 font family and a	*/
651 /*  PostScript font family. All we have is the names and the set width.	*/
652 /*  If results depend on the details of this routine, something else	*/
653 /*  is wrong: System configuration. But evidently, tweaking a little	*/
654 /*  does no harm.							*/
655 /*									*/
656 /************************************************************************/
657 
appFontX11ScoreSimilarity(const XFontFamily * xff,const char * psName,int psNameLen,int psWidth)658 static int appFontX11ScoreSimilarity(	const XFontFamily *	xff,
659 					const char *		psName,
660 					int			psNameLen,
661 					int			psWidth )
662     {
663     int		common;
664     int		wdif;
665     int		wrange= FONTwidth_MAX- FONTwidth_MIN;
666 
667     common= utilLongestCommonSubstring( xff->xffFamilyLower, psName );
668     if  ( common < 5 && common < ( 2* psNameLen )/ 3 )
669 	{ return 0;	}
670 
671     wdif= psWidth- xff->xffSwdth;
672     if  ( wdif < 0 )
673 	{ wdif= -wdif;	}
674 
675     return ( 100* common )/ psNameLen+
676 				( 30* ( wrange- wdif ) )/ wrange;
677     }
678 
679 /************************************************************************/
680 /*									*/
681 /*  Determine the X11 font name to use with a particular document font.	*/
682 /*									*/
683 /************************************************************************/
684 
appFontXFontName(char * target,Display * display,const AfmFontInfo * afi,AppFontEncoding * afe,int anyFont,int pixelSize,const char * psName,int psNameLen,int psWidth)685 static int appFontXFontName(	char *			target,
686 				Display *		display,
687 				const AfmFontInfo *	afi,
688 				AppFontEncoding *	afe,
689 				int			anyFont,
690 				int			pixelSize,
691 				const char *		psName,
692 				int			psNameLen,
693 				int			psWidth )
694     {
695     const XFontFamily *		xff= (const XFontFamily *)0;
696     const XFontTypeface *	xft;
697 
698     int				fam= 0;
699     int				face;
700 
701     const char *		t1Entry= (const char *)0;
702     const char *		scalableEntry= (const char *)0;
703 
704     int				best;
705     int				f;
706 
707     if  ( ! afi || ! afe )
708 	{ XXDEB(afi,afe); return -1;	}
709 
710     if  ( afe->feX11Reg_Enc_Strlen == 0 )
711 	{ afe->feX11Reg_Enc_Strlen= strlen( afe->feX11Reg_Enc );	}
712 
713     for ( f= 0; f < afi->afiX11FontCount; f++ )
714 	{
715 	int		l11= strlen( afi->afiX11Fonts[f] );
716 	int		o11= l11- afe->feX11Reg_Enc_Strlen;
717 
718 	if  ( o11 > 0							&&
719 	      afi->afiX11Fonts[f][o11-1] == '-'				&&
720 	      ! strcmp( afi->afiX11Fonts[f]+ o11, afe->feX11Reg_Enc )	)
721 	    { t1Entry= afi->afiX11Fonts[f]; break;	}
722 	}
723 
724     /*  1  */
725     appFontXCatalog( display, afe );
726 
727     if  ( ! afe->afeXfontFamilies )
728 	{ return -1;	}
729 
730     /*  2  */
731     xff= afe->afeXfontFamilies;
732     best= 0;
733     fam= -1;
734     for ( f= 0; f < afe->afeXfontFamilyCount; xff++, f++ )
735 	{
736 	int	score;
737 
738 	score= appFontX11ScoreSimilarity( xff, psName, psNameLen, psWidth );
739 
740 	if  ( score > best )
741 	    { fam= f; best= score;	}
742 	}
743 
744     if  ( fam < 0 )
745 	{
746 	if  ( t1Entry )
747 	    {
748 	    if  ( appFontXFontUsingQuery( target, t1Entry, pixelSize ) )
749 		{ SDEB(t1Entry); return -1;	}
750 
751 	    return 0;
752 	    }
753 
754 	/* Arbitrarily pick first one */
755 	if  ( anyFont )
756 	    { fam= 0;		}
757 	else{ return 1;		}
758 	}
759 
760     xff= afe->afeXfontFamilies+ fam;
761 
762     {
763     int		faceFound= xff->xffFaceCount;
764     int		difCountFound= 999;
765     double	distanceFound= 999;
766 
767     xft= xff->xffFaces;
768     for ( face= 0; face < xff->xffFaceCount; xft++, face++ )
769 	{
770 	int		difCount;
771 	double		distance;
772 
773 	psFontFaceDistance( &difCount, &distance, afi,
774 					xft->xftIsSlanted, xft->xftWeight );
775 
776 	if  ( difCount < difCountFound		&&
777 	      difCount < 2			&&
778 	      distance < distanceFound		&&
779 	      distance < 0.3			)
780 	    {
781 	    faceFound= face;
782 	    difCountFound= difCount;
783 	    distanceFound= distance;
784 	    }
785 	}
786 
787     if  ( faceFound >= xff->xffFaceCount )
788 	{
789 	if  ( t1Entry )
790 	    {
791 	    if  ( appFontXFontUsingQuery( target, t1Entry, pixelSize ) )
792 		{ SDEB(t1Entry); return -1;	}
793 
794 	    return 0;
795 	    }
796 
797 	if  ( anyFont && xff->xffFaceCount > 0 )
798 	    { faceFound= 0;	}
799 	else{ return 1;		}
800 	}
801 
802     face= faceFound;
803     xft= xff->xffFaces+ face;
804     }
805 
806     /*  8  */
807     if  ( xft->xftFaceSizeCount > 0 )
808 	{
809 	int		i;
810 	int		s;
811 	int		dv;
812 
813 	for ( i= 0; i < xft->xftFaceSizeCount; i++ )
814 	    {
815 	    if  ( xft->xftFaceSizes[i].xffsPixelSize >= pixelSize )
816 		{ break;	}
817 	    }
818 
819 	if  ( i >= xft->xftFaceSizeCount )
820 	    { i= xft->xftFaceSizeCount-1;	}
821 
822 	if  ( i > 0						&&
823 	      xft->xftFaceSizes[i].xffsPixelSize > pixelSize	)
824 	    {
825 	    int		d0;
826 	    int		d1;
827 
828 	    d0= ( 100* pixelSize )/ xft->xftFaceSizes[i-1].xffsPixelSize;
829 	    d1= ( 100* xft->xftFaceSizes[i].xffsPixelSize )/ pixelSize;
830 
831 	    if  ( d1 > 105 || d0 < d1 )
832 		{ i--;	}
833 	    }
834 
835 	s= xft->xftFaceSizes[i].xffsPixelSize;
836 	if  ( s >= pixelSize )
837 	    { dv= ( 100* s )/ pixelSize;	}
838 	else{ dv= ( 100* pixelSize )/ s;	}
839 
840 	if  ( dv <= 115					||
841 	      ( ! t1Entry			&&
842 	        xft->xftScalableListIndex < 0	)	)
843 	    {
844 	    int	idx= xft->xftFaceSizes[i].xffsListIndex;
845 
846 	    if  ( strlen( afe->afeXFontList[idx] ) >= X_FONTNAME_MAX )
847 		{ SDEB(afe->afeXFontList[idx]); }
848 
849 	    strcpy( target, afe->afeXFontList[idx] );
850 
851 	    return 0;
852 	    }
853 	}
854 
855     if  ( t1Entry )
856 	{ scalableEntry= t1Entry;	}
857     else{
858 	if  ( xft->xftScalableListIndex < 0 )
859 	    { LDEB(xft->xftScalableListIndex); return -1;	}
860 
861 	scalableEntry= afe->afeXFontList[xft->xftScalableListIndex];
862 	}
863 
864     if  ( appFontXFontUsingQuery( target, scalableEntry, pixelSize ) )
865 	{ SLDEB(scalableEntry,pixelSize); return -1;	}
866 
867     return 0;
868     }
869 
870 /************************************************************************/
871 
appFontGetEncodingInfo(const IndexMapping ** pIm,const IndexSet ** pIs,const int ** pUnicodes,AppFontEncoding * fe,const char * fontName)872 static int appFontGetEncodingInfo(	const IndexMapping **	pIm,
873 					const IndexSet **	pIs,
874 					const int **		pUnicodes,
875 					AppFontEncoding *	fe,
876 					const char *		fontName )
877     {
878     IndexMapping *	im= &(fe->feSymbolToByteMapping);
879     IndexSet *		is= &(fe->feSymbolSet);
880     const int *		unicodes= fe->feGlyphUnicodes;
881 
882     if  ( fe->feBytesPerChar == 1 && ! unicodes )
883 	{
884 	if  ( ! strcmp( fontName, "ITC Zapf Dingbats" ) ||
885 	      ! strcmp( fontName, "ZapfDingbats" )	||
886 	      ! strcmp( fontName, "Dingbats" )	)
887 	    {
888 	    im= &UNI_DingbatsToGlyphMapping;
889 	    is= &UNI_DingbatsCodeSet;
890 	    unicodes= uniDingbatsGlyphUnicodes;
891 	    }
892 	else{
893 	    if  ( ! strcmp( fontName, "Symbol" ) )
894 		{
895 		im= &UNI_SymbolToGlyphMapping;
896 		is= &UNI_SymbolCodeSet;
897 		unicodes= uniSymbolGlyphUnicodes;
898 		}
899 	    else{ /*SDEB(fontName);*/ return 1;		}
900 	    }
901 	}
902 
903     if  ( unicodes && utilIndexMappingIsEmpty( im ) )
904 	{
905 	if  ( utilIndexMappingBuildBackward( im, unicodes, 256 )	)
906 	    { LDEB(1); return -1;	}
907 	if  ( utilIndexSetAddArray( is, unicodes, 256 )	)
908 	    { LDEB(1); return -1;	}
909 	}
910 
911     *pUnicodes= unicodes;
912     *pIm= im;
913     *pIs= is;
914     return 0;
915     }
916 
917 /************************************************************************/
918 
appXfontHasCode(const XFontStruct * xfs,int code)919 static int appXfontHasCode(	const XFontStruct *	xfs,
920 				int			code )
921     {
922     int		min_byte= xfs->min_char_or_byte2;
923     int		max_byte= xfs->max_char_or_byte2;
924     int		offset;
925 
926     if  ( xfs->min_byte1 == 0 && xfs->max_byte1 == 0 )
927 	{
928 	if  ( code < min_byte || code > max_byte )
929 	    { return 0;	}
930 
931 	offset= code- min_byte;
932 	}
933     else{
934 	int	D= max_byte- min_byte+ 1;
935 	int	byte1= code/ D;
936 	int	byte2= code% D;
937 
938 	if  ( byte1 < xfs->min_byte1 || byte1 > xfs->max_byte1 )
939 	    { return 0;	}
940 	if  ( byte2 < min_byte || byte2 > max_byte )
941 	    { return 0;	}
942 
943 	offset= D* ( byte1- xfs->min_byte1 )+ code- min_byte;
944 	}
945 
946     if  ( xfs->all_chars_exist )
947 	{ return 1;	}
948     if  ( ! xfs->per_char )
949 	{
950 	/*LLXDEB(xfs->all_chars_exist,offset,xfs->per_char);*/
951 	return 1;
952 	}
953 
954     return xfs->per_char[offset].width > 0;
955     }
956 
957 /************************************************************************/
958 
appXFontSymbols(EncodedScreenFontList * esfl,const EncodedScreenFont * sf,IndexSet * isRequired,const int * unicodes,int font)959 static void appXFontSymbols(	EncodedScreenFontList *		esfl,
960 				const EncodedScreenFont *	sf,
961 				IndexSet *			isRequired,
962 				const int *			unicodes,
963 				int				font )
964     {
965     const XFontStruct *	xfs;
966 
967 #   ifdef USE_MOTIF
968     xfs= sf->esfFontStruct;
969 #   endif
970 
971 #   ifdef USE_GTK
972 #   if GTK_MAJOR_VERSION >= 2
973     xfs= (XFontStruct *)gdk_x11_font_get_xfont( sf->esfFontStruct );
974 #   else
975     xfs= GDK_FONT_XFONT( sf->esfFontStruct );
976 #   endif
977 #   endif
978 
979     if  ( unicodes )
980 	{
981 	int		code;
982 
983 	for ( code= 0; code < 256; code++ )
984 	    {
985 	    int	symbol= unicodes[code];
986 
987 	    if  ( symbol < 0 || ! appXfontHasCode( xfs, code ) )
988 		{ continue;	}
989 
990 	    if  ( utilIndexMappingGet( &(esfl->esflSymbolToFont), symbol )
991 									>= 0 )
992 		{ continue;	}
993 
994 	    if  ( utilIndexMappingPut( &(esfl->esflSymbolToFont),
995 							    symbol, font ) )
996 		{ LLDEB(symbol,font);	}
997 
998 	    utilIndexSetRemove( isRequired, symbol );
999 	    }
1000 	}
1001     else{
1002 	if  ( sf->esfIsTwoByte )
1003 	    {
1004 	    int		symbol;
1005 
1006 	    for ( symbol= 0; symbol < 256* 256; symbol++ )
1007 		{
1008 		if  ( appXfontHasCode( xfs, symbol ) )
1009 		    {
1010 		    if  ( utilIndexMappingGet( &(esfl->esflSymbolToFont),
1011 								symbol ) >= 0 )
1012 			{ continue;	}
1013 
1014 		    if  ( utilIndexMappingPut( &(esfl->esflSymbolToFont),
1015 							    symbol, font ) )
1016 			{ LLDEB(symbol,font);	}
1017 
1018 		    utilIndexSetRemove( isRequired, symbol );
1019 		    }
1020 		}
1021 	    }
1022 	else{ LDEB(sf->esfIsTwoByte);	}
1023 	}
1024 
1025     return;
1026     }
1027 
1028 /************************************************************************/
1029 
appFontX11TryEncoding(EncodedScreenFont * sf,EncodedScreenFontList * esfl,DrawScreenFont * dsf,int font,AppFontEncoding * fe,const AfmFontInfo * afi,int sizePixels,const char * psName,int psNameLen,int psWidth,int anyFont,IndexSet * isRequired)1030 static int appFontX11TryEncoding(	EncodedScreenFont *	sf,
1031 					EncodedScreenFontList *	esfl,
1032 					DrawScreenFont *	dsf,
1033 					int			font,
1034 					AppFontEncoding *	fe,
1035 					const AfmFontInfo *	afi,
1036 					int			sizePixels,
1037 					const char *		psName,
1038 					int			psNameLen,
1039 					int			psWidth,
1040 					int			anyFont,
1041 					IndexSet *		isRequired )
1042     {
1043     int				rval= 0;
1044     int				res;
1045 
1046     const IndexMapping *	im;
1047     const IndexSet *		isProvided;
1048     const int *			unicodes;
1049 
1050     IndexSet			isCandidate;
1051 
1052     utilInitIndexSet( &isCandidate );
1053 
1054     res= appFontGetEncodingInfo( &im, &isProvided, &unicodes,
1055 						fe, afi->afiFamilyName );
1056     if  ( res < 0 )
1057 	{ LDEB(res); rval= -1; goto ready;	}
1058     if  ( res > 0 )
1059 	{ rval= 1; goto ready;			}
1060 
1061     utilCleanIndexSet( &isCandidate );
1062     utilInitIndexSet( &isCandidate );
1063     res= utilIndexSetIntersect( &isCandidate, isRequired, isProvided );
1064     if  ( res < 0 )
1065 	{ LDEB(res); rval= -1; goto ready;	}
1066     if  ( res == 0 )
1067 	{ rval= 1; goto ready;			}
1068 
1069     if  ( appFontXFontName( sf->esfFontName, dsf->dsfDisplay, afi, fe, anyFont,
1070 				    sizePixels, psName, psNameLen, psWidth ) )
1071 	{ rval= 1; goto ready;	}
1072 
1073     if  ( ! dsf->apfFontName[0] )
1074 	{
1075 	if  ( strlen( sf->esfFontName ) >= X_FONTNAME_MAX )
1076 	    { SDEB(sf->esfFontName);				}
1077 	else{ strcpy( dsf->apfFontName, sf->esfFontName );	}
1078 	}
1079 
1080     sf->esfIsTwoByte= fe->feBytesPerChar == 2;
1081     sf->esfSymbolToByteMapping= im;
1082 
1083 #   ifdef USE_MOTIF
1084     sf->esfFontStruct= XLoadQueryFont( dsf->dsfDisplay, sf->esfFontName );
1085 #   endif
1086 
1087 #   ifdef USE_GTK
1088     sf->esfFontStruct= gdk_font_load( sf->esfFontName );
1089 #   endif
1090 
1091     if  ( ! sf->esfFontStruct )
1092 	{
1093 	SXDEB(sf->esfFontName,sf->esfFontStruct);
1094 	drawCleanEncodedScreenFont( dsf, sf );
1095 	drawInitEncodedScreenFont( sf );
1096 	rval= 1; goto ready;
1097 	}
1098 
1099     appXFontSymbols( esfl, sf, isRequired, unicodes, font );
1100 
1101   ready:
1102 
1103     utilCleanIndexSet( &isCandidate );
1104 
1105     return rval;
1106     }
1107 
1108 /************************************************************************/
1109 /*									*/
1110 /*  Get the X font with a font.						*/
1111 /*									*/
1112 /*  1)  Determine the full font height in pixels.			*/
1113 /*  2)  Open the font for normal use.					*/
1114 /*  3)  Obtain some font properties.					*/
1115 /*  4)  Try to obtain a slightly smaller font for smallcaps.		*/
1116 /*									*/
1117 /************************************************************************/
1118 
1119 # define SFCOUNT 12
1120 
appFontOpenX11Fonts(DrawScreenFont * dsf)1121 int appFontOpenX11Fonts(	DrawScreenFont *		dsf )
1122     {
1123     int				rval= 0;
1124     const AfmFontInfo *		afi= dsf->apfPsFontInfo;
1125     char			psName[120+1];
1126     int				psNameLen;
1127     int				psWidth= FONTwidthNORMAL;
1128 
1129     int				count= 0;
1130     int				encIdx;
1131 
1132     EncodedScreenFontList *	esfl;
1133     EncodedScreenFont *		esfs= (EncodedScreenFont *)0;
1134     EncodedScreenFont *		sf;
1135 
1136     EncodedScreenFont		screenFonts[2*SFCOUNT];
1137 
1138     int				anyFont;
1139     IndexSet			isRequired;
1140 
1141     utilInitIndexSet( &isRequired );
1142 
1143     if  ( ! dsf )
1144 	{ XDEB(dsf); return -1;	}
1145     esfl= &(dsf->dsfEncodedFonts);
1146 
1147     for ( encIdx= 0; encIdx < AppFontXEncodingCount; encIdx++ )
1148 	{ drawInitEncodedScreenFont( screenFonts+ encIdx );	}
1149 
1150     if  ( AppFontXEncodingCount != SFCOUNT )
1151 	{ LLDEB(AppFontXEncodingCount,SFCOUNT);	}
1152 
1153     if  ( psRemoveWidthFromName( psName, sizeof(psName)- 1, &psWidth,
1154 						    afi->afiFamilyName ) < 0 )
1155 	{ SDEB(afi->afiFamilyName); rval= -1; goto ready;	}
1156     for ( psNameLen= 0; psName[psNameLen]; psNameLen++ )
1157 	{ psName[psNameLen]= tolower( psName[psNameLen] ); }
1158 
1159     if  ( dsf->dsfUnicodesUsed )
1160 	{
1161 	if  ( utilCopyIndexSet( &isRequired, dsf->dsfUnicodesUsed ) < 0 )
1162 	    { LDEB(1); return -1;	}
1163 	}
1164 
1165     /*  2  */
1166     sf= screenFonts;
1167     for ( anyFont= 0; anyFont <= 1; anyFont++ )
1168 	{
1169 	AppFontEncoding *	fe= AppFontXEncodings;
1170 
1171 	for ( encIdx= 0; encIdx < AppFontXEncodingCount; fe++, encIdx++ )
1172 	    {
1173 	    int			res;
1174 
1175 	    res= appFontX11TryEncoding( sf, esfl, dsf, count, fe, afi,
1176 					dsf->dsfSizePixels, psName, psNameLen,
1177 					psWidth, anyFont, &isRequired );
1178 	    if  ( res < 0 )
1179 		{ LDEB(res); rval= -1; goto ready;	}
1180 	    if  ( res > 0 )
1181 		{ continue;			}
1182 
1183 	    count++; sf++;
1184 	    }
1185 	}
1186 
1187     if  ( count == 0 )
1188 	{
1189 	SLLDEB(afi->afiFamilyName,dsf->dsfSizePixels,count);
1190 	rval= -1; goto ready;
1191 	}
1192 
1193     esfs= malloc( count * sizeof(EncodedScreenFont) );
1194     if  ( ! esfs )
1195 	{ LXDEB(count,esfs); rval= -1; goto ready;	}
1196 
1197     for ( encIdx= 0; encIdx < count; encIdx++ )
1198 	{ esfs[encIdx]= screenFonts[encIdx]; }
1199 
1200     esfl->esfFonts= esfs; esfs= (EncodedScreenFont *)0; /* steal*/
1201     esfl->esfFontCount= count; count= 0; /* steal */
1202 
1203   ready:
1204 
1205     utilCleanIndexSet( &isRequired );
1206 
1207     if  ( esfs )
1208 	{
1209 	for ( encIdx= 0; encIdx < count; encIdx++ )
1210 	    { drawCleanEncodedScreenFont( dsf, esfs+ encIdx );	}
1211 
1212 	free( esfs );
1213 	}
1214 
1215     return rval;
1216     }
1217 
1218 /************************************************************************/
1219 /*									*/
1220 /*  Find the X11 fonts corresponding to the PostScript fonts in a font	*/
1221 /*  list. The match is made on the basis of the full name of the fonts.	*/
1222 /*									*/
1223 /************************************************************************/
1224 
1225 # ifndef XA_FACE_NAME
1226 static Atom XA_FACE_NAME;
1227 # endif
1228 
appFindX11Fonts(APP_WIDGET topw,PostScriptFontList * psfl)1229 int appFindX11Fonts(	APP_WIDGET			topw,
1230 			PostScriptFontList *		psfl )
1231     {
1232     int			rval= 0;
1233     int			i;
1234 
1235     void *		full2afi= (void *)0;
1236     const int		ownKeys= 0;
1237 
1238     char		fontFormat[120];
1239     char **		fontNames= (char **)0;
1240     XFontStruct *	fontInfos= (XFontStruct *)0;
1241     int			fontCount= 0;
1242 
1243 #   ifdef USE_MOTIF
1244     Display *		display= XtDisplay( topw );
1245 #   endif
1246 
1247 #   ifdef USE_GTK
1248     Display *		display= GDK_DISPLAY();
1249 #   endif
1250 
1251 
1252 #   ifndef XA_FACE_NAME
1253     if  ( ! XA_FACE_NAME )
1254 	{
1255 	XA_FACE_NAME= XInternAtom( display, "FACE_NAME", TRUE );
1256 	if  ( ! XA_FACE_NAME )
1257 	    { XDEB(XA_FACE_NAME); rval= -1; goto ready;	}
1258 	}
1259 #   endif
1260 
1261     full2afi= utilTreeMakeTree( ownKeys );
1262     if  ( ! full2afi )
1263 	{ XDEB(full2afi); rval= -1; goto ready;	}
1264 
1265     for ( i= 0; i < psfl->psflInfoCount; i++ )
1266 	{
1267 	AfmFontInfo *	afi= psfl->psflInfos[i];
1268 
1269 	if  ( utilTreeStoreValue( full2afi, (void **)0, (const char **)0,
1270 						    afi->afiFullName, afi ) )
1271 	    { SDEB(afi->afiFullName); rval= -1; goto ready;	}
1272 	}
1273 
1274     appFontQueryString( fontFormat,
1275 		EditFontAnyTemplate,		/* foundry,		*/
1276 		EditFontAnyTemplate,		/* family,		*/
1277 		EditFontAnyTemplate,		/* weight,		*/
1278 		EditFontAnyTemplate,		/* slant,		*/
1279 		EditFontAnyTemplate,		/* swdth,		*/
1280 		"0",				/* pxlsz: scalable	*/
1281 		EditFontAnyRegistry_EncodingTemplate );	/* registry,enc	*/
1282 
1283     fontNames= XListFontsWithInfo( display, fontFormat, 6000,
1284 						    &fontCount, &fontInfos );
1285 
1286     if  ( fontCount == 6000 )
1287 	{ LDEB(fontCount);	}
1288 
1289     for ( i= 0; i < fontCount; i++ )
1290 	{
1291 	Atom	faceNameA;
1292 
1293 	if  ( XGetFontProperty( &(fontInfos[i]), XA_FACE_NAME, &faceNameA ) )
1294 	    {
1295 	    char *		faceName= XGetAtomName( display, faceNameA );
1296 	    AfmFontInfo *	afi;
1297 
1298 	    afi= (AfmFontInfo *)utilTreeGetEQ( full2afi,
1299 						(const char **)0, faceName );
1300 	    if  ( afi )
1301 		{
1302 		if  ( psAddX11FontToInfo( afi, fontNames[i] ) )
1303 		    { SDEB(fontNames[i]); rval= -1; goto ready;	}
1304 		}
1305 	    }
1306 	}
1307 
1308   ready:
1309 
1310     if  ( fontNames )
1311 	{ XFreeFontInfo( fontNames, fontInfos, fontCount );	}
1312 
1313     if  ( full2afi )
1314 	{ utilTreeFreeTree( full2afi, (UTIL_TREE_CALLBACK)0, (void *)0 ); }
1315 
1316     return rval;
1317     }
1318 
1319 /************************************************************************/
1320 /*									*/
1321 /*  Get the name and the encoding of a font.				*/
1322 /*									*/
1323 /************************************************************************/
1324 
addDrawX11GetFontProperties(EncodedScreenFont * esf,DrawScreenFont * dsf)1325 void addDrawX11GetFontProperties(	EncodedScreenFont *	esf,
1326 					DrawScreenFont *	dsf )
1327     {
1328     EncodedScreenFontList *	esfl= &(dsf->dsfEncodedFonts);
1329     AppFontEncoding *		fe;
1330 
1331     int				i;
1332 
1333     int				prevDash;
1334     int				len;
1335     XFontStruct *		xfs= (XFontStruct *)0;
1336     Display *			display;
1337 
1338     int				dash;
1339 
1340     static const char * an[]=
1341 	{
1342 	"FOUNDRY",
1343 	"FAMILY_NAME",
1344 	"WEIGHT_NAME",
1345 	"SLANT",
1346 	"SETWIDTH_NAME",
1347 	"ADD_STYLE_NAME",
1348 	"PIXEL_SIZE",
1349 	"POINT_SIZE",
1350 	"RESOLUTION_X",
1351 	"RESOLUTION_Y",
1352 	"SPACING",
1353 	"AVERAGE_WIDTH",
1354 	"CHARSET_REGISTRY",
1355 	"CHARSET_ENCODING"
1356 	};
1357 
1358     static Atom na[14];
1359 
1360 #   ifdef USE_MOTIF
1361     xfs= esf->esfFontStruct;
1362     display= dsf->dsfDisplay;
1363 #   endif
1364 
1365 #   ifdef USE_GTK
1366 #   if GTK_MAJOR_VERSION >= 2
1367     xfs= (XFontStruct *)gdk_x11_font_get_xfont( esf->esfFontStruct );
1368 #   else
1369     xfs= GDK_FONT_XFONT( esf->esfFontStruct );
1370 #   endif
1371 
1372     if  ( esf->esfFontStruct->type != GDK_FONT_FONT )
1373 	{ LDEB(esf->esfFontStruct->type); return;	}
1374     display= GDK_DISPLAY();
1375 #   endif
1376 
1377     if  ( na[0] == None )
1378 	{
1379 	for ( i= 0; i < 14; i++ )
1380 	    { na[i]= XInternAtom( display, an[i], False );	}
1381 	}
1382 
1383     len= 0;
1384     prevDash= dash= -1;
1385     for ( i= 0; i < 14; i++ )
1386 	{
1387 	Atom		a= None;
1388 	char *		as= (char *)0;
1389 	int		al;
1390 
1391 	char		scratch[15];
1392 
1393 	scratch[0]= '\0';
1394 
1395 	if  ( XGetFontProperty( xfs, na[i], &a ) )
1396 	    {
1397 	    if  ( i <= 5 || i >= 12 || i == 10 )
1398 		{ as= XGetAtomName( display, a );		}
1399 	    else{ as= scratch; sprintf( scratch, "%ld", a );	}
1400 	    }
1401 
1402 	if  ( ! as )
1403 	    { as= scratch;	}
1404 	al= strlen( as );
1405 
1406 	if  ( len+ 1+ al >= X_FONTNAME_MAX )
1407 	    { LLDEB(len+ 1+ al,X_FONTNAME_MAX); break;	}
1408 
1409 	prevDash= dash; dash= len;
1410 	esf->esfFontName[len++]= '-';
1411 	strcpy( esf->esfFontName+ len, as ); len += al;
1412 
1413 	if  ( as != scratch )
1414 	    { XFree( as );	}
1415 	}
1416 
1417 #   if 0
1418     {
1419     const char *	name= gdk_x11_font_get_name( esf->esfFontStruct );
1420 
1421     len= strlen( name );
1422     prevDash= -1;
1423 
1424     if  ( len > X_FONTNAME_MAX )
1425 	{ SLDEB(name, X_FONTNAME_MAX); return;	}
1426     strcpy( esf->esfFontName, name );
1427 
1428     for ( i= 0; i < 13; i++ )
1429 	{
1430 	char *	d= strchr( name+ prevDash+ 1, '-' );
1431 
1432 	if  ( ! d )
1433 	    { XDEB(d); break;	}
1434 	prevDash= d- name;
1435 	}
1436     if  ( i < 13 )
1437 	{ LSDEB(i,name); return;	}
1438     }
1439 #   endif
1440 
1441     for ( i= 0; i < len; i++ )
1442 	{ esf->esfFontName[i]= tolower( esf->esfFontName[i] );	}
1443 
1444     fe= AppFontXEncodings;
1445     for ( i= 0; i < AppFontXEncodingCount; fe++, i++ )
1446 	{
1447 	if  ( ! strcmp( esf->esfFontName+ prevDash+ 1, fe->feX11Reg_Enc ) )
1448 	    {
1449 	    IndexMapping *	im= &(fe->feSymbolToByteMapping);
1450 	    const int *		unicodes= fe->feGlyphUnicodes;
1451 
1452 	    if  ( unicodes )
1453 		{
1454 		int		code;
1455 		const int	font= 0;
1456 
1457 		if  ( utilIndexMappingIsEmpty( im )			&&
1458 		      utilIndexMappingBuildBackward( im, unicodes, 256 ) )
1459 		    { LDEB(1); return;	}
1460 
1461 		esf->esfSymbolToByteMapping= im;
1462 
1463 		for ( code= 0; code < 256; code++ )
1464 		    {
1465 		    int	symbol= unicodes[code];
1466 
1467 		    if  ( symbol < 0 || ! appXfontHasCode( xfs, code ) )
1468 			{ continue;	}
1469 
1470 		    if  ( utilIndexMappingPut( &(esfl->esflSymbolToFont),
1471 							    symbol, font ) )
1472 			{ LLDEB(symbol,font);	}
1473 		    }
1474 		}
1475 	    }
1476 	}
1477 
1478     if  ( ! esf->esfSymbolToByteMapping )
1479 	{ SXDEB(esf->esfFontName,esf->esfSymbolToByteMapping);	}
1480     }
1481 
1482 #   endif
1483 
guiSystemFont(DrawingSurface ds,APP_FONT * xfs)1484 int guiSystemFont(	DrawingSurface		ds,
1485 			APP_FONT *		xfs )
1486     {
1487     NumberedPropertiesList *	npl= &(ds->dsScreenFontAdmin);
1488     DrawScreenFont *		dsf= (DrawScreenFont *)0;
1489     int				screenFont;
1490 
1491     /* HACK */
1492     dsf= utilPagedListClaimItemAtEnd( &screenFont, &(npl->nplPagedList) );
1493     if  ( ! dsf )
1494 	{ XDEB(dsf); return -1;	}
1495 
1496     dsf->dsfEncodedFonts.esfFonts= malloc( sizeof(EncodedScreenFont) );
1497     if  ( ! dsf->dsfEncodedFonts.esfFonts )
1498 	{ XDEB(dsf->dsfEncodedFonts.esfFonts); return -1;	}
1499     drawInitEncodedScreenFont( dsf->dsfEncodedFonts.esfFonts );
1500     dsf->dsfEncodedFonts.esfFontCount= 1;
1501 
1502     dsf->dsfEncodedFonts.esfFonts[0].esfFontStruct= xfs;
1503 
1504 #   ifdef USE_MOTIF
1505     dsf->dsfDisplay= ds->dsDisplay;
1506     dsf->dsfDrawable= ds->dsDrawable;
1507     dsf->dsfGc= ds->dsGc;
1508     dsf->dsfEncodedFonts.esfFonts[0].esfFontBorrowed= 1;
1509 #   endif
1510 
1511 #   ifdef USE_GTK
1512     dsf->dsfDrawable= ds->dsDrawable;
1513     dsf->dsfGc= ds->dsGc;
1514     dsf->dsfEncodedFonts.esfFonts[0].esfFontBorrowed= 0;
1515 #   endif
1516 
1517 #   ifdef USE_XFT
1518     dsf->dsfXftDrawable= ds->dsXftDrawable;
1519 #   endif
1520 
1521 #   ifdef USE_X11_FONTS
1522     addDrawX11GetFontProperties( dsf->dsfEncodedFonts.esfFonts, dsf );
1523     strcpy( dsf->apfFontName, dsf->dsfEncodedFonts.esfFonts->esfFontName );
1524 #   endif
1525 
1526     return screenFont;
1527     }
1528 
1529