First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xprint / ps / PsFonts.c
blob8ab6314417785464b7224e108f06d9e8188ddee0
1 /*
3 Copyright 1996, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
27 * (c) Copyright 1996 Hewlett-Packard Company
28 * (c) Copyright 1996 International Business Machines Corp.
29 * (c) Copyright 1996 Sun Microsystems, Inc.
30 * (c) Copyright 1996 Novell, Inc.
31 * (c) Copyright 1996 Digital Equipment Corp.
32 * (c) Copyright 1996 Fujitsu Limited
33 * (c) Copyright 1996 Hitachi, Ltd.
35 * Permission is hereby granted, free of charge, to any person obtaining
36 * a copy of this software and associated documentation files (the
37 * "Software"), to deal in the Software without restriction, including
38 * without limitation the rights to use, copy, modify, merge, publish,
39 * distribute, sublicense, and/or sell copies of the Software, and to
40 * permit persons to whom the Software is furnished to do so, subject
41 * to the following conditions:
43 * The above copyright notice and this permission notice shall be included
44 * in all copies or substantial portions of the Software.
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49 * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
50 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
51 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
52 * SOFTWARE.
54 * Except as contained in this notice, the names of the copyright holders
55 * shall not be used in advertising or otherwise to promote the sale, use
56 * or other dealings in this Software without prior written authorization
57 * from said copyright holders.
60 /*******************************************************************
62 ** *********************************************************
63 ** *
64 ** * File: PsFonts.c
65 ** *
66 ** * Contents: Font code for PS driver.
67 ** *
68 ** * Created By: Roger Helmendach (Liberty Systems)
69 ** *
70 ** * Copyright: Copyright 1996 The Open Group, Inc.
71 ** *
72 ** *********************************************************
73 **
74 ********************************************************************/
76 #ifdef HAVE_DIX_CONFIG_H
77 #include <dix-config.h>
78 #endif
80 #include "regionstr.h"
81 #include <X11/fonts/fontstruct.h>
82 #include "dixfontstr.h"
83 #include "scrnintstr.h"
84 #include <X11/fonts/fontxlfd.h>
85 #include <X11/fonts/fntfil.h>
86 #include <X11/fonts/fntfilst.h>
88 #include "Ps.h"
90 #include <ctype.h>
91 #include <limits.h>
92 #include <sys/stat.h>
94 Bool
95 PsRealizeFont(
96 ScreenPtr pscr,
97 FontPtr pFont)
99 return TRUE;
102 Bool
103 PsUnrealizeFont(
104 ScreenPtr pscr,
105 FontPtr pFont)
107 return TRUE;
110 char *
111 PsGetFontName(FontPtr pFont)
113 int i;
114 int nprops = pFont->info.nprops;
115 FontPropPtr props = pFont->info.props;
116 Atom name = MakeAtom("FONT", 4, True);
117 Atom value = (Atom)0;
119 for( i=0 ; i<nprops ; i++ )
121 if( (Atom)props[i].name==name )
122 { value = props[i].value; break; }
124 if( !value ) return (char *)0;
125 return NameForAtom(value);
129 PsGetFontSize(FontPtr pFont, float *mtx)
131 FontScalableRec vals;
132 char *name = PsGetFontName(pFont);
133 int value = 0;
135 FontParseXLFDName(name, &vals, FONT_XLFD_REPLACE_NONE);
136 if( vals.values_supplied&PIXELSIZE_ARRAY )
138 int i;
139 for( i=0 ; i<4 ; i++ )
140 mtx[i] = (float)vals.pixel_matrix[i];
142 else
144 value = vals.pixel;
145 if( !value ) value = 20;
147 return value;
150 char *
151 PsGetPSFontName(FontPtr pFont)
153 int i;
154 int nprops = pFont->info.nprops;
155 FontPropPtr props = pFont->info.props;
156 /* "_ADOBE_POSTSCRIPT_FONTNAME" maps directly to a PMF OBJ_NAME attribute
157 * name - changing the name will break printer-builtin fonts. */
158 Atom name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, True);
159 Atom value = (Atom)0;
161 for( i=0 ; i<nprops ; i++ )
163 if( (Atom)props[i].name==name )
164 { value = props[i].value; break; }
166 if( !value ) return (char *)0;
167 return NameForAtom(value);
171 PsIsISOLatin1Encoding(FontPtr pFont)
173 int i;
174 int nprops = pFont->info.nprops;
175 FontPropPtr props = pFont->info.props;
176 Atom reg = MakeAtom("CHARSET_REGISTRY", 16, True);
177 Atom enc = MakeAtom("CHARSET_ENCODING", 16, True);
178 Atom rv = 0, ev = 0;
179 char *rp = 0;
180 char *ep = 0;
182 for( i=0 ; i<nprops ; i++ )
184 if( (Atom)props[i].name==reg ) rv = props[i].value;
185 if( (Atom)props[i].name==enc ) ev = props[i].value;
187 if( rv ) rp = NameForAtom(rv);
188 if( ev ) ep = NameForAtom(ev);
189 if( (!rp) || (!ep) ) return(0);
190 if( (char)tolower(rp[0])!='i' ||
191 (char)tolower(rp[1])!='s' ||
192 (char)tolower(rp[2])!='o' ||
193 memcmp(&rp[3], "8859", 4)!=0 ||
194 ep[0]!='1' ) return(0);
195 return(1);
198 /* Return the encoding part of the XLFD (e.g. "*-iso8859-6.8x" etc.)*/
199 char *PsGetEncodingName(FontPtr pFont)
201 int i;
202 int nprops = pFont->info.nprops;
203 FontPropPtr props = pFont->info.props;
204 Atom fnt = MakeAtom("FONT", 4, True);
205 Atom reg = MakeAtom("CHARSET_REGISTRY", 16, True);
206 Atom enc = MakeAtom("CHARSET_ENCODING", 16, True);
207 Atom fv = 0, rv = 0, ev = 0;
208 char *fp = 0;
209 char *rp = 0;
210 char *ep = 0;
211 char *encname;
213 for( i=0 ; i<nprops ; i++ )
215 if( props[i].name==fnt ) fv = props[i].value;
216 if( props[i].name==reg ) rv = props[i].value;
217 if( props[i].name==enc ) ev = props[i].value;
219 if( fv ) fp = NameForAtom(fv);
220 if( rv ) rp = NameForAtom(rv);
221 if( ev ) ep = NameForAtom(ev);
223 if( (!rp) || (!ep) || (!fp))
224 return(0);
226 encname = fp;
227 encname += strlen(encname) - (strlen(rp) + strlen(ep) + 1);
229 return encname;
232 /* strstr(), case-insensitive */
233 static
234 char *str_case_str(const char *s, const char *find)
236 size_t len;
237 char c,
240 if ((c = tolower(*find++)) != '\0')
242 len = strlen(find);
247 if ((sc = tolower(*s++)) == '\0')
248 return NULL;
249 } while (sc != c);
250 } while (strncasecmp(s, find, len) != 0);
251 s--;
253 return ((char *)s);
256 /* Check if the font path element is a directory which can be examined
257 * (for example the font may be from a font server
258 * (e.g. pFont->fpe->name == "tcp/:7100"))
260 static
261 Bool IsFPEaReadableDir(FontPtr pFont)
263 const char *fpe_name = pFont->fpe->name;
264 if (!fpe_name)
265 return False;
267 #define MODEL_FONTPATH_PREFIX "PRINTER:"
268 #define MODEL_FONTPATH_PREFIX_LEN 8
269 /* Strip model-specific font path prefix if there is one... */
270 if (!strncmp(fpe_name, MODEL_FONTPATH_PREFIX, MODEL_FONTPATH_PREFIX_LEN))
271 fpe_name += MODEL_FONTPATH_PREFIX_LEN;
273 if (access(fpe_name, F_OK) == 0)
275 return True;
278 return False;
281 static
282 char *getFontFilename(FontPtr pFont)
284 FontDirectoryPtr dir;
285 const char *dlfnam;
286 FILE *file;
287 struct stat statb;
288 char buf[512];
289 char *front, *fn;
290 char font_dir_fname[PATH_MAX], /* Full path of fonts.dir */
291 font_file_fname[PATH_MAX]; /* Name of font file (excluding path) */
293 #ifdef XP_USE_FREETYPE
294 if( PsIsFreeTypeFont(pFont) )
296 const char *fontname = PsGetFTFontFileName(pFont);
298 #ifdef DEBUG_gisburn
299 fprintf(stderr, "getFontFilename: freetype font, file='%s'\n", fontname?fontname:"<NULL>");
300 #endif /* DEBUG_gisburn */
302 if( !fontname )
303 return NULL;
305 return strdup(fontname);
307 #endif /* XP_USE_FREETYPE */
309 if (!IsFPEaReadableDir(pFont))
311 #ifdef DEBUG_gisburn
312 fprintf(stderr, "getFontFilename: '%s' no valid font path on disk\n", pFont->fpe->name);
313 #endif /* DEBUG_gisburn */
314 return NULL;
317 dir = pFont->fpe->private;
318 sprintf(font_dir_fname, "%s%s", dir->directory, "fonts.dir");
320 if (!(dlfnam = PsGetFontName(pFont)))
321 return NULL;
323 file = fopen(font_dir_fname, "r");
324 if (file)
326 if (fstat (fileno(file), &statb) == -1)
327 return NULL;
329 while( fgets(buf, sizeof(buf)-1, file) )
331 if ((fn = strstr(buf, " -")))
333 strcpy(font_file_fname, buf);
334 font_file_fname[fn - buf] = '\0';
335 fn++;
336 if ((front = str_case_str(fn, "normal-")))
338 fn[front - fn] = '\0';
339 if (str_case_str(dlfnam, fn))
341 char full_font_file_path[PATH_MAX];
343 fclose(file);
345 sprintf(full_font_file_path, "%s%s", dir->directory, font_file_fname);
347 #ifdef xDEBUG_gisburn
348 fprintf(stderr, "getFontFilename: returning '%s'\n", full_font_file_path);
349 #endif /* DEBUG_gisburn */
350 return strdup(full_font_file_path);
356 font_file_fname[0] = '\0';
357 fclose(file);
359 #ifdef DEBUG_gisburn
360 fprintf(stderr, "getFontFilename: returning NULL\n");
361 #endif /* DEBUG_gisburn */
363 return NULL;
366 static
367 PsFontTypeInfoRec *PsFindFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
369 PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
370 PsFontTypeInfoRec *rec;
371 const char *psname;
372 char *font_filename;
373 char *encname;
374 #ifdef XP_USE_FREETYPE
375 Bool is_freetypefont;
376 #endif /* XP_USE_FREETYPE */
378 #ifdef XP_USE_FREETYPE
379 is_freetypefont = PsIsFreeTypeFont(pFont);
380 #endif /* XP_USE_FREETYPE */
381 encname = PsGetEncodingName(pFont);
383 /* First try: Search by PostScript font name */
384 psname = PsGetPSFontName(pFont);
385 if (psname)
387 for( rec = cPriv->fontTypeInfoRecords ; rec != NULL ; rec = rec->next )
389 #ifdef XP_USE_FREETYPE
390 if (is_freetypefont)
392 if (rec->adobe_ps_name)
394 if ((rec->font_type == PSFTI_FONT_TYPE_FREETYPE) &&
395 (!strcmp(rec->adobe_ps_name, psname)) &&
396 (!strcmp(rec->ft_download_encoding, encname)))
398 return rec;
402 else
403 #endif /* XP_USE_FREETYPE */
405 if (rec->adobe_ps_name)
407 if ((rec->font_type != PSFTI_FONT_TYPE_FREETYPE) &&
408 (!strcmp(rec->adobe_ps_name, psname)))
410 return rec;
417 /* Last attempt: Search by filename */
418 font_filename = getFontFilename(pFont);
419 if (font_filename)
421 for( rec = cPriv->fontTypeInfoRecords ; rec != NULL ; rec = rec->next )
423 if (rec->filename)
425 #ifdef XP_USE_FREETYPE
426 if (is_freetypefont)
428 if ( (rec->font_type == PSFTI_FONT_TYPE_FREETYPE) &&
429 (!strcasecmp(rec->filename, font_filename)) &&
430 (!strcasecmp(rec->ft_download_encoding, encname)) )
432 free(font_filename);
433 return rec;
436 else
437 #endif /* XP_USE_FREETYPE */
439 if ( (rec->font_type != PSFTI_FONT_TYPE_FREETYPE) &&
440 (!strcasecmp(rec->filename, font_filename)) )
442 free(font_filename);
443 return rec;
449 free(font_filename);
452 return NULL;
455 static
456 void PsAddFontTypeInfoRec(DrawablePtr pDrawable, PsFontTypeInfoRec *add_rec)
458 PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
460 /* ToDO: Always move the last used entry to the top that the list get's
461 * sorted in an efficient order... :-) */
462 add_rec->next = cPriv->fontTypeInfoRecords;
463 cPriv->fontTypeInfoRecords = add_rec;
466 static
467 Bool strcaseendswith(const char *str, const char *suffix)
469 const char *s;
471 s = str + strlen(str) - strlen(suffix);
473 if (!strcasecmp(s, suffix))
474 return True;
476 return False;
480 static
481 int getFontFileType( const char *filename )
483 int type;
485 /* Is this a Adobe PostScript Type 1 binary font (PFB) ? */
486 if( strcaseendswith(filename, ".pfb") )
488 type = PSFTI_FONT_TYPE_PS_TYPE1_PFB;
490 /* Is this a Adobe PostScript ASCII font (PFA) ? */
491 else if( strcaseendswith(filename, ".pfa") )
493 type = PSFTI_FONT_TYPE_PS_TYPE1_PFA;
495 /* Is this a PMF(=Printer Metrics File) ? */
496 else if( strcaseendswith(filename, ".pmf") )
498 type = PSFTI_FONT_TYPE_PMF;
500 /* Is this a TrueType font file ? */
501 else if( strcaseendswith(filename, ".ttf") ||
502 strcaseendswith(filename, ".ttc") ||
503 strcaseendswith(filename, ".otf") ||
504 strcaseendswith(filename, ".otc") )
506 type = PSFTI_FONT_TYPE_TRUETYPE;
508 else
510 type = PSFTI_FONT_TYPE_OTHER;
513 #ifdef XP_USE_FREETYPE
515 XpContextPtr pCon;
516 char *downloadfonts;
517 pCon = XpGetPrintContext(requestingClient);
518 downloadfonts = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-psddx-download-fonts");
519 if( downloadfonts )
521 /* Should we download PS Type1 fonts as PS Type1||Type3 ? */
522 if( (type == PSFTI_FONT_TYPE_PS_TYPE1_PFA) &&
523 (strstr(downloadfonts, "pfa") != NULL) )
525 type = PSFTI_FONT_TYPE_FREETYPE;
528 if( (type == PSFTI_FONT_TYPE_PS_TYPE1_PFB) &&
529 (strstr(downloadfonts, "pfb") != NULL) )
531 type = PSFTI_FONT_TYPE_FREETYPE;
534 /* Should we download TrueType fonts as PS Type1||Type3 ? */
535 if( (type == PSFTI_FONT_TYPE_TRUETYPE) &&
536 ((strstr(downloadfonts, "ttf") != NULL) ||
537 (strstr(downloadfonts, "ttc") != NULL) ||
538 (strstr(downloadfonts, "otf") != NULL) ||
539 (strstr(downloadfonts, "otc") != NULL)) )
541 type = PSFTI_FONT_TYPE_FREETYPE;
545 #endif /* XP_USE_FREETYPE */
547 #ifdef DEBUG_gisburn
548 fprintf(stderr, "getFontFileType: '%s' is %d\n", filename, (int)type);
549 #endif /* DEBUG_gisburn */
550 return type;
553 PsFTDownloadFontType PsGetFTDownloadFontType(void)
555 PsFTDownloadFontType downloadfonttype;
556 XpContextPtr pCon;
557 char *psfonttype;
559 pCon = XpGetPrintContext(requestingClient);
560 psfonttype = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-psddx-download-font-type");
562 if( !psfonttype || !strlen(psfonttype) )
564 return PsFontType1; /* Default download font type is PS Type1 */
567 if( !strcmp(psfonttype, "bitmap") )
569 downloadfonttype = PsFontBitmap;
571 else if( !strcmp(psfonttype, "pstype3") )
573 downloadfonttype = PsFontType3;
575 else if( !strcmp(psfonttype, "pstype1") )
577 downloadfonttype = PsFontType1;
579 else
581 FatalError("PS DDX: XPPrinterAttr/xp-psddx-download-freetype-font-type='%s' not implemented\n", psfonttype);
582 return 0; /* NO-OP, FatalError() will call |exit()| */
585 return downloadfonttype;
588 static
589 PsFontTypeInfoRec *PsCreateFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
591 char *dlfnam;
592 PsFontTypeInfoRec *rec;
594 if (!(dlfnam = PsGetFontName(pFont)))
595 return NULL;
597 if (!(rec = (PsFontTypeInfoRec *)xalloc(sizeof(PsFontTypeInfoRec))))
598 return NULL;
599 memset(rec, 0, sizeof(PsFontTypeInfoRec));
601 rec->next = NULL;
603 if ((rec->filename = getFontFilename(pFont)))
605 rec->font_type = getFontFileType(rec->filename);
607 else
609 rec->filename = NULL;
610 rec->font_type = PSFTI_FONT_TYPE_OTHER;
613 rec->adobe_ps_name = PsGetPSFontName(pFont);
614 #ifdef XP_USE_FREETYPE
615 rec->ft_download_encoding = PsGetEncodingName(pFont);
616 rec->ft_download_font_type = PsGetFTDownloadFontType();
617 #endif /* XP_USE_FREETYPE */
618 rec->download_ps_name = NULL;
620 #define SET_FONT_DOWNLOAD_STATUS(rec, downloaded) { int i; for (i = 0 ; i < 256 ; i++) { (rec)->alreadyDownloaded[i]=(downloaded); } }
622 /* Set some flags based on the font type */
623 switch( rec->font_type )
625 case PSFTI_FONT_TYPE_PS_TYPE1_PFA:
626 case PSFTI_FONT_TYPE_PS_TYPE1_PFB:
627 rec->downloadableFont = True;
628 SET_FONT_DOWNLOAD_STATUS(rec, False);
629 rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
630 break;
632 case PSFTI_FONT_TYPE_PMF:
633 rec->downloadableFont = True; /* This font is in printer's ROM */
634 SET_FONT_DOWNLOAD_STATUS(rec, True);
635 rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
636 break;
638 case PSFTI_FONT_TYPE_TRUETYPE:
639 /* Note: TrueType font download not implemented */
640 rec->downloadableFont = False;
641 SET_FONT_DOWNLOAD_STATUS(rec, False);
642 rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
643 break;
645 #ifdef XP_USE_FREETYPE
646 case PSFTI_FONT_TYPE_FREETYPE:
647 if( rec->ft_download_font_type == PsFontType1 ||
648 rec->ft_download_font_type == PsFontType3 )
650 rec->downloadableFont = True;
652 else
654 rec->downloadableFont = False;
657 SET_FONT_DOWNLOAD_STATUS(rec, False);
658 rec->is_iso_encoding = False; /* Freetype--->PS Type1/Type3 uses always non-iso PS encoding for now */
659 break;
660 #endif /* XP_USE_FREETYPE */
662 case PSFTI_FONT_TYPE_OTHER:
663 default:
664 rec->downloadableFont = False;
665 SET_FONT_DOWNLOAD_STATUS(rec, False);
666 rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
667 break;
670 #ifdef XP_USE_FREETYPE
671 if( (rec->font_type == PSFTI_FONT_TYPE_FREETYPE) )
673 char *s;
674 register int c;
676 if( rec->adobe_ps_name )
678 rec->download_ps_name = malloc(strlen(rec->adobe_ps_name) + strlen(rec->ft_download_encoding) + 2);
679 sprintf(rec->download_ps_name, "%s_%s", rec->adobe_ps_name, rec->ft_download_encoding);
681 else
683 /* Unfortunately not all TTF fonts have a PostScript font name (like
684 * Solaris TTF fonts in /usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType,
685 * /usr/openwin/lib/locale/ko/X11/fonts/TrueType) - in this case we
686 * have to generate a font name
688 char ftfontname[64];
689 static long myfontindex = 0L;
690 sprintf(ftfontname, "psfont_%lx", myfontindex++);
692 rec->download_ps_name = malloc(strlen(ftfontname) + strlen(rec->ft_download_encoding) + 2);
693 sprintf(rec->download_ps_name, "%s_%s", ftfontname, rec->ft_download_encoding);
695 fprintf(stderr, "PsCreateFontTypeInfoRec: Note: '%s' has no PS font name, using '%s' for now.\n", dlfnam, rec->download_ps_name);
698 /* Make sure the font name we use for download is a valid PS font name */
699 for( s = rec->download_ps_name ; *s != '\0'; s++ )
701 c = *s;
703 /* Check for allowed chars, invalid ones are replaced with a '_'
704 * (and check that the first char is not a digit) */
705 if( !(isalnum(c) || c == '.' || c == '_' || c == '-') || (s==rec->download_ps_name && isdigit(c)) )
707 *s = '_';
711 else
712 #endif /* XP_USE_FREETYPE */
714 if( rec->adobe_ps_name )
716 rec->download_ps_name = strdup(rec->adobe_ps_name);
718 else
720 rec->download_ps_name = NULL;
724 /* Safeguard - only treat font as downloadable when we have a PS font name!! */
725 if (!rec->download_ps_name && rec->downloadableFont)
727 /* XXX: Log this message to the log when the logging service has been hook'ed up */
728 fprintf(stderr, "PsCreateFontTypeInfoRec: Safeguard: No PS font name for '%s'!\n", dlfnam);
729 rec->downloadableFont = False;
732 #ifdef DEBUG_gisburn
733 fprintf(stderr, "PsCreateFontTypeInfoRec: Created PsFontTypeInfoRec '%s' ('%s'/'%s')\n",
734 ((rec->filename) ?(rec->filename) :("<null>")),
735 ((rec->adobe_ps_name) ?(rec->adobe_ps_name):("<null>")),
736 ((rec->download_ps_name)?(rec->download_ps_name):("<null>")));
737 #endif /* DEBUG_gisburn */
739 return rec;
742 static
743 PsFontTypeInfoRec *PsGetFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
745 PsFontTypeInfoRec *rec;
746 char *dlfnam;
748 if(!(dlfnam = PsGetFontName(pFont)))
749 return NULL;
751 rec = PsFindFontTypeInfoRec(pDrawable, pFont);
752 if (rec)
753 return rec;
755 rec = PsCreateFontTypeInfoRec(pDrawable, pFont);
756 if (!rec)
757 return NULL;
759 PsAddFontTypeInfoRec(pDrawable, rec);
761 return rec;
764 static
765 void PsFreeFontTypeInfoRecords( PsContextPrivPtr priv )
767 PsFontTypeInfoRec *curr, *next;
768 curr = priv->fontTypeInfoRecords;
769 while( curr != NULL )
771 if (curr->filename)
772 free(curr->filename); /* Free memory allocated by |strdup()| */
774 if (curr->download_ps_name)
775 free(curr->download_ps_name);
777 next = curr->next;
778 xfree(curr);
779 curr = next;
783 static
784 PsFontInfoRec *PsFindFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
786 PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
787 PsFontInfoRec *rec;
789 if (!pFont)
790 return NULL;
792 for( rec = cPriv->fontInfoRecords ; rec != NULL ; rec = rec->next )
794 if ((rec->font == pFont) &&
795 (rec->font_fontPrivate == pFont->fontPrivate))
796 return rec;
799 return NULL;
802 static
803 void PsAddFontInfoRec(DrawablePtr pDrawable, PsFontInfoRec *add_rec)
805 PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
807 /* ToDO: Always move the last used entry to the top that the list get's
808 * sorted in an efficient order... :-) */
809 add_rec->next = cPriv->fontInfoRecords;
810 cPriv->fontInfoRecords = add_rec;
813 static
814 PsFontInfoRec *PsCreateFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
816 PsFontInfoRec *rec;
817 PsFontTypeInfoRec *ftir;
819 if (!(ftir = PsGetFontTypeInfoRec(pDrawable, pFont)))
820 return NULL;
822 if (!(rec = (PsFontInfoRec *)xalloc(sizeof(PsFontInfoRec))))
823 return NULL;
824 memset(rec, 0, sizeof(PsFontInfoRec));
826 rec->font = pFont;
827 rec->font_fontPrivate = pFont->fontPrivate;
828 rec->ftir = ftir;
829 rec->next = NULL;
830 rec->dfl_name = PsGetFontName(pFont);
831 rec->size = PsGetFontSize(pFont, rec->mtx);
833 #ifdef DEBUG_gisburn
834 fprintf(stderr, "PsCreateFontInfoRec: Created PsFontInfoRec '%s'\n",
835 ((rec->dfl_name)?(rec->dfl_name):("<null>")));
836 #endif /* DEBUG_gisburn */
838 return rec;
841 PsFontInfoRec *PsGetFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
843 PsFontInfoRec *rec;
845 rec = PsFindFontInfoRec(pDrawable, pFont);
846 if (rec)
847 return rec;
849 rec = PsCreateFontInfoRec(pDrawable, pFont);
850 if (!rec)
851 return NULL;
853 PsAddFontInfoRec(pDrawable, rec);
855 return rec;
858 void PsFreeFontInfoRecords( PsContextPrivPtr priv )
860 PsFontInfoRec *curr, *next;
861 curr = priv->fontInfoRecords;
862 while( curr != NULL )
864 next = curr->next;
865 xfree(curr);
866 curr = next;
869 PsFreeFontTypeInfoRecords(priv);
871 priv->fontTypeInfoRecords = NULL;
872 priv->fontInfoRecords = NULL;