Back to index

tetex-bin  3.0
FoFiType1.cc
Go to the documentation of this file.
00001 //========================================================================
00002 //
00003 // FoFiType1.cc
00004 //
00005 // Copyright 1999-2003 Glyph & Cog, LLC
00006 //
00007 //========================================================================
00008 
00009 #include <aconf.h>
00010 
00011 #ifdef USE_GCC_PRAGMAS
00012 #pragma implementation
00013 #endif
00014 
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include "gmem.h"
00018 #include "FoFiEncodings.h"
00019 #include "FoFiType1.h"
00020 
00021 //------------------------------------------------------------------------
00022 // FoFiType1
00023 //------------------------------------------------------------------------
00024 
00025 FoFiType1 *FoFiType1::make(char *fileA, int lenA) {
00026   return new FoFiType1(fileA, lenA, gFalse);
00027 }
00028 
00029 FoFiType1 *FoFiType1::load(char *fileName) {
00030   char *fileA;
00031   int lenA;
00032 
00033   if (!(fileA = FoFiBase::readFile(fileName, &lenA))) {
00034     return NULL;
00035   }
00036   return new FoFiType1(fileA, lenA, gTrue);
00037 }
00038 
00039 FoFiType1::FoFiType1(char *fileA, int lenA, GBool freeFileDataA):
00040   FoFiBase(fileA, lenA, freeFileDataA)
00041 {
00042   name = NULL;
00043   encoding = NULL;
00044   parsed = gFalse;
00045 }
00046 
00047 FoFiType1::~FoFiType1() {
00048   int i;
00049 
00050   if (name) {
00051     gfree(name);
00052   }
00053   if (encoding && encoding != fofiType1StandardEncoding) {
00054     for (i = 0; i < 256; ++i) {
00055       gfree(encoding[i]);
00056     }
00057     gfree(encoding);
00058   }
00059 }
00060 
00061 char *FoFiType1::getName() {
00062   if (!parsed) {
00063     parse();
00064   }
00065   return name;
00066 }
00067 
00068 char **FoFiType1::getEncoding() {
00069   if (!parsed) {
00070     parse();
00071   }
00072   return encoding;
00073 }
00074 
00075 void FoFiType1::writeEncoded(char **newEncoding,
00076                           FoFiOutputFunc outputFunc, void *outputStream) {
00077   char buf[512];
00078   char *line;
00079   int i;
00080 
00081   // copy everything up to the encoding
00082   for (line = (char *)file;
00083        line && strncmp(line, "/Encoding", 9);
00084        line = getNextLine(line)) ;
00085   if (!line) {
00086     // no encoding - just copy the whole font file
00087     (*outputFunc)(outputStream, (char *)file, len);
00088     return;
00089   }
00090   (*outputFunc)(outputStream, (char *)file, line - (char *)file);
00091 
00092   // write the new encoding
00093   (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
00094   (*outputFunc)(outputStream,
00095               "0 1 255 {1 index exch /.notdef put} for\n", 40);
00096   for (i = 0; i < 256; ++i) {
00097     if (newEncoding[i]) {
00098       sprintf(buf, "dup %d /%s put\n", i, newEncoding[i]);
00099       (*outputFunc)(outputStream, buf, strlen(buf));
00100     }
00101   }
00102   (*outputFunc)(outputStream, "readonly def\n", 13);
00103   
00104   // copy everything after the encoding
00105   if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
00106     line = getNextLine(line);
00107   } else {
00108     for (line = getNextLine(line);
00109         line && strncmp(line, "readonly def", 12);
00110         line = getNextLine(line)) ;
00111   }
00112   if (line) {
00113     (*outputFunc)(outputStream, line, ((char *)file + len) - line);
00114   }
00115 }
00116 
00117 char *FoFiType1::getNextLine(char *line) {
00118   while (line < (char *)file + len && *line != '\x0a' && *line != '\x0d') {
00119     ++line;
00120   }
00121   if (line < (char *)file + len && *line == '\x0d') {
00122     ++line;
00123   }
00124   if (line < (char *)file + len && *line == '\x0a') {
00125     ++line;
00126   }
00127   if (line >= (char *)file + len) {
00128     return NULL;
00129   }
00130   return line;
00131 }
00132 
00133 void FoFiType1::parse() {
00134   char *line, *line1, *p, *p2;
00135   char buf[256];
00136   char c;
00137   int n, code, i, j;
00138 
00139   for (i = 1, line = (char *)file;
00140        i <= 100 && line && (!name || !encoding);
00141        ++i) {
00142 
00143     // get font name
00144     if (!name && !strncmp(line, "/FontName", 9)) {
00145       strncpy(buf, line, 255);
00146       buf[255] = '\0';
00147       if ((p = strchr(buf+9, '/')) &&
00148          (p = strtok(p+1, " \t\n\r"))) {
00149        name = copyString(p);
00150       }
00151       line = getNextLine(line);
00152 
00153     // get encoding
00154     } else if (!encoding &&
00155               !strncmp(line, "/Encoding StandardEncoding def", 30)) {
00156       encoding = fofiType1StandardEncoding;
00157     } else if (!encoding &&
00158               !strncmp(line, "/Encoding 256 array", 19)) {
00159       encoding = (char **)gmalloc(256 * sizeof(char *));
00160       for (j = 0; j < 256; ++j) {
00161        encoding[j] = NULL;
00162       }
00163       for (j = 0, line = getNextLine(line);
00164           j < 300 && line && (line1 = getNextLine(line));
00165           ++j, line = line1) {
00166        if ((n = line1 - line) > 255) {
00167          n = 255;
00168        }
00169        if (n < 0) n = 0;
00170        strncpy(buf, line, n);
00171        buf[n] = '\0';
00172        for (p = buf; *p == ' ' || *p == '\t'; ++p) ;
00173        if (!strncmp(p, "dup", 3)) {
00174          for (p += 3; *p == ' ' || *p == '\t'; ++p) ;
00175          for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ;
00176          if (*p2) {
00177            c = *p2;
00178            *p2 = '\0';
00179            if ((code = atoi(p)) < 256) {
00180              *p2 = c;
00181              for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
00182              if (*p == '/') {
00183               ++p;
00184               for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ;
00185               *p2 = '\0';
00186               encoding[code] = copyString(p);
00187              }
00188            }
00189          }
00190        } else {
00191          if (strtok(buf, " \t") &&
00192              (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) {
00193            break;
00194          }
00195        }
00196        line = line1;
00197       }
00198       //~ check for getinterval/putinterval junk
00199 
00200     } else {
00201       line = getNextLine(line);
00202     }
00203 
00204     ++i;
00205   }
00206 
00207   parsed = gTrue;
00208 }