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;
 | 
						|
}
 |