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