874 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			874 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
| 
 | |
| Copyright 1996, 1998  The Open Group
 | |
| 
 | |
| Permission to use, copy, modify, distribute, and sell this software and its
 | |
| documentation for any purpose is hereby granted without fee, provided that
 | |
| the above copyright notice appear in all copies and that both that
 | |
| copyright notice and this permission notice appear in supporting
 | |
| documentation.
 | |
| 
 | |
| The above copyright notice and this permission notice shall be included in
 | |
| all copies or substantial portions of the Software.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | |
| OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 | |
| AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | |
| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| 
 | |
| Except as contained in this notice, the name of The Open Group shall not be
 | |
| used in advertising or otherwise to promote the sale, use or other dealings
 | |
| in this Software without prior written authorization from The Open Group.
 | |
| 
 | |
| */
 | |
| /*
 | |
|  * (c) Copyright 1996 Hewlett-Packard Company
 | |
|  * (c) Copyright 1996 International Business Machines Corp.
 | |
|  * (c) Copyright 1996 Sun Microsystems, Inc.
 | |
|  * (c) Copyright 1996 Novell, Inc.
 | |
|  * (c) Copyright 1996 Digital Equipment Corp.
 | |
|  * (c) Copyright 1996 Fujitsu Limited
 | |
|  * (c) Copyright 1996 Hitachi, Ltd.
 | |
|  *
 | |
|  * Permission is hereby granted, free of charge, to any person obtaining
 | |
|  * a copy of this software and associated documentation files (the
 | |
|  * "Software"), to deal in the Software without restriction, including
 | |
|  * without limitation the rights to use, copy, modify, merge, publish,
 | |
|  * distribute, sublicense, and/or sell copies of the Software, and to
 | |
|  * permit persons to whom the Software is furnished to do so, subject
 | |
|  * to the following conditions:
 | |
|  *
 | |
|  * The above copyright notice and this permission notice shall be included
 | |
|  * in all copies or substantial portions of the Software.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | |
|  * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | |
|  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | |
|  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | |
|  * SOFTWARE.
 | |
|  *
 | |
|  * Except as contained in this notice, the names of the copyright holders
 | |
|  * shall not be used in advertising or otherwise to promote the sale, use
 | |
|  * or other dealings in this Software without prior written authorization
 | |
|  * from said copyright holders.
 | |
|  */
 | |
| 
 | |
| /*******************************************************************
 | |
| **
 | |
| **    *********************************************************
 | |
| **    *
 | |
| **    *  File:		PsFonts.c
 | |
| **    *
 | |
| **    *  Contents:	Font code for PS driver.
 | |
| **    *
 | |
| **    *  Created By:	Roger Helmendach (Liberty Systems)
 | |
| **    *
 | |
| **    *  Copyright:	Copyright 1996 The Open Group, Inc.
 | |
| **    *
 | |
| **    *********************************************************
 | |
| ** 
 | |
| ********************************************************************/
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include "regionstr.h"
 | |
| #include <X11/fonts/fontstruct.h>
 | |
| #include "dixfontstr.h"
 | |
| #include "scrnintstr.h"
 | |
| #include <X11/fonts/fontxlfd.h>
 | |
| #include <X11/fonts/fntfil.h>
 | |
| #include <X11/fonts/fntfilst.h>
 | |
| 
 | |
| #include "Ps.h"
 | |
| 
 | |
| #include <ctype.h>
 | |
| #include <limits.h>
 | |
| #include <sys/stat.h>
 | |
| 
 | |
| Bool
 | |
| PsRealizeFont(
 | |
|   ScreenPtr  pscr,
 | |
|   FontPtr    pFont)
 | |
| {
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| Bool
 | |
| PsUnrealizeFont(
 | |
|   ScreenPtr  pscr,
 | |
|   FontPtr    pFont)
 | |
| {
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| char *
 | |
| PsGetFontName(FontPtr pFont)
 | |
| {
 | |
|   int         i;
 | |
|   int         nprops = pFont->info.nprops;
 | |
|   FontPropPtr props  = pFont->info.props;
 | |
|   Atom        name   = MakeAtom("FONT", 4, True);
 | |
|   Atom        value  = (Atom)0;
 | |
| 
 | |
|   for( i=0 ; i<nprops ; i++ )
 | |
|   {
 | |
|     if( (Atom)props[i].name==name )
 | |
|       { value = props[i].value; break; }
 | |
|   }
 | |
|   if( !value ) return (char *)0;
 | |
|   return NameForAtom(value);
 | |
| }
 | |
| 
 | |
| int
 | |
| PsGetFontSize(FontPtr pFont, float *mtx)
 | |
| {
 | |
|   FontScalableRec   vals;
 | |
|   char             *name = PsGetFontName(pFont);
 | |
|   int               value = 0;
 | |
| 
 | |
|   FontParseXLFDName(name, &vals, FONT_XLFD_REPLACE_NONE);
 | |
|   if( vals.values_supplied&PIXELSIZE_ARRAY )
 | |
|   {
 | |
|     int  i;
 | |
|     for( i=0 ; i<4 ; i++ )
 | |
|       mtx[i] = (float)vals.pixel_matrix[i];
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     value = vals.pixel;
 | |
|     if( !value ) value = 20;
 | |
|   }
 | |
|   return value;
 | |
| }
 | |
| 
 | |
| char *
 | |
| PsGetPSFontName(FontPtr pFont)
 | |
| {
 | |
|   int         i;
 | |
|   int         nprops = pFont->info.nprops;
 | |
|   FontPropPtr props  = pFont->info.props;
 | |
|   /* "_ADOBE_POSTSCRIPT_FONTNAME" maps directly to a PMF OBJ_NAME attribute
 | |
|    * name - changing the name will break printer-builtin fonts. */
 | |
|   Atom        name   = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, True); 
 | |
|   Atom        value  = (Atom)0;
 | |
| 
 | |
|   for( i=0 ; i<nprops ; i++ )
 | |
|   {
 | |
|     if( (Atom)props[i].name==name )
 | |
|       { value = props[i].value; break; }
 | |
|   }
 | |
|   if( !value ) return (char *)0; 
 | |
|   return NameForAtom(value);
 | |
| }
 | |
| 
 | |
| int
 | |
| PsIsISOLatin1Encoding(FontPtr pFont)
 | |
| {
 | |
|   int          i;
 | |
|   int          nprops = pFont->info.nprops;
 | |
|   FontPropPtr  props  = pFont->info.props;
 | |
|   Atom         reg = MakeAtom("CHARSET_REGISTRY", 16, True);
 | |
|   Atom         enc = MakeAtom("CHARSET_ENCODING", 16, True);
 | |
|   Atom         rv = 0, ev = 0;
 | |
|   char        *rp = 0;
 | |
|   char        *ep = 0;
 | |
| 
 | |
|   for( i=0 ; i<nprops ; i++ )
 | |
|   {
 | |
|     if( (Atom)props[i].name==reg ) rv = props[i].value;
 | |
|     if( (Atom)props[i].name==enc ) ev = props[i].value;
 | |
|   }
 | |
|   if( rv ) rp = NameForAtom(rv);
 | |
|   if( ev ) ep = NameForAtom(ev);
 | |
|   if( (!rp) || (!ep) ) return(0);
 | |
|   if( (char)tolower(rp[0])!='i' ||
 | |
|       (char)tolower(rp[1])!='s' ||
 | |
|       (char)tolower(rp[2])!='o' ||
 | |
|       memcmp(&rp[3], "8859", 4)!=0 ||
 | |
|       ep[0]!='1' ) return(0);
 | |
|   return(1);
 | |
| }
 | |
| 
 | |
| /* Return the encoding part of the XLFD (e.g. "*-iso8859-6.8x" etc.)*/
 | |
| char *PsGetEncodingName(FontPtr pFont)
 | |
| {
 | |
|   int          i;
 | |
|   int          nprops = pFont->info.nprops;
 | |
|   FontPropPtr  props  = pFont->info.props;
 | |
|   Atom         fnt = MakeAtom("FONT",              4, True);
 | |
|   Atom         reg = MakeAtom("CHARSET_REGISTRY", 16, True);
 | |
|   Atom         enc = MakeAtom("CHARSET_ENCODING", 16, True);
 | |
|   Atom         fv = 0, rv = 0, ev = 0;
 | |
|   char        *fp = 0;
 | |
|   char        *rp = 0;
 | |
|   char        *ep = 0;
 | |
|   char        *encname;
 | |
| 
 | |
|   for( i=0 ; i<nprops ; i++ )
 | |
|   {
 | |
|     if( props[i].name==fnt ) fv = props[i].value;
 | |
|     if( props[i].name==reg ) rv = props[i].value;
 | |
|     if( props[i].name==enc ) ev = props[i].value;
 | |
|   }
 | |
|   if( fv ) fp = NameForAtom(fv);
 | |
|   if( rv ) rp = NameForAtom(rv);
 | |
|   if( ev ) ep = NameForAtom(ev);
 | |
| 
 | |
|   if( (!rp) || (!ep) || (!fp))
 | |
|     return(0);
 | |
|   
 | |
|   encname  = fp;
 | |
|   encname += strlen(encname) - (strlen(rp) + strlen(ep) + 1);
 | |
|   
 | |
|   return encname;
 | |
| }
 | |
| 
 | |
| /* strstr(), case-insensitive */
 | |
| static 
 | |
| char *str_case_str(const char *s, const char *find)
 | |
| {
 | |
|   size_t len;
 | |
|   char   c, 
 | |
|          sc;
 | |
| 
 | |
|   if ((c = tolower(*find++)) != '\0')
 | |
|   {
 | |
|     len = strlen(find);
 | |
|     do 
 | |
|     {
 | |
|       do
 | |
|       {
 | |
|         if ((sc = tolower(*s++)) == '\0')
 | |
|           return NULL;
 | |
|       } while (sc != c);
 | |
|     } while (strncasecmp(s, find, len) != 0);
 | |
|     s--;
 | |
|   }
 | |
|   return ((char *)s);
 | |
| }
 | |
| 
 | |
| /* Check if the font path element is a directory which can be examined
 | |
|  * (for example the font may be from a font server
 | |
|  * (e.g. pFont->fpe->name == "tcp/:7100"))
 | |
|  */
 | |
| static
 | |
| Bool IsFPEaReadableDir(FontPtr pFont)
 | |
| {
 | |
|   const char *fpe_name = pFont->fpe->name;
 | |
|   if (!fpe_name)
 | |
|     return False;
 | |
| 
 | |
| #define MODEL_FONTPATH_PREFIX     "PRINTER:"
 | |
| #define MODEL_FONTPATH_PREFIX_LEN 8
 | |
|   /* Strip model-specific font path prefix if there is one... */
 | |
|   if (!strncmp(fpe_name, MODEL_FONTPATH_PREFIX, MODEL_FONTPATH_PREFIX_LEN))
 | |
|     fpe_name += MODEL_FONTPATH_PREFIX_LEN;
 | |
|     
 | |
|   if (access(fpe_name, F_OK) == 0)
 | |
|   {
 | |
|     return True;
 | |
|   }
 | |
| 
 | |
|   return False;
 | |
| }
 | |
| 
 | |
| static
 | |
| char *getFontFilename(FontPtr pFont)
 | |
| {
 | |
|   FontDirectoryPtr   dir;
 | |
|   const char        *dlfnam;
 | |
|   FILE              *file;
 | |
|   struct stat        statb;
 | |
|   char               buf[512];
 | |
|   char              *front, *fn;
 | |
|   char               font_dir_fname[PATH_MAX],  /* Full path of fonts.dir */
 | |
|                      font_file_fname[PATH_MAX]; /* Name of font file (excluding path) */
 | |
| 
 | |
| #ifdef XP_USE_FREETYPE
 | |
|   if( PsIsFreeTypeFont(pFont) )
 | |
|   {
 | |
|     const char  *fontname = PsGetFTFontFileName(pFont);
 | |
| 
 | |
| #ifdef DEBUG_gisburn
 | |
|     fprintf(stderr, "getFontFilename: freetype font, file='%s'\n", fontname?fontname:"<NULL>");
 | |
| #endif /* DEBUG_gisburn */  
 | |
| 
 | |
|     if( !fontname )
 | |
|       return NULL;
 | |
|       
 | |
|     return strdup(fontname);
 | |
|   }
 | |
| #endif /* XP_USE_FREETYPE */
 | |
| 
 | |
|   if (!IsFPEaReadableDir(pFont))
 | |
|   {
 | |
| #ifdef DEBUG_gisburn
 | |
|     fprintf(stderr, "getFontFilename: '%s' no valid font path on disk\n", pFont->fpe->name);
 | |
| #endif /* DEBUG_gisburn */  
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   dir = pFont->fpe->private;
 | |
|   sprintf(font_dir_fname, "%s%s", dir->directory, "fonts.dir");  
 | |
|   
 | |
|   if (!(dlfnam = PsGetFontName(pFont)))
 | |
|     return NULL;
 | |
|   
 | |
|   file = fopen(font_dir_fname, "r");
 | |
|   if (file)
 | |
|   {
 | |
|     if (fstat (fileno(file), &statb) == -1)
 | |
|       return NULL;
 | |
| 
 | |
|     while( fgets(buf, sizeof(buf)-1, file) )
 | |
|     {             
 | |
|       if ((fn = strstr(buf, " -")))
 | |
|       {
 | |
|         strcpy(font_file_fname, buf);
 | |
|         font_file_fname[fn - buf] = '\0';
 | |
|         fn++;
 | |
|         if ((front = str_case_str(fn, "normal-")))
 | |
|         {
 | |
|           fn[front - fn] = '\0';
 | |
|           if (str_case_str(dlfnam, fn))        
 | |
|           {
 | |
|             char full_font_file_path[PATH_MAX];
 | |
| 
 | |
|             fclose(file);
 | |
|             
 | |
|             sprintf(full_font_file_path, "%s%s", dir->directory, font_file_fname);
 | |
| 
 | |
| #ifdef xDEBUG_gisburn
 | |
|             fprintf(stderr, "getFontFilename: returning '%s'\n", full_font_file_path);
 | |
| #endif /* DEBUG_gisburn */
 | |
|             return strdup(full_font_file_path); 
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   font_file_fname[0] = '\0';
 | |
|   fclose(file);
 | |
| 
 | |
| #ifdef DEBUG_gisburn
 | |
|   fprintf(stderr, "getFontFilename: returning NULL\n");
 | |
| #endif /* DEBUG_gisburn */
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| static
 | |
| PsFontTypeInfoRec *PsFindFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
 | |
| {
 | |
|   PsContextPrivRec  *cPriv = PsGetPsContextPriv(pDrawable);
 | |
|   PsFontTypeInfoRec *rec;
 | |
|   const char        *psname;
 | |
|   char              *font_filename;
 | |
|   char              *encname;
 | |
| #ifdef XP_USE_FREETYPE
 | |
|   Bool               is_freetypefont;
 | |
| #endif /* XP_USE_FREETYPE */
 | |
|   
 | |
| #ifdef XP_USE_FREETYPE
 | |
|   is_freetypefont = PsIsFreeTypeFont(pFont);
 | |
| #endif /* XP_USE_FREETYPE */
 | |
|   encname         = PsGetEncodingName(pFont);
 | |
| 
 | |
|   /* First try: Search by PostScript font name */
 | |
|   psname = PsGetPSFontName(pFont);
 | |
|   if (psname)
 | |
|   {
 | |
|     for( rec = cPriv->fontTypeInfoRecords ; rec != NULL ; rec = rec->next )
 | |
|     {
 | |
| #ifdef XP_USE_FREETYPE
 | |
|       if (is_freetypefont)
 | |
|       {
 | |
|         if (rec->adobe_ps_name)
 | |
|         {
 | |
|           if ((rec->font_type == PSFTI_FONT_TYPE_FREETYPE) &&
 | |
|               (!strcmp(rec->adobe_ps_name, psname)) &&
 | |
|               (!strcmp(rec->ft_download_encoding, encname)))
 | |
|           {
 | |
|             return rec;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
| #endif /* XP_USE_FREETYPE */
 | |
|       {
 | |
|         if (rec->adobe_ps_name)
 | |
|         {
 | |
|           if ((rec->font_type != PSFTI_FONT_TYPE_FREETYPE) &&
 | |
|               (!strcmp(rec->adobe_ps_name, psname)))
 | |
|           {
 | |
|             return rec;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Last attempt: Search by filename */
 | |
|   font_filename = getFontFilename(pFont);
 | |
|   if (font_filename)
 | |
|   {
 | |
|     for( rec = cPriv->fontTypeInfoRecords ; rec != NULL ; rec = rec->next )
 | |
|     {
 | |
|       if (rec->filename)
 | |
|       {
 | |
| #ifdef XP_USE_FREETYPE
 | |
|         if (is_freetypefont)
 | |
|         {
 | |
|           if ( (rec->font_type == PSFTI_FONT_TYPE_FREETYPE) &&
 | |
|                (!strcasecmp(rec->filename, font_filename)) && 
 | |
|                (!strcasecmp(rec->ft_download_encoding, encname)) )
 | |
|           {
 | |
|             free(font_filename);
 | |
|             return rec;
 | |
|           }
 | |
|         }
 | |
|         else
 | |
| #endif /* XP_USE_FREETYPE */
 | |
|         {
 | |
|           if ( (rec->font_type != PSFTI_FONT_TYPE_FREETYPE) &&
 | |
|                (!strcasecmp(rec->filename, font_filename)) )
 | |
|           {
 | |
|             free(font_filename);
 | |
|             return rec;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     free(font_filename);
 | |
|   }
 | |
|   
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| static
 | |
| void PsAddFontTypeInfoRec(DrawablePtr pDrawable, PsFontTypeInfoRec *add_rec)
 | |
| { 
 | |
|   PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
 | |
| 
 | |
|   /* ToDO: Always move the last used entry to the top that the list get's
 | |
|    * sorted in an efficient order... :-) */
 | |
|   add_rec->next = cPriv->fontTypeInfoRecords;
 | |
|   cPriv->fontTypeInfoRecords = add_rec;
 | |
| }
 | |
| 
 | |
| static
 | |
| Bool strcaseendswith(const char *str, const char *suffix)
 | |
| {
 | |
|   const char *s;
 | |
| 
 | |
|   s = str + strlen(str) - strlen(suffix);
 | |
| 
 | |
|   if (!strcasecmp(s, suffix))
 | |
|     return True;
 | |
| 
 | |
|   return False;
 | |
| }
 | |
| 
 | |
| 
 | |
| static
 | |
| int getFontFileType( const char *filename )
 | |
| {
 | |
|   int type;
 | |
| 
 | |
|   /* Is this a Adobe PostScript Type 1 binary font (PFB) ? */
 | |
|   if( strcaseendswith(filename, ".pfb") )
 | |
|   {
 | |
|     type = PSFTI_FONT_TYPE_PS_TYPE1_PFB;
 | |
|   }
 | |
|   /* Is this a Adobe PostScript ASCII font (PFA) ? */
 | |
|   else if( strcaseendswith(filename, ".pfa") )
 | |
|   {
 | |
|     type = PSFTI_FONT_TYPE_PS_TYPE1_PFA;
 | |
|   }
 | |
|   /* Is this a PMF(=Printer Metrics File) ? */
 | |
|   else if( strcaseendswith(filename, ".pmf") )
 | |
|   {
 | |
|     type = PSFTI_FONT_TYPE_PMF;
 | |
|   }
 | |
|   /* Is this a TrueType font file ? */
 | |
|   else if( strcaseendswith(filename, ".ttf") ||
 | |
|            strcaseendswith(filename, ".ttc") ||
 | |
|            strcaseendswith(filename, ".otf") ||
 | |
|            strcaseendswith(filename, ".otc") )
 | |
|   {
 | |
|     type = PSFTI_FONT_TYPE_TRUETYPE;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     type = PSFTI_FONT_TYPE_OTHER;
 | |
|   }
 | |
| 
 | |
| #ifdef XP_USE_FREETYPE
 | |
|   {
 | |
|     XpContextPtr  pCon;
 | |
|     char         *downloadfonts;
 | |
|     pCon = XpGetPrintContext(requestingClient);
 | |
|     downloadfonts = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-psddx-download-fonts");
 | |
|     if( downloadfonts )
 | |
|     {
 | |
|       /* Should we download PS Type1 fonts as PS Type1||Type3 ? */
 | |
|       if( (type == PSFTI_FONT_TYPE_PS_TYPE1_PFA) &&
 | |
|           (strstr(downloadfonts, "pfa") != NULL) )
 | |
|       {
 | |
|         type = PSFTI_FONT_TYPE_FREETYPE;
 | |
|       }
 | |
| 
 | |
|       if( (type == PSFTI_FONT_TYPE_PS_TYPE1_PFB) &&
 | |
|           (strstr(downloadfonts, "pfb") != NULL) )
 | |
|       {
 | |
|         type = PSFTI_FONT_TYPE_FREETYPE;
 | |
|       }
 | |
| 
 | |
|       /* Should we download TrueType fonts as PS Type1||Type3 ? */
 | |
|       if( (type == PSFTI_FONT_TYPE_TRUETYPE) &&
 | |
|           ((strstr(downloadfonts, "ttf") != NULL) || 
 | |
|            (strstr(downloadfonts, "ttc") != NULL) || 
 | |
|            (strstr(downloadfonts, "otf") != NULL) || 
 | |
|            (strstr(downloadfonts, "otc") != NULL)) )
 | |
|       {
 | |
|         type = PSFTI_FONT_TYPE_FREETYPE;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #endif /* XP_USE_FREETYPE */
 | |
| 
 | |
| #ifdef DEBUG_gisburn
 | |
|   fprintf(stderr, "getFontFileType: '%s' is %d\n", filename, (int)type);
 | |
| #endif /* DEBUG_gisburn */
 | |
|   return type;
 | |
| }
 | |
| 
 | |
| PsFTDownloadFontType PsGetFTDownloadFontType(void)
 | |
| {
 | |
|   PsFTDownloadFontType  downloadfonttype;
 | |
|   XpContextPtr          pCon;
 | |
|   char                 *psfonttype;
 | |
| 
 | |
|   pCon       = XpGetPrintContext(requestingClient);
 | |
|   psfonttype = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-psddx-download-font-type");
 | |
| 
 | |
|   if( !psfonttype || !strlen(psfonttype) )
 | |
|   {
 | |
|     return PsFontType1; /* Default download font type is PS Type1 */
 | |
|   }
 | |
| 
 | |
|   if( !strcmp(psfonttype, "bitmap") )
 | |
|   {
 | |
|     downloadfonttype = PsFontBitmap;
 | |
|   }
 | |
|   else if( !strcmp(psfonttype, "pstype3") )
 | |
|   {
 | |
|     downloadfonttype = PsFontType3;
 | |
|   }
 | |
|   else if( !strcmp(psfonttype, "pstype1") )
 | |
|   { 
 | |
|     downloadfonttype = PsFontType1;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|      FatalError("PS DDX: XPPrinterAttr/xp-psddx-download-freetype-font-type='%s' not implemented\n", psfonttype);
 | |
|      return 0; /* NO-OP, FatalError() will call |exit()| */
 | |
|   }
 | |
|   
 | |
|   return downloadfonttype;
 | |
| }
 | |
| 
 | |
| static
 | |
| PsFontTypeInfoRec *PsCreateFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
 | |
| {
 | |
|   char              *dlfnam;
 | |
|   PsFontTypeInfoRec *rec;
 | |
|   
 | |
|   if (!(dlfnam = PsGetFontName(pFont)))
 | |
|     return NULL;
 | |
| 
 | |
|   if (!(rec = (PsFontTypeInfoRec *)xalloc(sizeof(PsFontTypeInfoRec))))
 | |
|     return NULL;
 | |
|   memset(rec, 0, sizeof(PsFontTypeInfoRec));
 | |
| 
 | |
|   rec->next              = NULL;
 | |
| 
 | |
|   if ((rec->filename = getFontFilename(pFont)))
 | |
|   {
 | |
|     rec->font_type = getFontFileType(rec->filename);   
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     rec->filename  = NULL;
 | |
|     rec->font_type = PSFTI_FONT_TYPE_OTHER;
 | |
|   }
 | |
| 
 | |
|   rec->adobe_ps_name         = PsGetPSFontName(pFont);
 | |
| #ifdef XP_USE_FREETYPE
 | |
|   rec->ft_download_encoding  = PsGetEncodingName(pFont);
 | |
|   rec->ft_download_font_type = PsGetFTDownloadFontType();
 | |
| #endif /* XP_USE_FREETYPE */
 | |
|   rec->download_ps_name      = NULL;
 | |
| 
 | |
| #define SET_FONT_DOWNLOAD_STATUS(rec, downloaded) { int i; for (i = 0 ; i < 256 ; i++) { (rec)->alreadyDownloaded[i]=(downloaded); } }
 | |
| 
 | |
|   /* Set some flags based on the font type */
 | |
|   switch( rec->font_type )
 | |
|   {
 | |
|     case PSFTI_FONT_TYPE_PS_TYPE1_PFA:
 | |
|     case PSFTI_FONT_TYPE_PS_TYPE1_PFB:
 | |
|       rec->downloadableFont  = True;
 | |
|       SET_FONT_DOWNLOAD_STATUS(rec, False);
 | |
|       rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
 | |
|       break;
 | |
| 
 | |
|     case PSFTI_FONT_TYPE_PMF:
 | |
|       rec->downloadableFont  = True; /* This font is in printer's ROM */
 | |
|       SET_FONT_DOWNLOAD_STATUS(rec, True);
 | |
|       rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
 | |
|       break;
 | |
|     
 | |
|     case PSFTI_FONT_TYPE_TRUETYPE:
 | |
|       /* Note: TrueType font download not implemented */
 | |
|       rec->downloadableFont  = False;
 | |
|       SET_FONT_DOWNLOAD_STATUS(rec, False);
 | |
|       rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
 | |
|       break;
 | |
| 
 | |
| #ifdef XP_USE_FREETYPE
 | |
|     case PSFTI_FONT_TYPE_FREETYPE:
 | |
|       if( rec->ft_download_font_type == PsFontType1 ||
 | |
|           rec->ft_download_font_type == PsFontType3 )
 | |
|       {
 | |
|         rec->downloadableFont = True;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         rec->downloadableFont = False;
 | |
|       }
 | |
| 
 | |
|       SET_FONT_DOWNLOAD_STATUS(rec, False);
 | |
|       rec->is_iso_encoding   = False; /* Freetype--->PS Type1/Type3 uses always non-iso PS encoding for now */
 | |
|       break;
 | |
| #endif /* XP_USE_FREETYPE */
 | |
| 
 | |
|     case PSFTI_FONT_TYPE_OTHER:
 | |
|     default:
 | |
|       rec->downloadableFont  = False;
 | |
|       SET_FONT_DOWNLOAD_STATUS(rec, False);
 | |
|       rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
 | |
|       break;
 | |
|   }
 | |
|   
 | |
| #ifdef XP_USE_FREETYPE
 | |
|   if( (rec->font_type == PSFTI_FONT_TYPE_FREETYPE) )
 | |
|   {
 | |
|     char *s;
 | |
|     register int c;
 | |
| 
 | |
|     if( rec->adobe_ps_name )
 | |
|     {
 | |
|       rec->download_ps_name = malloc(strlen(rec->adobe_ps_name) + strlen(rec->ft_download_encoding) + 2);
 | |
|       sprintf(rec->download_ps_name, "%s_%s", rec->adobe_ps_name, rec->ft_download_encoding);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Unfortunately not all TTF fonts have a PostScript font name (like
 | |
|        * Solaris TTF fonts in /usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType,
 | |
|        * /usr/openwin/lib/locale/ko/X11/fonts/TrueType) - in this case we
 | |
|        * have to generate a font name
 | |
|        */
 | |
|       char        ftfontname[64];
 | |
|       static long myfontindex = 0L;
 | |
|       sprintf(ftfontname, "psfont_%lx", myfontindex++);
 | |
|       
 | |
|       rec->download_ps_name = malloc(strlen(ftfontname) + strlen(rec->ft_download_encoding) + 2);
 | |
|       sprintf(rec->download_ps_name, "%s_%s", ftfontname, rec->ft_download_encoding);
 | |
|       
 | |
|       fprintf(stderr, "PsCreateFontTypeInfoRec: Note: '%s' has no PS font name, using '%s' for now.\n", dlfnam, rec->download_ps_name);
 | |
|     }
 | |
|     
 | |
|     /* Make sure the font name we use for download is a valid PS font name */
 | |
|     for( s = rec->download_ps_name ; *s != '\0'; s++ )
 | |
|     {
 | |
|       c = *s;
 | |
|       
 | |
|       /* Check for allowed chars, invalid ones are replaced with a '_'
 | |
|        * (and check that the first char is not a digit) */
 | |
|       if( !(isalnum(c) || c == '.' || c == '_' || c == '-') || (s==rec->download_ps_name && isdigit(c)) )
 | |
|       {
 | |
|         *s = '_';
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   else
 | |
| #endif /* XP_USE_FREETYPE */
 | |
|   {
 | |
|     if( rec->adobe_ps_name )
 | |
|     {
 | |
|       rec->download_ps_name = strdup(rec->adobe_ps_name);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       rec->download_ps_name = NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Safeguard - only treat font as downloadable when we have a PS font name!! */
 | |
|   if (!rec->download_ps_name && rec->downloadableFont)
 | |
|   {
 | |
|     /* XXX: Log this message to the log when the logging service has been hook'ed up */
 | |
|     fprintf(stderr, "PsCreateFontTypeInfoRec: Safeguard: No PS font name for '%s'!\n", dlfnam);
 | |
|     rec->downloadableFont = False;
 | |
|   }
 | |
| 
 | |
| #ifdef DEBUG_gisburn
 | |
|   fprintf(stderr, "PsCreateFontTypeInfoRec: Created PsFontTypeInfoRec '%s' ('%s'/'%s')\n",
 | |
|           ((rec->filename)        ?(rec->filename)     :("<null>")),
 | |
|           ((rec->adobe_ps_name)   ?(rec->adobe_ps_name):("<null>")),
 | |
|           ((rec->download_ps_name)?(rec->download_ps_name):("<null>")));
 | |
| #endif /* DEBUG_gisburn */
 | |
| 
 | |
|   return rec;
 | |
| }
 | |
| 
 | |
| static
 | |
| PsFontTypeInfoRec *PsGetFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
 | |
| {
 | |
|   PsFontTypeInfoRec *rec;
 | |
|   char              *dlfnam;
 | |
| 
 | |
|   if(!(dlfnam = PsGetFontName(pFont)))
 | |
|     return NULL;
 | |
|   
 | |
|   rec = PsFindFontTypeInfoRec(pDrawable, pFont);
 | |
|   if (rec)
 | |
|     return rec;
 | |
|     
 | |
|   rec = PsCreateFontTypeInfoRec(pDrawable, pFont);
 | |
|   if (!rec)
 | |
|     return NULL;
 | |
|   
 | |
|   PsAddFontTypeInfoRec(pDrawable, rec);
 | |
| 
 | |
|   return rec;
 | |
| }
 | |
| 
 | |
| static
 | |
| void PsFreeFontTypeInfoRecords( PsContextPrivPtr priv )
 | |
| {
 | |
|   PsFontTypeInfoRec *curr, *next;
 | |
|   curr = priv->fontTypeInfoRecords;
 | |
|   while( curr != NULL )
 | |
|   {
 | |
|     if (curr->filename)
 | |
|       free(curr->filename); /* Free memory allocated by |strdup()| */
 | |
| 
 | |
|     if (curr->download_ps_name)
 | |
|       free(curr->download_ps_name);
 | |
|       
 | |
|     next = curr->next;
 | |
|     xfree(curr);
 | |
|     curr = next;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static
 | |
| PsFontInfoRec *PsFindFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
 | |
| {
 | |
|   PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
 | |
|   PsFontInfoRec    *rec;
 | |
| 
 | |
|   if (!pFont)
 | |
|     return NULL;
 | |
| 
 | |
|   for( rec = cPriv->fontInfoRecords ; rec != NULL ; rec = rec->next )
 | |
|   {
 | |
|     if ((rec->font == pFont) && 
 | |
|         (rec->font_fontPrivate == pFont->fontPrivate))
 | |
|       return rec;
 | |
|   }
 | |
|   
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| static
 | |
| void PsAddFontInfoRec(DrawablePtr pDrawable, PsFontInfoRec *add_rec)
 | |
| { 
 | |
|   PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
 | |
| 
 | |
|   /* ToDO: Always move the last used entry to the top that the list get's
 | |
|    * sorted in an efficient order... :-) */
 | |
|   add_rec->next = cPriv->fontInfoRecords;
 | |
|   cPriv->fontInfoRecords = add_rec;
 | |
| }
 | |
| 
 | |
| static
 | |
| PsFontInfoRec *PsCreateFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
 | |
| {
 | |
|   PsFontInfoRec     *rec;
 | |
|   PsFontTypeInfoRec *ftir;
 | |
|   
 | |
|   if (!(ftir = PsGetFontTypeInfoRec(pDrawable, pFont)))
 | |
|     return NULL;
 | |
| 
 | |
|   if (!(rec = (PsFontInfoRec *)xalloc(sizeof(PsFontInfoRec))))
 | |
|     return NULL;
 | |
|   memset(rec, 0, sizeof(PsFontInfoRec));
 | |
| 
 | |
|   rec->font     = pFont;
 | |
|   rec->font_fontPrivate = pFont->fontPrivate;
 | |
|   rec->ftir     = ftir;
 | |
|   rec->next     = NULL;
 | |
|   rec->dfl_name = PsGetFontName(pFont);
 | |
|   rec->size     = PsGetFontSize(pFont, rec->mtx);
 | |
| 
 | |
| #ifdef DEBUG_gisburn
 | |
|   fprintf(stderr, "PsCreateFontInfoRec: Created PsFontInfoRec '%s'\n",
 | |
|           ((rec->dfl_name)?(rec->dfl_name):("<null>")));
 | |
| #endif /* DEBUG_gisburn */
 | |
| 
 | |
|   return rec;
 | |
| }
 | |
| 
 | |
| PsFontInfoRec *PsGetFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
 | |
| {
 | |
|   PsFontInfoRec *rec;
 | |
| 
 | |
|   rec = PsFindFontInfoRec(pDrawable, pFont);
 | |
|   if (rec)
 | |
|     return rec;
 | |
|     
 | |
|   rec = PsCreateFontInfoRec(pDrawable, pFont);
 | |
|   if (!rec)
 | |
|     return NULL;
 | |
|   
 | |
|   PsAddFontInfoRec(pDrawable, rec);
 | |
| 
 | |
|   return rec;
 | |
| }
 | |
| 
 | |
| void PsFreeFontInfoRecords( PsContextPrivPtr priv )
 | |
| {
 | |
|   PsFontInfoRec *curr, *next;
 | |
|   curr = priv->fontInfoRecords;
 | |
|   while( curr != NULL )
 | |
|   {  
 | |
|     next = curr->next;
 | |
|     xfree(curr);
 | |
|     curr = next;
 | |
|   }
 | |
|   
 | |
|   PsFreeFontTypeInfoRecords(priv);
 | |
| 
 | |
|   priv->fontTypeInfoRecords = NULL;
 | |
|   priv->fontInfoRecords     = NULL;
 | |
| }
 |