Main Page   Modules   Alphabetical List   Compound List   File List   Compound Members   File Members  

fontlist.c

Go to the documentation of this file.
00001 /*  $Id: fontlist.c,v 1.9 2000/12/11 22:15:36 dbryson Exp $
00002 **
00003 **  Copyright (c) 2000 Derry Bryson <derry@techass.com>
00004 **
00005 **  Description:
00006 **  
00007 **    Postscript Library
00008 **
00009 **
00010 **  License:
00011 **
00012 **    This library is free software; you can redistribute it and/or
00013 **    modify it under the terms of the GNU Lesser General Public
00014 **    License as published by the Free Software Foundation; either
00015 **    version 2.1 of the License, or (at your option) any later version.
00016 **
00017 **    This library is distributed in the hope that it will be useful,
00018 **    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 **    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 **    Lesser General Public License for more details.
00021 **
00022 **    You should have received a copy of the GNU Lesser General Public
00023 **    License along with this library; if not, write to the Free Software
00024 **    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 **
00026 **
00027 **  Contact:
00028 **
00029 **      Mail:
00030 **
00031 **        Technology Associates, Inc.
00032 **        LIBPS Project
00033 **        1455 Deming Way #11
00034 **        Sparks, NV  89431
00035 **        USA
00036 **
00037 **      Email:
00038 **
00039 **        libps@techass.com
00040 **
00041 **      See our website at:
00042 **
00043 **        libps.sourceforge.net
00044 **
00045 */
00046 
00047 
00057 #ifdef HAVE_CONFIG_H
00058 # include "psconfig.h"
00059 #endif
00060 
00061 #include <stdio.h>
00062 #include <stdlib.h>
00063 #include <string.h>
00064 #include <unistd.h>
00065 #include <sys/stat.h>
00066 #include <ctype.h>
00067 #include "ps/ps.h"
00068 
00069 #if HAVE_DIRENT_H
00070 # include <dirent.h>
00071 # define NAMLEN(dirent) strlen((dirent)->d_name)
00072 #else
00073 # define dirent direct
00074 # define NAMLEN(dirent) (dirent)->d_namlen
00075 # if HAVE_SYS_NDIR_H
00076 #  include <sys/ndir.h>
00077 # endif
00078 # if HAVE_SYS_DIR_H
00079 #  include <sys/dir.h>
00080 # endif
00081 # if HAVE_NDIR_H
00082 #  include <ndir.h>
00083 # endif
00084 #endif
00085 
00086 #define MAX_EXT_LEN             4               // max extension length
00087 
00088 #define XFONTSDIR               "fonts.dir"
00089 
00095 PSFontType 
00096   psFontTypes[] =
00097   {
00098     { ".ttf", PS_FONTTYPE_TRUETYPE },
00099     { ".pfa", PS_FONTTYPE_PSTYPE1ALPHA },
00100     { ".pfb", PS_FONTTYPE_PSTYPE1BIN },
00101     { NULL, PS_FONTTYPE_UNKNOWN }
00102   };
00103   
00111 PSList
00112   *psFontList = NULL;
00113   
00119 static char
00120   *psFontPath = NULL;
00121   
00122 static char
00123   *curFontDir = NULL;
00124   
00125 static char
00126   **curExt = NULL;
00127   
00138 void 
00139 psFontListSetPath(char *path)
00140 {
00141   if(psFontPath)
00142     free(psFontPath);
00143   psFontPath = strdup(path);
00144 }
00145 
00152 char*
00153 psFontListGetPath(void)
00154 {
00155   return psFontPath;
00156 }
00157 
00164 void 
00165 psFontListAppendPath(char *dir)
00166 {
00167   char
00168     sep[2];
00169     
00170   if(psFontPath)
00171   {
00172     psFontPath = realloc(psFontPath, strlen(psFontPath) + strlen(dir) + 2);
00173     if(psFontPath)
00174     {
00175       sep[0] = PS_PATH_SEPARATOR;
00176       sep[1] = 0;
00177       strcat(psFontPath, sep);
00178       strcat(psFontPath, dir);
00179     }
00180   }
00181   else
00182     psFontPath = strdup(dir);
00183 }
00184 
00190 void 
00191 psFontListFreePath(void)
00192 {
00193   if(psFontPath)
00194     free(psFontPath);
00195   psFontPath = NULL;
00196 }
00197 
00211 static char*
00212 GetFontFileNameAndType(char *fmName, char **fontName, int *type)
00213 {
00214   int
00215    i;
00216    
00217   char
00218     *p;
00219     
00220   struct stat
00221     statBuf;
00222     
00223   p = malloc(strlen(fmName) + MAX_EXT_LEN + 1);  
00224   if(p)
00225   {
00226     strcpy(p, fmName);
00227     for(i = 0; psFontTypes[i].extension; i++)
00228     {
00229       if(strrchr(p, '.'))
00230         *strrchr(p, '.') = 0;
00231       strcat(p, psFontTypes[i].extension);
00232       if(!access(p, R_OK))
00233       {
00234         *fontName = p;
00235         *type = psFontTypes[i].type;
00236         return p;
00237       }
00238     }
00239     free(p);    
00240   }
00241   
00242   return NULL;
00243 }
00244 
00252 static int
00253 GetFontType(char *fileName)
00254 {
00255   int
00256     i;
00257     
00258   for(i = 0; psFontTypes[i].extension; i++)
00259     if(strlen(fileName) >= strlen(psFontTypes[i].extension))
00260       if(!strcmp(fileName + strlen(fileName) - strlen(psFontTypes[i].extension),
00261            psFontTypes[i].extension))
00262         break;
00263         
00264   return psFontTypes[i].type;
00265 }
00266 
00273 static int
00274 SelectDir(const struct dirent *d)
00275 {
00276   char
00277     *p;
00278     
00279   struct stat
00280     statBuf;
00281     
00282   p = malloc(strlen(curFontDir) + strlen(d->d_name) + 2);
00283   if(p)
00284   {
00285     strcpy(p, curFontDir);
00286     if(p[strlen(p) - 1] != '/')
00287       strcat(p, "/");
00288     strcat(p, d->d_name);
00289     if(!stat(p, &statBuf))
00290     {
00291       free(p);
00292       return S_ISDIR(statBuf.st_mode);
00293     }
00294     free(p);
00295   }
00296     
00297   return 0;
00298 }
00299 
00307 static int
00308 SelectExt(const struct dirent *d)
00309 {
00310   int
00311     i;
00312     
00313   for(i = 0; curExt[i]; i++)
00314   {
00315     if(strlen(d->d_name) >= strlen(curExt[i]))
00316       if(!strcmp(d->d_name + strlen(d->d_name) - strlen(curExt[i]),
00317            curExt[i]))
00318         return 1;
00319   }
00320   return 0;
00321 }
00322 
00330 static void
00331 LoadXFontsDir(char *dir)
00332 {
00333   char
00334     line[1024],
00335     *p,
00336     *fname;
00337     
00338   FILE
00339     *fp;
00340     
00341   int
00342     i,
00343     numFonts;
00344     
00345   PSFont
00346     *font;
00347     
00348   p = malloc(strlen(dir) + strlen(XFONTSDIR) + 2);
00349   if(p)
00350   {
00351     strcpy(p, dir);
00352     if(p[strlen(p) - 1] != '/')
00353       strcat(p, "/");
00354     strcat(p, XFONTSDIR);
00355     fp = fopen(p, "rb");
00356     free(p);
00357     if(fp)
00358     {
00359       if(fgets(line, 1024, fp))
00360       {
00361         numFonts = atoi(line);
00362         for(i = 0; i < numFonts && fgets(line, 1024, fp); i++)
00363         {
00364           for(p = line + strlen(line) - 1; isspace(*p); p--)
00365             *p = 0;
00366           for(p = line; *p && !isspace(*p); p++)
00367             ;
00368           *p = 0;
00369           p++;
00370           fname = malloc(strlen(dir) + strlen(line) + 2);
00371           if(fname)
00372           {
00373             strcpy(fname, dir);
00374             if(fname[strlen(fname) - 1] != '/')
00375               strcat(fname, "/");
00376             strcat(fname, line);
00377             font = psFontListLookupByFontFileName(fname);
00378             if(font)
00379             {
00380               for(; *p && isspace(*p); p++)
00381                 ;
00382               if(strlen(p))
00383                 psListInsert(font->xFontNames, NULL, strdup(p));
00384             }
00385             free(fname);
00386           }
00387         }
00388       }
00389       fclose(fp);    
00390     }
00391   }
00392 }
00393 
00404 static int
00405 ScanFontDir(char *dir, void (*statusFunc)(char* msg))
00406 {
00407   char
00408     *p,
00409     *q,
00410     *oldCurFontDir = curFontDir,
00411     **oldCurExt = curExt,
00412     msg[1024];
00413     
00414   struct dirent
00415     **namelist; 
00416     
00417   int
00418     fontType,
00419     i,
00420     n;
00421     
00422   PSFont
00423     *font;
00424     
00425   PSAFM
00426     *fm;
00427     
00428   PSTTFontInfo
00429     *finfo;
00430     
00431   static char
00432     *exts[] = 
00433     {
00434       ".ttf",
00435       ".pfb",
00436       ".pfa",
00437       NULL
00438     };
00439 
00440 //printf("scanning %s...\n", dir);    
00441   curFontDir = dir;
00442   
00443   /*
00444   **  First scan through and descend directories
00445   */
00446   n = scandir(dir, &namelist, SelectDir, alphasort);
00447   if(n > 0)
00448   {
00449     for(i = 0; i < n; i++)
00450     {
00451       if(strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, ".."))
00452       {
00453         p = malloc(strlen(dir) + strlen(namelist[i]->d_name) + 2);
00454         strcpy(p, dir);
00455         if(p[strlen(p) - 1] != '/')
00456           strcat(p, "/");
00457         strcat(p, namelist[i]->d_name);
00458         ScanFontDir(p, statusFunc);
00459         free(p);
00460       }
00461       free(namelist[i]);
00462     }
00463     free(namelist);
00464   }
00465   
00466   /*
00467   **  Now scan the files
00468   */
00469   curExt = exts;
00470   n = scandir(dir, &namelist, SelectExt, alphasort);
00471   if(n > 0)
00472   {
00473     for(i = 0; i < n; i++)
00474     {
00475 //printf("found %s\n", namelist[i]->d_name);    
00476       p = malloc(strlen(dir) + strlen(namelist[i]->d_name) + 2);
00477       if(p)
00478       {
00479         strcpy(p, dir);
00480         if(p[strlen(p) - 1] != '/')
00481           strcat(p, "/");
00482         strcat(p, namelist[i]->d_name);
00483         if(statusFunc)
00484         {
00485           sprintf(msg, "Loading: %s", p);
00486           statusFunc(msg);
00487         }
00488           
00489         if((fontType = GetFontType(p)) != PS_FONTTYPE_UNKNOWN)
00490         {
00491           font = psFontAlloc();
00492           if(font)
00493           {
00494             font->fontType = fontType;
00495             switch(fontType)
00496             {
00497               case PS_FONTTYPE_TRUETYPE :
00498                 finfo = psTTGetFontInfo(p);
00499                 if(finfo)
00500                 {
00501                   if(finfo->name)
00502                     font->fontName = strdup(finfo->name);
00503                   if(finfo->family)
00504                     font->fontFamily = strdup(finfo->family);
00505                   font->weight = psTTGetPSFontWeight(finfo);
00506                   font->width = psTTGetPSFontWidth(finfo);
00507                   font->italic = finfo->italic;
00508                   psTTFontInfoFree(finfo);
00509                 }
00510                 font->fontFileName = strdup(p);
00511               break;
00512           
00513               case PS_FONTTYPE_PSTYPE1ALPHA :
00514               case PS_FONTTYPE_PSTYPE1BIN :
00515                 q = strdup(p);
00516                 if(q)
00517                 {
00518                   if(strrchr(q, '.'))
00519                     *strrchr(q, '.') = 0;
00520                   strcat(q, PSAFM_FILEEXT);
00521                   fm = psAFMLoad(q);
00522                   if(fm)
00523                   {
00524                     font->fontMetric = fm;
00525                     font->fontName = strdup(fm->fontName);
00526                     font->fontFamily = strdup(fm->familyName);
00527                     font->fontMetricFileName = strdup(q);
00528                     font->fontFileName = strdup(p);
00529                     font->weight = psAFMGetPSWeight(fm);
00530                     font->width = psAFMGetPSWidth(fm);
00531                     font->italic = psAFMGetPSItalic(fm);
00532                   }
00533                   else
00534                   {
00535                     psFontFree(font);
00536                     font = NULL;
00537                   }
00538                   free(q);
00539                 }
00540               break;
00541             }  
00542             if(font)
00543               psListInsert(psFontList, NULL, font);
00544           }
00545         }
00546         free(p);
00547       }
00548       free(namelist[i]);
00549     }
00550     free(namelist);
00551   }
00552   
00553   /*
00554   **  Now read in the X Windows fonts.dir file and match up
00555   **  X font descriptions to fonts in the list.
00556   */
00557   LoadXFontsDir(dir);
00558     
00559   curFontDir = oldCurFontDir;
00560   curExt = oldCurExt;
00561   
00562   return 1;
00563 }
00564 
00571 static int
00572 ScanAFMDir(void (*statusFunc)(char* msg))
00573 {
00574   char
00575     *p,
00576     *dir,
00577     *oldCurFontDir = curFontDir,
00578     **oldCurExt = curExt,
00579     msg[1024];
00580     
00581   struct dirent
00582     **namelist; 
00583     
00584   int
00585     retVal = 0,
00586     i,
00587     n;
00588     
00589   PSFont
00590     *font;
00591     
00592   PSAFM
00593     *fm;
00594     
00595   static char
00596     *exts[] = 
00597     {
00598       ".afm",
00599       NULL
00600     };
00601 
00602   
00603   dir = PS_DATADIR;
00604   
00605   curFontDir = dir;
00606   
00607   curExt = exts;
00608   n = scandir(dir, &namelist, SelectExt, alphasort);
00609   if(n > 0)
00610   {
00611     for(i = 0; i < n; i++)
00612     {
00613       p = malloc(strlen(dir) + strlen(namelist[i]->d_name) + 2);
00614       if(p)
00615       {
00616         strcpy(p, dir);
00617         if(p[strlen(p) - 1] != '/')
00618           strcat(p, "/");
00619         strcat(p, namelist[i]->d_name);
00620         if(statusFunc)
00621         {
00622           sprintf(msg, "Loading: %s", p);
00623           statusFunc(msg);
00624         }
00625           
00626         font = psFontAlloc();
00627         if(font)
00628         {
00629           font->fontType = PS_FONTTYPE_PRINTER;
00630           fm = psAFMLoad(p);
00631           if(fm)
00632           {
00633             font->fontMetric = fm;
00634             font->fontName = strdup(fm->fontName);
00635             font->fontFamily = strdup(fm->familyName);
00636             font->fontMetricFileName = strdup(p);
00637             font->weight = psAFMGetPSWeight(fm);
00638             font->width = psAFMGetPSWidth(fm);
00639             font->italic = psAFMGetPSItalic(fm);
00640           }
00641           else
00642           {
00643             psFontFree(font);
00644             font = NULL;
00645           }
00646           if(font)
00647             psListInsert(psFontList, NULL, font);
00648         }
00649         free(p);
00650       }
00651       free(namelist[i]);
00652     }
00653     free(namelist);
00654   }
00655   retVal = 1;
00656   
00657 Outtahere:
00658   curFontDir = oldCurFontDir;
00659   curExt = oldCurExt;
00660   
00661   return retVal;
00662 }
00663 
00677 int 
00678 psFontListLoad(int flags, void(*statusFunc)(char* msg))
00679 {
00680   char
00681     *p,
00682     *q,
00683     *path;
00684     
00685   PSAFM
00686     *fm;
00687     
00688   /*
00689   **  Set default flags if necessary
00690   */
00691   if(flags == PS_FONTLIST_FLAG_DEFAULT)
00692     flags = PS_FONTLIST_FLAG_INCLUDE_TRUETYPE | 
00693             PS_FONTLIST_FLAG_INCLUDE_PSTYPE1 | 
00694             PS_FONTLIST_FLAG_INCLUDE_AFM;
00695             
00696   pserrno = PSERR_NONE;
00697   
00698   if(psFontList)
00699     psListFree(psFontList);
00700  
00701   psFontList = psListAlloc((PSListDestroyFunc)psFontFree);
00702   if(psFontList && psFontPath)
00703   {
00704     path = strdup(psFontPath);
00705     if(path)
00706     {
00707       p = q = path;
00708       for(q = p; *q && *q != PS_PATH_SEPARATOR; q++)
00709         ;
00710       if(*q)
00711       {
00712         *q = 0;
00713         q++;
00714       }
00715       while(*p)
00716       {
00717         ScanFontDir(p, statusFunc);
00718         p = q;
00719         for(q = p; *q && *q != PS_PATH_SEPARATOR; q++)
00720           ;
00721         if(*q)
00722         {
00723           *q = 0;
00724           q++;
00725         }
00726       }
00727       free(path);
00728     }
00729     
00730     if(flags & PS_FONTLIST_FLAG_INCLUDE_AFM)
00731       ScanAFMDir(statusFunc);
00732   }
00733   
00734   return !pserrno;
00735 }
00736 
00743 void 
00744 psFontListFree()
00745 {
00746   if(psFontList)
00747   {
00748     psListFree(psFontList);
00749     psFontList = NULL;
00750   }
00751 }
00752 
00762 PSFont* 
00763 psFontListLookupByFontName(char *fontName)
00764 {
00765   PSListNode
00766     *node;
00767     
00768   PSFont
00769     *font;
00770     
00771   if(psFontList)
00772   {
00773     node = psListFirst(psFontList);
00774     while(node)
00775     {
00776       font = psListGetValue(psFontList, node);
00777       if(font->fontName && !strcasecmp(font->fontName, fontName))
00778         return font;
00779       node = psListNext(psFontList, node);
00780     }
00781   }
00782   
00783   return NULL;
00784 }
00785 
00795 PSFont* 
00796 psFontListLookupByFontFamily(char *fontFamily)
00797 {
00798   PSListNode
00799     *node;
00800     
00801   PSFont
00802     *font;
00803     
00804   if(psFontList)
00805   {
00806     node = psListFirst(psFontList);
00807     while(node)
00808     {
00809       font = psListGetValue(psFontList, node);
00810       if(font->fontFamily && !strcasecmp(font->fontFamily, fontFamily))
00811         return font;
00812       node = psListNext(psFontList, node);
00813     }
00814   }
00815   
00816   return NULL;
00817 }
00818 
00828 PSFont* 
00829 psFontListLookupByXLFD(char *xlfd)
00830 {
00831   PSListNode
00832     *flnode,
00833     *xnnode;
00834     
00835   PSFont
00836     *font = NULL;
00837     
00838   PSXFont
00839     *f1 = 0,
00840     *f2 = 0;
00841     
00842   char
00843     *p;
00844     
00845   f1 = psXFontAlloc();
00846   if(!f1)
00847     goto Outtahere;
00848   psXFontSet(f1, xlfd);
00849   f2 = psXFontAlloc();
00850   if(!f2)
00851     goto Outtahere;
00852     
00853   if(psFontList)
00854   {
00855     flnode = psListFirst(psFontList);
00856     while(flnode)
00857     {
00858       font = psListGetValue(psFontList, flnode);
00859       if(font->xFontNames)
00860       {
00861         xnnode = psListFirst(font->xFontNames);
00862         while(xnnode)
00863         {
00864           p = psListGetValue(font->xFontNames, xnnode);
00865           psXFontSet(f2, p);
00866           if(psXFontMatch(f1, f2))
00867             goto Outtahere;
00868           xnnode = psListNext(font->xFontNames, xnnode);
00869         }
00870       }
00871       flnode = psListNext(psFontList, flnode);
00872     }
00873     font = NULL;
00874   }
00875   
00876 Outtahere:
00877   if(f1)
00878     psXFontFree(f1);
00879   if(f2)
00880     psXFontFree(f2);
00881   
00882   return font;
00883 }
00884 
00894 PSFont* 
00895 psFontListLookupByFontFileName(char *fontFileName)
00896 {
00897   PSListNode
00898     *node;
00899     
00900   PSFont
00901     *font;
00902     
00903   if(psFontList)
00904   {
00905     node = psListFirst(psFontList);
00906     while(node)
00907     {
00908       font = psListGetValue(psFontList, node);
00909       if(font->fontFileName && !strcasecmp(font->fontFileName, fontFileName))
00910         return font;
00911       node = psListNext(psFontList, node);
00912     }
00913   }
00914   
00915   return NULL;
00916 }
00917 
00918 
00919 static int
00920 LookupXLFD(char *XLFD, char *dir, char **fileName)
00921 {
00922   int
00923     retVal = 0,
00924     i,
00925     numFonts;
00926     
00927   char
00928     *p,
00929     *fname = NULL,
00930     line[1024];
00931     
00932   FILE
00933     *fp;
00934     
00935   fname = malloc(strlen(dir) + strlen(XFONTSDIR) + 2);
00936   if(fname)
00937   {
00938     strcpy(fname, dir);
00939     if(fname[strlen(fname) - 1] != '/')
00940       strcat(fname, "/");
00941     strcat(fname, XFONTSDIR);
00942     
00943     fp = fopen(fname, "rb");
00944     if(fp)
00945     {
00946       if(fgets(line, 1024, fp))
00947       {
00948         numFonts = atoi(line);
00949         for(i = 0; i < numFonts && fgets(line, 1024, fp); i++)
00950         {
00951           for(p = line + strlen(line) - 1; p >= line && isspace(*p); p--)
00952               *p = 0;
00953           for(p = line; *p && !isspace(*p); p++)
00954             ;
00955           for(;*p && isspace(*p); p++)
00956             ;
00957           if(*p && !strcmp(XLFD, p))
00958           {
00959             for(p = line; *p && !isspace(*p); p++)
00960               ;
00961             if(*p)
00962               *p = 0;
00963             *fileName = malloc(strlen(dir) + strlen(line) + 2);
00964             if(*fileName)
00965             {
00966               strcpy(*fileName, dir);
00967               if(*fileName[strlen(*fileName) - 1] != '/')
00968                 strcat(*fileName, "/");
00969               strcat(*fileName, line);
00970               retVal = 1;
00971             }
00972             break;
00973           }
00974         }
00975       }    
00976       fclose(fp);
00977     }
00978   }
00979   
00980   if(fname)
00981     free(fname);
00982   
00983   return retVal;
00984 }
00985 
00986 static int
00987 ScanXFontsDir(char *XLFD, char *dir, char **fileName)
00988 {
00989   char
00990     *p,
00991     *oldCurFontDir = curFontDir,
00992     **oldCurExt = curExt;
00993     
00994   struct dirent
00995     **namelist; 
00996     
00997   int
00998     retVal = 0,
00999     i,
01000     n;
01001     
01002   curFontDir = dir;
01003   
01004   /*
01005   **  First scan through and descend directories
01006   */
01007   n = scandir(dir, &namelist, SelectDir, alphasort);
01008   if(n > 0)
01009   {
01010     for(i = 0; i < n; i++)
01011     {
01012       if(strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, ".."))
01013       {
01014         p = malloc(strlen(dir) + strlen(namelist[i]->d_name) + 2);
01015         strcpy(p, dir);
01016         if(p[strlen(p) - 1] != '/')
01017           strcat(p, "/");
01018         strcat(p, namelist[i]->d_name);
01019         if(ScanXFontsDir(XLFD, p, fileName))
01020         {
01021           free(*namelist);
01022           free(p);
01023           retVal = 1;
01024           goto Outtahere;
01025         }
01026         free(p);
01027       }
01028       free(namelist[i]);
01029     }
01030     free(namelist);
01031   }
01032   
01033   /*
01034   **  Now scan the file
01035   */
01036   if(LookupXLFD(XLFD, dir, fileName))
01037     retVal = 1;
01038 
01039 Outtahere:    
01040   curFontDir = oldCurFontDir;
01041   curExt = oldCurExt;
01042   
01043   return retVal;
01044 }
01045 
01046 char *
01047 psGetXFontFileName(char* XLFD, char **fileName)
01048 {
01049   char
01050     *p,
01051     *q,
01052     *path;
01053     
01054   PSAFM
01055     *fm;
01056     
01057   pserrno = PSERR_NONE;
01058   
01059   path = strdup(psFontPath);
01060   if(path)
01061   {
01062     p = q = path;
01063     for(q = p; *q && *q != PS_PATH_SEPARATOR; q++)
01064       ;
01065     if(*q)
01066     {
01067       *q = 0;
01068       q++;
01069     }
01070     while(*p)
01071     {
01072       if(ScanXFontsDir(XLFD, p, fileName))
01073       {
01074         free(path);
01075         return *fileName;
01076       }
01077       p = q;
01078       for(q = p; *q && *q != PS_PATH_SEPARATOR; q++)
01079         ;
01080       if(*q)
01081       {
01082         *q = 0;
01083         q++;
01084       }
01085     }
01086     free(path);
01087   }
01088   
01089   return NULL;
01090 }
01091 
01101 double
01102 psFontGetTextWidth(PSFont* font, char *text)
01103 {
01104   PSStream
01105     *ttf,
01106     *afm;
01107     
01108   FILE
01109     *ttffp,
01110     *afmfp;
01111     
01112   /*
01113   **  If the font is a true type font and we don't have a font metric
01114   **  yet, create and parse an AFM file.  In the future we should be using
01115   **  the information directly from the true type font file.
01116   */
01117   if(font->fontType == PS_FONTTYPE_TRUETYPE && !font->fontMetric)
01118   {
01119     font->fontMetricFileName = strdup(font->fontFileName);
01120     if(font->fontMetricFileName)
01121     {
01122       *strrchr(font->fontMetricFileName, '.') = 0;
01123       strcat(font->fontMetricFileName, PSAFM_FILEEXT);
01124       afmfp = fopen(font->fontMetricFileName, "wb");
01125       if(afmfp)
01126       {
01127         afm = psStreamAlloc(afmfp, &psStandardStreamFuncs);
01128         if(afm)
01129         {
01130           ttffp = fopen(font->fontFileName, "rb");
01131           if(ttffp)
01132           {
01133             ttf = psStreamAlloc(ttffp, &psStandardStreamFuncs);
01134             if(ttf)
01135             {
01136               if(psTTFToT42PFA(ttf, NULL, afm))
01137               {
01138                 fclose(ttffp);
01139                 ttffp = NULL;
01140                 fclose(afmfp);
01141                 afmfp = NULL;
01142                 psStreamFree(ttf);
01143                 ttf = NULL;
01144                 psStreamFree(afm);
01145                 afm = NULL;
01146                 font->fontMetric = psAFMLoad(font->fontMetricFileName);
01147               }
01148               if(ttf)
01149                 psStreamFree(ttf);
01150             }
01151             if(ttffp)
01152               fclose(ttffp);
01153           }
01154           if(afm)
01155             psStreamFree(afm);
01156         }
01157         if(afmfp)
01158           fclose(afmfp);
01159       }
01160     }
01161   }
01162   
01163   if(font->fontMetric)
01164     return psAFMGetTextWidth(font->fontMetric, text);
01165     
01166   return 0.0;
01167 }

Generated at Mon Dec 11 22:46:27 2000 for Postscript Utility Library by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000