Ignore:
Timestamp:
Jun 30, 2008, 10:13:07 AM (13 years ago)
Author:
Eugene Romanenko
Message:

PDF plugin: poppler library updated to version 0.8.3

Location:
trunk/poppler/mypoppler/fofi
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/poppler/mypoppler/fofi/FoFiBase.cc

    r2 r250  
    1515#include <stdio.h>
    1616#include "goo/gmem.h"
     17#include "poppler/Error.h"
    1718#include "FoFiBase.h"
    1819
     
    3940
    4041  if (!(f = fopen(fileName, "rb"))) {
     42    error(-1, "Cannot open '%s'", fileName);
    4143    return NULL;
    4244  }
    43   fseek(f, 0, SEEK_END);
     45  if (fseek(f, 0, SEEK_END) != 0) {
     46    error(-1, "Cannot seek to end of '%s'", fileName);
     47    fclose(f);
     48    return NULL;
     49  }
    4450  n = (int)ftell(f);
    45   fseek(f, 0, SEEK_SET);
     51  if (fseek(f, 0, SEEK_SET) != 0) {
     52    error(-1, "Cannot seek to start of '%s'", fileName);
     53    fclose(f);
     54    return NULL;
     55  }
    4656  buf = (char *)gmalloc(n);
    4757  if ((int)fread(buf, 1, n, f) != n) {
  • trunk/poppler/mypoppler/fofi/FoFiTrueType.cc

    r2 r250  
    1919#include "goo/GooString.h"
    2020#include "goo/GooHash.h"
     21#include "FoFiType1C.h"
    2122#include "FoFiTrueType.h"
    2223
     
    109110#define glyfTag 0x676c7966
    110111#define headTag 0x68656164
     112#define hheaTag 0x68686561
     113#define hmtxTag 0x686d7478
    111114#define locaTag 0x6c6f6361
    112115#define nameTag 0x6e616d65
     116#define os2Tag  0x4f532f32
    113117#define postTag 0x706f7374
     118#define vrt2Tag 0x76727432
     119#define vertTag 0x76657274
    114120
    115121static int cmpTrueTypeLocaOffset(const void *p1, const void *p2) {
     
    279285  parsedOk = gFalse;
    280286  faceIndex = faceIndexA;
     287  gsubFeatureTable = 0;
     288  gsubLookupList = 0;
    281289
    282290  parse();
     
    314322}
    315323
    316 Gushort FoFiTrueType::mapCodeToGID(int i, int c) {
     324Gushort FoFiTrueType::mapCodeToGID(int i, Guint c) {
    317325  Gushort gid;
    318   int segCnt, segEnd, segStart, segDelta, segOffset;
    319   int cmapFirst, cmapLen;
     326  Guint segCnt, segEnd, segStart, segDelta, segOffset;
     327  Guint cmapFirst, cmapLen;
    320328  int pos, a, b, m;
    321329  GBool ok;
     
    328336  switch (cmaps[i].fmt) {
    329337  case 0:
    330     if (c < 0 || c >= cmaps[i].len - 6) {
     338    if (c >= cmaps[i].len - 6) {
    331339      return 0;
    332340    }
     
    377385    gid = getU16BE(pos + 10 + 2 * (c - cmapFirst), &ok);
    378386    break;
     387  case 12:
     388    segCnt = getU32BE(pos + 12, &ok);
     389    a = -1;
     390    b = segCnt - 1;
     391    segEnd = getU32BE(pos + 16 + 12*b+4, &ok);
     392    if (c > segEnd) {
     393      return 0;
     394    }
     395    // invariant: seg[a].end < code <= seg[b].end
     396    while (b - a > 1 && ok) {
     397      m = (a + b) / 2;
     398      segEnd = getU32BE(pos + 16 + 12*m+4, &ok);
     399      if (segEnd < c) {
     400        a = m;
     401      } else {
     402        b = m;
     403      }
     404    }
     405    segStart = getU32BE(pos + 16 + 12*b, &ok);
     406    segDelta = getU32BE(pos + 16 + 12*b+8, &ok);
     407    if (c < segStart) {
     408      return 0;
     409    }
     410    gid = segDelta + (c-segStart);
     411    break;
    379412  default:
    380413    return 0;
     
    391424  }
    392425  return nameToGID->lookupInt(name);
     426}
     427
     428Gushort *FoFiTrueType::getCIDToGIDMap(int *nCIDs) {
     429  FoFiType1C *ff;
     430  Gushort *map;
     431  int i;
     432
     433  *nCIDs = 0;
     434  if (!openTypeCFF) {
     435    return NULL;
     436  }
     437  i = seekTable("CFF ");
     438  if (!checkRegion(tables[i].offset, tables[i].len)) {
     439    return NULL;
     440  }
     441  if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
     442                              tables[i].len))) {
     443    return NULL;
     444  }
     445  map = ff->getCIDToGIDMap(nCIDs);
     446  delete ff;
     447  return map;
    393448}
    394449
     
    421476                                   FoFiOutputFunc outputFunc,
    422477                                   void *outputStream) {
    423   char buf[512];
     478  GooString *buf;
    424479  GBool ok;
     480
     481  if (openTypeCFF) {
     482    return;
     483  }
    425484
    426485  // write the header
    427486  ok = gTrue;
    428   sprintf(buf, "%%!PS-TrueTypeFont-%g\n", (double)getS32BE(0, &ok) / 65536.0);
    429   (*outputFunc)(outputStream, buf, strlen(buf));
     487  buf = GooString::format("%!PS-TrueTypeFont-{0:2g}\n",
     488                        (double)getS32BE(0, &ok) / 65536.0);
     489  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     490  delete buf;
    430491
    431492  // begin the font dictionary
     
    436497  (*outputFunc)(outputStream, "/FontType 42 def\n", 17);
    437498  (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
    438   sprintf(buf, "/FontBBox [%d %d %d %d] def\n",
    439           bbox[0], bbox[1], bbox[2], bbox[3]);
    440   (*outputFunc)(outputStream, buf, strlen(buf));
     499  buf = GooString::format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n",
     500                        bbox[0], bbox[1], bbox[2], bbox[3]);
     501  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     502  delete buf;
    441503  (*outputFunc)(outputStream, "/PaintType 0 def\n", 17);
    442504
     
    448510  // end the dictionary and define the font
    449511  (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
     512}
     513
     514void FoFiTrueType::convertToType1(char *psName, char **newEncoding,
     515                                  GBool ascii, FoFiOutputFunc outputFunc,
     516                                  void *outputStream) {
     517  FoFiType1C *ff;
     518  int i;
     519
     520  if (!openTypeCFF) {
     521    return;
     522  }
     523  i = seekTable("CFF ");
     524  if (!checkRegion(tables[i].offset, tables[i].len)) {
     525    return;
     526  }
     527  if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
     528                              tables[i].len))) {
     529    return;
     530  }
     531  ff->convertToType1(psName, newEncoding, ascii, outputFunc, outputStream);
     532  delete ff;
    450533}
    451534
     
    455538                                     FoFiOutputFunc outputFunc,
    456539                                     void *outputStream) {
    457   char buf[512];
     540  GooString *buf;
    458541  Gushort cid;
    459542  GBool ok;
    460543  int i, j, k;
    461544
     545  if (openTypeCFF) {
     546    return;
     547  }
     548
    462549  // write the header
    463550  ok = gTrue;
    464   sprintf(buf, "%%!PS-TrueTypeFont-%g\n", (double)getS32BE(0, &ok) / 65536.0);
    465   (*outputFunc)(outputStream, buf, strlen(buf));
     551  buf = GooString::format("%!PS-TrueTypeFont-{0:2g}\n",
     552                        (double)getS32BE(0, &ok) / 65536.0);
     553  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     554  delete buf;
    466555
    467556  // begin the font dictionary
     
    479568  (*outputFunc)(outputStream, "/GDBytes 2 def\n", 15);
    480569  if (cidMap) {
    481     sprintf(buf, "/CIDCount %d def\n", nCIDs);
    482     (*outputFunc)(outputStream, buf, strlen(buf));
     570    buf = GooString::format("/CIDCount {0:d} def\n", nCIDs);
     571    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     572    delete buf;
    483573    if (nCIDs > 32767) {
    484574      (*outputFunc)(outputStream, "/CIDMap [", 9);
     
    489579          for (k = 0; k < 16 && i+j+k < nCIDs; ++k) {
    490580            cid = cidMap[i+j+k];
    491             sprintf(buf, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff);
    492             (*outputFunc)(outputStream, buf, strlen(buf));
     581            buf = GooString::format("{0:02x}{1:02x}",
     582                                  (cid >> 8) & 0xff, cid & 0xff);
     583            (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     584            delete buf;
    493585          }
    494586          (*outputFunc)(outputStream, "\n", 1);
     
    504596        for (j = 0; j < 16 && i+j < nCIDs; ++j) {
    505597          cid = cidMap[i+j];
    506           sprintf(buf, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff);
    507           (*outputFunc)(outputStream, buf, strlen(buf));
     598          buf = GooString::format("{0:02x}{1:02x}",
     599                                (cid >> 8) & 0xff, cid & 0xff);
     600          (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     601          delete buf;
    508602        }
    509603        (*outputFunc)(outputStream, "\n", 1);
     
    513607  } else {
    514608    // direct mapping - just fill the string(s) with s[i]=i
    515     sprintf(buf, "/CIDCount %d def\n", nGlyphs);
    516     (*outputFunc)(outputStream, buf, strlen(buf));
     609    buf = GooString::format("/CIDCount {0:d} def\n", nGlyphs);
     610    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     611    delete buf;
    517612    if (nGlyphs > 32767) {
    518613      (*outputFunc)(outputStream, "/CIDMap [\n", 10);
    519614      for (i = 0; i < nGlyphs; i += 32767) {
    520615        j = nGlyphs - i < 32767 ? nGlyphs - i : 32767;
    521         sprintf(buf, "  %d string 0 1 %d {\n", 2 * j, j - 1);
    522         (*outputFunc)(outputStream, buf, strlen(buf));
    523         sprintf(buf, "    2 copy dup 2 mul exch %d add -8 bitshift put\n", i);
    524         (*outputFunc)(outputStream, buf, strlen(buf));
    525         sprintf(buf, "    1 index exch dup 2 mul 1 add exch %d add"
    526                 " 255 and put\n", i);
    527         (*outputFunc)(outputStream, buf, strlen(buf));
     616        buf = GooString::format("  {0:d} string 0 1 {1:d} {{\n", 2 * j, j - 1);
     617        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     618        delete buf;
     619        buf = GooString::format("    2 copy dup 2 mul exch {0:d} add -8 bitshift put\n",
     620                              i);
     621        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     622        delete buf;
     623        buf = GooString::format("    1 index exch dup 2 mul 1 add exch {0:d} add"
     624                              " 255 and put\n", i);
     625        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     626        delete buf;
    528627        (*outputFunc)(outputStream, "  } for\n", 8);
    529628      }
    530629      (*outputFunc)(outputStream, "] def\n", 6);
    531630    } else {
    532       sprintf(buf, "/CIDMap %d string\n", 2 * nGlyphs);
    533       (*outputFunc)(outputStream, buf, strlen(buf));
    534       sprintf(buf, "  0 1 %d {\n", nGlyphs - 1);
    535       (*outputFunc)(outputStream, buf, strlen(buf));
     631      buf = GooString::format("/CIDMap {0:d} string\n", 2 * nGlyphs);
     632      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     633      delete buf;
     634      buf = GooString::format("  0 1 {0:d} {{\n", nGlyphs - 1);
     635      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     636      delete buf;
    536637      (*outputFunc)(outputStream,
    537638                    "    2 copy dup 2 mul exch -8 bitshift put\n", 42);
     
    543644  }
    544645  (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
    545   sprintf(buf, "/FontBBox [%d %d %d %d] def\n",
    546           bbox[0], bbox[1], bbox[2], bbox[3]);
    547   (*outputFunc)(outputStream, buf, strlen(buf));
     646  buf = GooString::format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n",
     647                        bbox[0], bbox[1], bbox[2], bbox[3]);
     648  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     649  delete buf;
    548650  (*outputFunc)(outputStream, "/PaintType 0 def\n", 17);
    549651  (*outputFunc)(outputStream, "/Encoding [] readonly def\n", 26);
     
    561663}
    562664
     665void FoFiTrueType::convertToCIDType0(char *psName,
     666                                     FoFiOutputFunc outputFunc,
     667                                     void *outputStream) {
     668  FoFiType1C *ff;
     669  int i;
     670
     671  if (!openTypeCFF) {
     672    return;
     673  }
     674  i = seekTable("CFF ");
     675  if (!checkRegion(tables[i].offset, tables[i].len)) {
     676    return;
     677  }
     678  if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
     679                              tables[i].len))) {
     680    return;
     681  }
     682  ff->convertToCIDType0(psName, outputFunc, outputStream);
     683  delete ff;
     684}
     685
    563686void FoFiTrueType::convertToType0(char *psName, Gushort *cidMap, int nCIDs,
    564687                                  GBool needVerticalMetrics,
    565688                                  FoFiOutputFunc outputFunc,
    566689                                  void *outputStream) {
    567   char buf[512];
     690  GooString *buf;
    568691  GooString *sfntsName;
    569692  int n, i, j;
     693
     694  if (openTypeCFF) {
     695    return;
     696  }
    570697
    571698  // write the Type 42 sfnts array
     
    580707    (*outputFunc)(outputStream, "/FontName /", 11);
    581708    (*outputFunc)(outputStream, psName, strlen(psName));
    582     sprintf(buf, "_%02x def\n", i >> 8);
    583     (*outputFunc)(outputStream, buf, strlen(buf));
     709    buf = GooString::format("_{0:02x} def\n", i >> 8);
     710    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     711    delete buf;
    584712    (*outputFunc)(outputStream, "/FontType 42 def\n", 17);
    585713    (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
    586     sprintf(buf, "/FontBBox [%d %d %d %d] def\n",
    587             bbox[0], bbox[1], bbox[2], bbox[3]);
    588     (*outputFunc)(outputStream, buf, strlen(buf));
     714    buf = GooString::format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n",
     715                          bbox[0], bbox[1], bbox[2], bbox[3]);
     716    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     717    delete buf;
    589718    (*outputFunc)(outputStream, "/PaintType 0 def\n", 17);
    590719    (*outputFunc)(outputStream, "/sfnts ", 7);
     
    593722    (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
    594723    for (j = 0; j < 256 && i+j < n; ++j) {
    595       sprintf(buf, "dup %d /c%02x put\n", j, j);
    596       (*outputFunc)(outputStream, buf, strlen(buf));
     724      buf = GooString::format("dup {0:d} /c{1:02x} put\n", j, j);
     725      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     726      delete buf;
    597727    }
    598728    (*outputFunc)(outputStream, "readonly def\n", 13);
     
    600730    (*outputFunc)(outputStream, "/.notdef 0 def\n", 15);
    601731    for (j = 0; j < 256 && i+j < n; ++j) {
    602       sprintf(buf, "/c%02x %d def\n", j, cidMap ? cidMap[i+j] : i+j);
    603       (*outputFunc)(outputStream, buf, strlen(buf));
     732      buf = GooString::format("/c{0:02x} {1:d} def\n",
     733                            j, cidMap ? cidMap[i+j] : i+j);
     734      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     735      delete buf;
    604736    }
    605737    (*outputFunc)(outputStream, "end readonly def\n", 17);
     
    618750  (*outputFunc)(outputStream, "/Encoding [\n", 12);
    619751  for (i = 0; i < n; i += 256) {
    620     sprintf(buf, "%d\n", i >> 8);
    621     (*outputFunc)(outputStream, buf, strlen(buf));
     752    buf = GooString::format("{0:d}\n", i >> 8);
     753    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     754    delete buf;
    622755  }
    623756  (*outputFunc)(outputStream, "] def\n", 6);
     
    626759    (*outputFunc)(outputStream, "/", 1);
    627760    (*outputFunc)(outputStream, psName, strlen(psName));
    628     sprintf(buf, "_%02x findfont\n", i >> 8);
    629     (*outputFunc)(outputStream, buf, strlen(buf));
     761    buf = GooString::format("_{0:02x} findfont\n", i >> 8);
     762    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     763    delete buf;
    630764  }
    631765  (*outputFunc)(outputStream, "] def\n", 6);
    632766  (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
     767}
     768
     769void FoFiTrueType::convertToType0(char *psName,
     770                                  FoFiOutputFunc outputFunc,
     771                                  void *outputStream) {
     772  FoFiType1C *ff;
     773  int i;
     774
     775  if (!openTypeCFF) {
     776    return;
     777  }
     778  i = seekTable("CFF ");
     779  if (!checkRegion(tables[i].offset, tables[i].len)) {
     780    return;
     781  }
     782  if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
     783                              tables[i].len))) {
     784    return;
     785  }
     786  ff->convertToType0(psName, outputFunc, outputStream);
     787  delete ff;
    633788}
    634789
     
    674829    0, 0, 0, 0                  // max Type 1 memory
    675830  };
    676   GBool missingCmap, missingName, missingPost, unsortedLoca, badCmapLen;
     831  static char os2Tab[86] = {
     832    0, 1,                       // version
     833    0, 1,                       // xAvgCharWidth
     834    0, 0,                       // usWeightClass
     835    0, 0,                       // usWidthClass
     836    0, 0,                       // fsType
     837    0, 0,                       // ySubscriptXSize
     838    0, 0,                       // ySubscriptYSize
     839    0, 0,                       // ySubscriptXOffset
     840    0, 0,                       // ySubscriptYOffset
     841    0, 0,                       // ySuperscriptXSize
     842    0, 0,                       // ySuperscriptYSize
     843    0, 0,                       // ySuperscriptXOffset
     844    0, 0,                       // ySuperscriptYOffset
     845    0, 0,                       // yStrikeoutSize
     846    0, 0,                       // yStrikeoutPosition
     847    0, 0,                       // sFamilyClass
     848    0, 0, 0, 0, 0,              // panose
     849    0, 0, 0, 0, 0,
     850    0, 0, 0, 0,                 // ulUnicodeRange1
     851    0, 0, 0, 0,                 // ulUnicodeRange2
     852    0, 0, 0, 0,                 // ulUnicodeRange3
     853    0, 0, 0, 0,                 // ulUnicodeRange4
     854    0, 0, 0, 0,                 // achVendID
     855    0, 0,                       // fsSelection
     856    0, 0,                       // usFirstCharIndex
     857    0, 0,                       // usLastCharIndex
     858    0, 0,                       // sTypoAscender
     859    0, 0,                       // sTypoDescender
     860    0, 0,                       // sTypoLineGap
     861    0, 0,                       // usWinAscent
     862    0, 0,                       // usWinDescent
     863    0, 0, 0, 0,                 // ulCodePageRange1
     864    0, 0, 0, 0                  // ulCodePageRange2
     865  };
     866  GBool missingCmap, missingName, missingPost, missingOS2;
     867  GBool unsortedLoca, badCmapLen, abbrevHMTX;
    677868  int nZeroLengthTables;
     869  int nHMetrics, advWidth, lsb;
    678870  TrueTypeLoca *locaTable;
    679871  TrueTypeTable *newTables;
    680   char *newNameTab, *newCmapTab;
     872  char *newNameTab, *newCmapTab, *newHHEATab, *newHMTXTab;
    681873  int nNewTables, cmapIdx, cmapLen, glyfLen, newNameLen, newCmapLen, next;
     874  int newHHEALen, newHMTXLen;
    682875  Guint locaChecksum, glyfChecksum, fileChecksum;
    683876  char *tableDir;
     
    687880  int pos, i, j, k, n;
    688881
     882  if (openTypeCFF) {
     883    return;
     884  }
     885
    689886  // check for missing tables
     887  // (Note: if the OS/2 table is missing, the Microsoft PCL5 driver
     888  // will embed a PCL TrueType font with the pitch field set to zero,
     889  // which apparently causes divide-by-zero errors.  As far as I can
     890  // tell, the only important field in the OS/2 table is
     891  // xAvgCharWidth.)
    690892  missingCmap = (cmapIdx = seekTable("cmap")) < 0;
    691893  missingName = seekTable("name") < 0;
    692894  missingPost = seekTable("post") < 0;
     895  missingOS2 = seekTable("OS/2") < 0;
    693896
    694897  // read the loca table, check to see if it's sorted
     
    707910      unsortedLoca = gTrue;
    708911    }
     912    // glyph descriptions must be at least 12 bytes long (nContours,
     913    // xMin, yMin, xMax, yMax, instructionLength - two bytes each);
     914    // invalid glyph descriptions (even if they're never used) make
     915    // Windows choke, so we work around that problem here (ideally,
     916    // this would parse the glyph descriptions in the glyf table and
     917    // remove any that were invalid, but this quick test is a decent
     918    // start)
     919    if (i > 0 &&
     920        locaTable[i].origOffset - locaTable[i-1].origOffset > 0 &&
     921        locaTable[i].origOffset - locaTable[i-1].origOffset < 12) {
     922      locaTable[i-1].origOffset = locaTable[i].origOffset;
     923      unsortedLoca = gTrue;
     924    }
    709925    locaTable[i].idx = i;
    710926  }
     
    722938  cmapLen = 0; // make gcc happy
    723939  if (!missingCmap) {
    724     cmapLen = cmaps[0].offset + cmaps[0].len;
    725     for (i = 1; i < nCmaps; ++i) {
    726       if (cmaps[i].offset + cmaps[i].len > cmapLen) {
    727         cmapLen = cmaps[i].offset + cmaps[i].len;
     940    if (nCmaps > 0) {
     941      cmapLen = cmaps[0].offset + cmaps[0].len;
     942      for (i = 1; i < nCmaps; ++i) {
     943        if (cmaps[i].offset + cmaps[i].len > cmapLen) {
     944          cmapLen = cmaps[i].offset + cmaps[i].len;
     945        }
    728946      }
    729947    }
     
    734952  }
    735953
     954  // check for an abbreviated hmtx table (this is completely legal,
     955  // but confuses the Microsoft PCL5 printer driver, which generates
     956  // embedded fonts with the pitch field set to zero)
     957  i = seekTable("hhea");
     958  nHMetrics = getU16BE(tables[i].offset + 34, &ok);
     959  abbrevHMTX = nHMetrics < nGlyphs;
     960
    736961  // if nothing is broken, just write the TTF file as is
    737   if (!missingCmap && !missingName && !missingPost && !unsortedLoca &&
    738       !badCmapLen && nZeroLengthTables == 0 && !name && !codeToGID) {
     962  if (!missingCmap && !missingName && !missingPost && !missingOS2 &&
     963      !unsortedLoca && !badCmapLen && !abbrevHMTX && nZeroLengthTables == 0 &&
     964      !name && !codeToGID) {
    739965    (*outputFunc)(outputStream, (char *)file, len);
    740966    goto done1;
     
    8941120  }
    8951121
     1122  // generate the new hmtx table and the updated hhea table
     1123  if (abbrevHMTX) {
     1124    i = seekTable("hhea");
     1125    pos = tables[i].offset;
     1126    newHHEALen = 36;
     1127    newHHEATab = (char *)gmalloc(newHHEALen);
     1128    for (i = 0; i < newHHEALen; ++i) {
     1129      newHHEATab[i] = getU8(pos++, &ok);
     1130    }
     1131    newHHEATab[34] = nGlyphs >> 8;
     1132    newHHEATab[35] = nGlyphs & 0xff;
     1133    i = seekTable("hmtx");
     1134    pos = tables[i].offset;
     1135    newHMTXLen = 4 * nGlyphs;
     1136    newHMTXTab = (char *)gmalloc(newHMTXLen);
     1137    advWidth = 0;
     1138    for (i = 0; i < nHMetrics; ++i) {
     1139      advWidth = getU16BE(pos, &ok);
     1140      lsb = getU16BE(pos + 2, &ok);
     1141      pos += 4;
     1142      newHMTXTab[4*i    ] = advWidth >> 8;
     1143      newHMTXTab[4*i + 1] = advWidth & 0xff;
     1144      newHMTXTab[4*i + 2] = lsb >> 8;
     1145      newHMTXTab[4*i + 3] = lsb & 0xff;
     1146    }
     1147    for (; i < nGlyphs; ++i) {
     1148      lsb = getU16BE(pos, &ok);
     1149      pos += 2;
     1150      newHMTXTab[4*i    ] = advWidth >> 8;
     1151      newHMTXTab[4*i + 1] = advWidth & 0xff;
     1152      newHMTXTab[4*i + 2] = lsb >> 8;
     1153      newHMTXTab[4*i + 3] = lsb & 0xff;
     1154    }
     1155  } else {
     1156    newHHEATab = newHMTXTab = NULL;
     1157    newHHEALen = newHMTXLen = 0; // make gcc happy
     1158  }
     1159
    8961160  // construct the new table directory:
    8971161  // - keep all original tables with non-zero length
     
    9031167  nNewTables = nTables - nZeroLengthTables +
    9041168               (missingCmap ? 1 : 0) + (missingName ? 1 : 0) +
    905                (missingPost ? 1 : 0);
     1169               (missingPost ? 1 : 0) + (missingOS2 ? 1 : 0);
    9061170  newTables = (TrueTypeTable *)gmallocn(nNewTables, sizeof(TrueTypeTable));
    9071171  j = 0;
     
    9341198        newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab,
    9351199                                                     newNameLen);
     1200      } else if (newTables[j].tag == hheaTag && abbrevHMTX) {
     1201        newTables[j].len = newHHEALen;
     1202        newTables[j].checksum = computeTableChecksum((Guchar *)newHHEATab,
     1203                                                     newHHEALen);
     1204      } else if (newTables[j].tag == hmtxTag && abbrevHMTX) {
     1205        newTables[j].len = newHMTXLen;
     1206        newTables[j].checksum = computeTableChecksum((Guchar *)newHMTXTab,
     1207                                                     newHMTXLen);
    9361208      }
    9371209      ++j;
     
    9691241                                                 sizeof(postTab));
    9701242    newTables[j].len = sizeof(postTab);
     1243    ++j;
     1244  }
     1245  if (missingOS2) {
     1246    newTables[j].tag = os2Tag;
     1247    newTables[j].checksum = computeTableChecksum((Guchar *)os2Tab,
     1248                                                 sizeof(os2Tab));
     1249    newTables[j].len = sizeof(os2Tab);
    9711250    ++j;
    9721251  }
     
    10571336    } else if (newTables[i].tag == postTag && missingPost) {
    10581337      (*outputFunc)(outputStream, postTab, newTables[i].len);
     1338    } else if (newTables[i].tag == os2Tag && missingOS2) {
     1339      (*outputFunc)(outputStream, os2Tab, newTables[i].len);
     1340    } else if (newTables[i].tag == hheaTag && abbrevHMTX) {
     1341      (*outputFunc)(outputStream, newHHEATab, newTables[i].len);
     1342    } else if (newTables[i].tag == hmtxTag && abbrevHMTX) {
     1343      (*outputFunc)(outputStream, newHMTXTab, newTables[i].len);
    10591344    } else if (newTables[i].tag == locaTag && unsortedLoca) {
    10601345      for (j = 0; j <= nGlyphs; ++j) {
     
    11041389  }
    11051390
     1391  gfree(newHMTXTab);
     1392  gfree(newHHEATab);
    11061393  gfree(newCmapTab);
    11071394  gfree(newNameTab);
     
    11161403                               void *outputStream) {
    11171404  char *name;
    1118   char buf[64];
     1405  GooString *buf;
    11191406  int i;
    11201407
     
    11251412        name = ".notdef";
    11261413      }
    1127       sprintf(buf, "dup %d /", i);
    1128       (*outputFunc)(outputStream, buf, strlen(buf));
     1414      buf = GooString::format("dup {0:d} /", i);
     1415      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1416      delete buf;
    11291417      (*outputFunc)(outputStream, name, strlen(name));
    11301418      (*outputFunc)(outputStream, " put\n", 5);
     
    11321420  } else {
    11331421    for (i = 0; i < 256; ++i) {
    1134       sprintf(buf, "dup %d /c%02x put\n", i, i);
    1135       (*outputFunc)(outputStream, buf, strlen(buf));
     1422      buf = GooString::format("dup {0:d} /c{1:02x} put\n", i, i);
     1423      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1424      delete buf;
    11361425    }
    11371426  }
     
    11441433                                  void *outputStream) {
    11451434  char *name;
    1146   char buf[64], buf2[16];
     1435  GooString *buf;
     1436  char buf2[16];
    11471437  int i, k;
    11481438
     
    11791469        (*outputFunc)(outputStream, "/", 1);
    11801470        (*outputFunc)(outputStream, name, strlen(name));
    1181         sprintf(buf, " %d def\n", k);
    1182         (*outputFunc)(outputStream, buf, strlen(buf));
     1471        buf = GooString::format(" {0:d} def\n", k);
     1472        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1473        delete buf;
    11831474      }
    11841475    }
     
    14831774                              FoFiOutputFunc outputFunc,
    14841775                              void *outputStream) {
    1485   char buf[64];
     1776  GooString *buf;
    14861777  int pad, i, j;
    14871778
     
    14891780  for (i = 0; i < length; i += 32) {
    14901781    for (j = 0; j < 32 && i+j < length; ++j) {
    1491       sprintf(buf, "%02X", s[i+j] & 0xff);
    1492       (*outputFunc)(outputStream, buf, strlen(buf));
     1782      buf = GooString::format("{0:02x}", s[i+j] & 0xff);
     1783      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1784      delete buf;
    14931785    }
    14941786    if (i % (65536 - 32) == 65536 - 64) {
     
    15371829}
    15381830
    1539 #define toTag(a,b,c,d) (((unsigned int)(a)<<24) | ((unsigned int)(b)<<16) | ((unsigned int)(c)<<8) | (d))
    1540 
    15411831void FoFiTrueType::parse() {
    15421832  Guint topTag;
    1543   int pos, i, j;
    1544   unsigned int head;
     1833  int pos, ver, i, j;
    15451834
    15461835  parsedOk = gTrue;
     
    15521841  }
    15531842  if (topTag == ttcfTag) {
    1554     pos = getU32BE(12, &parsedOk);
    1555     if (!parsedOk) {
    1556       return;
    1557     }
    1558   } else {
    1559     pos = 0;
    1560   }
    1561 
    1562   // read the table directory
    1563   head = getU32BE(pos, &parsedOk);
    1564   if (! parsedOk)
    1565     return;
    1566   if (head == toTag('t','t','c','f')) {
    15671843    /* TTC font */
    1568     unsigned int tableDir;
    15691844    int dircount;
    15701845
     
    15821857    if (! parsedOk)
    15831858      return;
    1584   }
    1585 
    1586   pos += 4;
    1587   nTables = getU16BE(pos, &parsedOk);
     1859  } else {
     1860    pos = 0;
     1861  }
     1862
     1863  // check the sfnt version
     1864  ver = getU32BE(pos, &parsedOk);
    15881865  if (!parsedOk) {
    15891866    return;
    15901867  }
    1591 
    1592   pos += 8;
     1868  openTypeCFF = ver == 0x4f54544f; // 'OTTO'
     1869
     1870  // read the table directory
     1871  nTables = getU16BE(pos + 4, &parsedOk);
     1872  if (!parsedOk) {
     1873    return;
     1874  }
    15931875  tables = (TrueTypeTable *)gmallocn(nTables, sizeof(TrueTypeTable));
     1876  pos += 12;
    15941877  for (i = 0; i < nTables; ++i) {
    15951878    tables[i].tag = getU32BE(pos, &parsedOk);
     
    16111894  if (seekTable("head") < 0 ||
    16121895      seekTable("hhea") < 0 ||
    1613       seekTable("loca") < 0 ||
    16141896      seekTable("maxp") < 0 ||
    1615       seekTable("glyf") < 0 ||
    1616       seekTable("hmtx") < 0) {
     1897      seekTable("hmtx") < 0 ||
     1898      (!openTypeCFF && seekTable("loca") < 0) ||
     1899      (!openTypeCFF && seekTable("glyf") < 0) ||
     1900      (openTypeCFF && seekTable("CFF ") < 0)) {
    16171901    parsedOk = gFalse;
    16181902    return;
     
    16631947  // make sure the loca table is sane (correct length and entries are
    16641948  // in bounds)
    1665   i = seekTable("loca");
    1666   if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) {
    1667     parsedOk = gFalse;
    1668     return;
    1669   }
    1670   for (j = 0; j <= nGlyphs; ++j) {
    1671     if (locaFmt) {
    1672       pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk);
    1673     } else {
    1674       pos = getU16BE(tables[i].offset + j*2, &parsedOk);
    1675     }
    1676     if (pos < 0 || pos > len) {
     1949  if (!openTypeCFF) {
     1950    i = seekTable("loca");
     1951    if (tables[i].len < 0) {
    16771952      parsedOk = gFalse;
    1678     }
    1679   }
    1680   if (!parsedOk) {
    1681     return;
     1953      return;
     1954    }
     1955    if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) {
     1956      nGlyphs = tables[i].len / (locaFmt ? 4 : 2) - 1;
     1957    }
     1958    for (j = 0; j <= nGlyphs; ++j) {
     1959      if (locaFmt) {
     1960        pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk);
     1961      } else {
     1962        pos = getU16BE(tables[i].offset + j*2, &parsedOk);
     1963      }
     1964      if (pos < 0 || pos > len) {
     1965        parsedOk = gFalse;
     1966      }
     1967    }
     1968    if (!parsedOk) {
     1969      return;
     1970    }
    16821971  }
    16831972
     
    17812070  return -1;
    17822071}
     2072
     2073Guint FoFiTrueType::charToTag(const char *tagName)
     2074{
     2075  int n = strlen(tagName);
     2076  Guint tag = 0;
     2077  int i;
     2078
     2079  if (n > 4) n = 4;
     2080  for (i = 0;i < n;i++) {
     2081    tag <<= 8;
     2082    tag |= tagName[i] & 0xff;
     2083  }
     2084  for (;i < 4;i++) {
     2085    tag <<= 8;
     2086    tag |= ' ';
     2087  }
     2088  return tag;
     2089}
     2090
     2091/*
     2092  setup GSUB table data
     2093  Only supporting vertical text substitution.
     2094*/
     2095int FoFiTrueType::setupGSUB(const char *tagName)
     2096{
     2097  Guint gsubTable;
     2098  unsigned int i;
     2099  Guint scriptList, featureList;
     2100  Guint scriptCount;
     2101  Guint tag;
     2102  Guint scriptTable = 0;
     2103  Guint langSys;
     2104  Guint featureCount;
     2105  Guint featureIndex;
     2106  Guint ftable = 0;
     2107  Guint llist;
     2108  Guint scriptTag;
     2109  int x;
     2110  Guint pos;
     2111
     2112  if (tagName == 0) {
     2113    gsubFeatureTable = 0;
     2114    return 0;
     2115  }
     2116  scriptTag = charToTag(tagName);
     2117  /* read GSUB Header */
     2118  if ((x = seekTable("GSUB")) < 0) {
     2119    return 0; /* GSUB table not found */
     2120  }
     2121  gsubTable = tables[x].offset;
     2122  pos = gsubTable+4;
     2123  scriptList = getU16BE(pos,&parsedOk);
     2124  pos += 2;
     2125  featureList = getU16BE(pos,&parsedOk);
     2126  pos += 2;
     2127  llist = getU16BE(pos,&parsedOk);
     2128
     2129  gsubLookupList = llist+gsubTable; /* change to offset from top of file */
     2130  /* read script list table */
     2131  pos = gsubTable+scriptList;
     2132  scriptCount = getU16BE(pos,&parsedOk);
     2133  pos += 2;
     2134  /* find  script */
     2135  for (i = 0;i < scriptCount;i++) {
     2136    tag = getU32BE(pos,&parsedOk);
     2137    pos += 4;
     2138    scriptTable = getU16BE(pos,&parsedOk);
     2139    pos += 2;
     2140    if (tag == scriptTag) {
     2141      /* found */
     2142      break;
     2143    }
     2144  }
     2145  if (i >= scriptCount) {
     2146    /* not found */
     2147    return 0;
     2148  }
     2149
     2150  /* read script table */
     2151  /* use default language system */
     2152  pos = gsubTable+scriptList+scriptTable;
     2153  langSys = getU16BE(pos,&parsedOk);/* default language system */
     2154
     2155  /* read LangSys table */
     2156  if (langSys == 0) {
     2157    /* no ldefault LangSys */
     2158    return 0;
     2159  }
     2160
     2161  pos = gsubTable+scriptList+scriptTable+langSys+2;
     2162  featureIndex = getU16BE(pos,&parsedOk); /* ReqFeatureIndex */
     2163  pos += 2;
     2164
     2165  if (featureIndex != 0xffff) {
     2166    Guint tpos;
     2167    /* read feature record */
     2168    tpos = gsubTable+featureList;
     2169    featureCount = getU16BE(tpos,&parsedOk);
     2170    tpos = gsubTable+featureList+2+featureIndex*(4+2);
     2171    tag = getU32BE(tpos,&parsedOk);
     2172    tpos += 4;
     2173    if (tag == vrt2Tag) {
     2174      /* vrt2 is preferred, overwrite vert */
     2175      ftable = getU16BE(tpos,&parsedOk);
     2176      /* convert to offset from file top */
     2177      gsubFeatureTable = ftable+gsubTable+featureList;
     2178      return 0;
     2179    } else if (tag == vertTag) {
     2180      ftable = getU16BE(tpos,&parsedOk);
     2181    }
     2182  }
     2183  featureCount = getU16BE(pos,&parsedOk);
     2184  pos += 2;
     2185  /* find 'vrt2' or 'vert' feature */
     2186  for (i = 0;i < featureCount;i++) {
     2187    Guint oldPos;
     2188
     2189    featureIndex = getU16BE(pos,&parsedOk);
     2190    pos += 2;
     2191    oldPos = pos; /* save position */
     2192    /* read feature record */
     2193    pos = gsubTable+featureList+2+featureIndex*(4+2);
     2194    tag = getU32BE(pos,&parsedOk);
     2195    pos += 4;
     2196    if (tag == vrt2Tag) {
     2197      /* vrt2 is preferred, overwrite vert */
     2198      ftable = getU16BE(pos,&parsedOk);
     2199      break;
     2200    } else if (ftable == 0 && tag == vertTag) {
     2201      ftable = getU16BE(pos,&parsedOk);
     2202    }
     2203    pos = oldPos; /* restore old position */
     2204  }
     2205  if (ftable == 0) {
     2206    /* vert nor vrt2 are not found */
     2207    return 0;
     2208  }
     2209  /* convert to offset from file top */
     2210  gsubFeatureTable = ftable+gsubTable+featureList;
     2211  return 0;
     2212}
     2213
     2214Guint FoFiTrueType::doMapToVertGID(Guint orgGID)
     2215{
     2216  Guint lookupCount;
     2217  Guint lookupListIndex;
     2218  Guint i;
     2219  Guint gid = 0;
     2220  Guint pos;
     2221
     2222  pos = gsubFeatureTable+2;
     2223  lookupCount = getU16BE(pos,&parsedOk);
     2224  pos += 2;
     2225  for (i = 0;i < lookupCount;i++) {
     2226    lookupListIndex = getU16BE(pos,&parsedOk);
     2227    pos += 2;
     2228    if ((gid = scanLookupList(lookupListIndex,orgGID)) != 0) {
     2229      break;
     2230    }
     2231  }
     2232  return gid;
     2233}
     2234
     2235Guint FoFiTrueType::mapToVertGID(Guint orgGID)
     2236{
     2237  Guint mapped;
     2238
     2239  if (gsubFeatureTable == 0) return orgGID;
     2240  if ((mapped = doMapToVertGID(orgGID)) != 0) {
     2241    return mapped;
     2242  }
     2243  return orgGID;
     2244}
     2245
     2246Guint FoFiTrueType::scanLookupList(Guint listIndex, Guint orgGID)
     2247{
     2248  Guint lookupTable;
     2249  Guint subTableCount;
     2250  Guint subTable;
     2251  Guint i;
     2252  Guint gid = 0;
     2253  Guint pos;
     2254
     2255  if (gsubLookupList == 0) return 0; /* no lookup list */
     2256  pos = gsubLookupList+2+listIndex*2;
     2257  lookupTable = getU16BE(pos,&parsedOk);
     2258  /* read lookup table */
     2259  pos = gsubLookupList+lookupTable+4;
     2260  subTableCount = getU16BE(pos,&parsedOk);
     2261  pos += 2;;
     2262  for (i = 0;i < subTableCount;i++) {
     2263    subTable = getU16BE(pos,&parsedOk);
     2264    pos += 2;
     2265    if ((gid = scanLookupSubTable(gsubLookupList+lookupTable+subTable,orgGID))
     2266         != 0) break;
     2267  }
     2268  return gid;
     2269}
     2270
     2271Guint FoFiTrueType::scanLookupSubTable(Guint subTable, Guint orgGID)
     2272{
     2273  Guint format;
     2274  Guint coverage;
     2275  int delta;
     2276  int glyphCount;
     2277  Guint substitute;
     2278  Guint gid = 0;
     2279  int coverageIndex;
     2280  int pos;
     2281
     2282  pos = subTable;
     2283  format = getU16BE(pos,&parsedOk);
     2284  pos += 2;
     2285  coverage = getU16BE(pos,&parsedOk);
     2286  pos += 2;
     2287  if ((coverageIndex =
     2288     checkGIDInCoverage(subTable+coverage,orgGID)) >= 0) {
     2289    switch (format) {
     2290    case 1:
     2291      /* format 1 */
     2292      delta = getS16BE(pos,&parsedOk);
     2293      pos += 2;
     2294      gid = orgGID+delta;
     2295      break;
     2296    case 2:
     2297      /* format 2 */
     2298      glyphCount = getS16BE(pos,&parsedOk);
     2299      pos += 2;
     2300      if (glyphCount > coverageIndex) {
     2301        pos += coverageIndex*2;
     2302        substitute = getU16BE(pos,&parsedOk);
     2303        gid = substitute;
     2304      }
     2305      break;
     2306    default:
     2307      /* unknown format */
     2308      break;
     2309    }
     2310  }
     2311  return gid;
     2312}
     2313
     2314int FoFiTrueType::checkGIDInCoverage(Guint coverage, Guint orgGID)
     2315{
     2316  int index = -1;
     2317  Guint format;
     2318  Guint count;
     2319  Guint i;
     2320  Guint pos;
     2321
     2322  pos = coverage;
     2323  format = getU16BE(pos,&parsedOk);
     2324  pos += 2;
     2325  switch (format) {
     2326  case 1:
     2327    count = getU16BE(pos,&parsedOk);
     2328    pos += 2;
     2329    for (i = 0;i < count;i++) {
     2330      Guint gid;
     2331
     2332      gid = getU16BE(pos,&parsedOk);
     2333      pos += 2;
     2334      if (gid == orgGID) {
     2335        /* found */
     2336        index = i;
     2337        break;
     2338      } else if (gid > orgGID) {
     2339        /* not found */
     2340        break;
     2341      }
     2342    }
     2343    break;
     2344  case 2:
     2345    count = getU16BE(pos,&parsedOk);
     2346    pos += 2;
     2347    for (i = 0;i < count;i++) {
     2348      Guint startGID, endGID;
     2349      Guint startIndex;
     2350
     2351      startGID = getU16BE(pos,&parsedOk);
     2352      pos += 2;
     2353      endGID = getU16BE(pos,&parsedOk);
     2354      pos += 2;
     2355      startIndex = getU16BE(pos,&parsedOk);
     2356      pos += 2;
     2357      if (startGID <= orgGID && orgGID <= endGID) {
     2358        /* found */
     2359        index = startIndex+orgGID-startGID;
     2360        break;
     2361      } else if (orgGID <= endGID) {
     2362        /* not found */
     2363        break;
     2364      }
     2365    }
     2366    break;
     2367  default:
     2368    break;
     2369  }
     2370  return index;
     2371}
     2372
  • trunk/poppler/mypoppler/fofi/FoFiTrueType.h

    r2 r250  
    3535  static FoFiTrueType *load(char *fileName, int faceIndexA=0);
    3636
    37   FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA=0);
    3837  virtual ~FoFiTrueType();
     38
     39  // Returns true if this an OpenType font containing CFF data, false
     40  // if it's a TrueType font (or OpenType font with TrueType data).
     41  GBool isOpenTypeCFF() { return openTypeCFF; }
    3942
    4043  // Return the number of cmaps defined by this font.
     
    5255
    5356  // Return the GID corresponding to <c> according to the <i>th cmap.
    54   Gushort mapCodeToGID(int i, int c);
     57  Gushort mapCodeToGID(int i, Guint c);
     58
     59  // map gid to vertical glyph gid if exist.
     60  //   if not exist return original gid
     61  Guint mapToVertGID(Guint orgGID);
    5562
    5663  // Returns the GID corresponding to <name> according to the post
     
    5865  // font does not have a post table.
    5966  int mapNameToGID(char *name);
     67
     68  // Return the mapping from CIDs to GIDs, and return the number of
     69  // CIDs in *<nCIDs>.  This is only useful for CID fonts.  (Only
     70  // useful for OpenType CFF fonts.)
     71  Gushort *getCIDToGIDMap(int *nCIDs);
    6072
    6173  // Returns the least restrictive embedding licensing right (as
     
    7486  // If <encoding> is NULL, the encoding is unknown or undefined.  The
    7587  // <codeToGID> array specifies the mapping from char codes to GIDs.
     88  // (Not useful for OpenType CFF fonts.)
    7689  void convertToType42(char *psName, char **encoding,
    7790                       Gushort *codeToGID,
    7891                       FoFiOutputFunc outputFunc, void *outputStream);
     92
     93  // Convert to a Type 1 font, suitable for embedding in a PostScript
     94  // file.  This is only useful with 8-bit fonts.  If <newEncoding> is
     95  // not NULL, it will be used in place of the encoding in the Type 1C
     96  // font.  If <ascii> is true the eexec section will be hex-encoded,
     97  // otherwise it will be left as binary data.  If <psName> is
     98  // non-NULL, it will be used as the PostScript font name.  (Only
     99  // useful for OpenType CFF fonts.)
     100  void convertToType1(char *psName, char **newEncoding, GBool ascii,
     101                      FoFiOutputFunc outputFunc, void *outputStream);
    79102
    80103  // Convert to a Type 2 CIDFont, suitable for embedding in a
     
    82105  // name (so we don't need to depend on the 'name' table in the
    83106  // font).  The <cidMap> array maps CIDs to GIDs; it has <nCIDs>
    84   // entries.
     107  // entries.  (Not useful for OpenType CFF fonts.)
    85108  void convertToCIDType2(char *psName, Gushort *cidMap, int nCIDs,
    86109                         GBool needVerticalMetrics,
     110                         FoFiOutputFunc outputFunc, void *outputStream);
     111
     112  // Convert to a Type 0 CIDFont, suitable for embedding in a
     113  // PostScript file.  <psName> will be used as the PostScript font
     114  // name.  (Only useful for OpenType CFF fonts.)
     115  void convertToCIDType0(char *psName,
    87116                         FoFiOutputFunc outputFunc, void *outputStream);
    88117
     
    91120  // PostScript font name (so we don't need to depend on the 'name'
    92121  // table in the font).  The <cidMap> array maps CIDs to GIDs; it has
    93   // <nCIDs> entries.
     122  // <nCIDs> entries.  (Not useful for OpenType CFF fonts.)
    94123  void convertToType0(char *psName, Gushort *cidMap, int nCIDs,
    95124                      GBool needVerticalMetrics,
     125                      FoFiOutputFunc outputFunc, void *outputStream);
     126
     127  // Convert to a Type 0 (but non-CID) composite font, suitable for
     128  // embedding in a PostScript file.  <psName> will be used as the
     129  // PostScript font name.  (Only useful for OpenType CFF fonts.)
     130  void convertToType0(char *psName,
    96131                      FoFiOutputFunc outputFunc, void *outputStream);
    97132
     
    100135  // to <name>.  If <codeToGID> is non-NULL, the font is re-encoded,
    101136  // using a Windows Unicode cmap.  If <name> is NULL and the font is
    102   // complete and correct, it will be written unmodified.
     137  // complete and correct, it will be written unmodified.  (Not useful
     138  // for OpenType CFF fonts.)
    103139  void writeTTF(FoFiOutputFunc outputFunc, void *outputStream,
    104140                char *name = NULL, Gushort *codeToGID = NULL);
    105141
     142  int setupGSUB(const char *tagName);
    106143private:
    107144
     145  FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA);
    108146  void cvtEncoding(char **encoding,
    109147                   FoFiOutputFunc outputFunc,
     
    123161  void readPostTable();
    124162  int seekTable(char *tag);
     163  Guint charToTag(const char *tagName);
     164  Guint doMapToVertGID(Guint orgGID);
     165  Guint scanLookupList(Guint listIndex, Guint orgGID);
     166  Guint scanLookupSubTable(Guint subTable, Guint orgGID);
     167  int checkGIDInCoverage(Guint coverage, Guint orgGID);
    125168
    126169  TrueTypeTable *tables;
     
    132175  int bbox[4];
    133176  GooHash *nameToGID;
     177  GBool openTypeCFF;
    134178
    135179  GBool parsedOk;
    136180  int faceIndex;
     181  Guint gsubFeatureTable;
     182  Guint gsubLookupList;
    137183};
    138184
  • trunk/poppler/mypoppler/fofi/FoFiType1.cc

    r2 r250  
    7676                             FoFiOutputFunc outputFunc, void *outputStream) {
    7777  char buf[512];
    78   char *line;
     78  char *line, *line2, *p;
    7979  int i;
    8080
     
    102102  (*outputFunc)(outputStream, "readonly def\n", 13);
    103103 
    104   // copy everything after the encoding
     104  // find the end of the encoding data
     105  //~ this ought to parse PostScript tokens
    105106  if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
    106107    line = getNextLine(line);
    107108  } else {
    108     for (line = getNextLine(line);
    109          line && strncmp(line, "readonly def", 12);
    110          line = getNextLine(line)) ;
     109    // skip "/Encoding" + one whitespace char,
     110    // then look for 'def' preceded by PostScript whitespace
     111    p = line + 10;
     112    line = NULL;
     113    for (; p < (char *)file + len; ++p) {
     114      if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
     115           *p == '\x0d' || *p == '\x0c' || *p == '\0') &&
     116          p + 4 <= (char *)file + len &&
     117          !strncmp(p + 1, "def", 3)) {
     118        line = p + 4;
     119        break;
     120      }
     121    }
     122  }
     123
     124  // some fonts have two /Encoding entries in their dictionary, so we
     125  // check for a second one here
     126  if (line) {
     127    for (line2 = line, i = 0;
     128         i < 20 && line2 && strncmp(line2, "/Encoding", 9);
     129         line2 = getNextLine(line2), ++i) ;
     130    if (i < 20 && line2) {
     131      (*outputFunc)(outputStream, line, line2 - line);
     132      if (!strncmp(line2, "/Encoding StandardEncoding def", 30)) {
     133        line = getNextLine(line2);
     134      } else {
     135        // skip "/Encoding" + one whitespace char,
     136        // then look for 'def' preceded by PostScript whitespace
     137        p = line2 + 10;
     138        line = NULL;
     139        for (; p < (char *)file + len; ++p) {
     140          if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
     141               *p == '\x0d' || *p == '\x0c' || *p == '\0') &&
     142              p + 4 <= (char *)file + len &&
     143              !strncmp(p + 1, "def", 3)) {
     144            line = p + 4;
     145            break;
     146          }
     147        }
     148      }
     149    }
     150
     151    // copy everything after the encoding
    111152    if (line) {
    112       line = getNextLine(line);
    113     }
    114   }
    115   if (line) {
    116     (*outputFunc)(outputStream, line, ((char *)file + len) - line);
     153      (*outputFunc)(outputStream, line, ((char *)file + len) - line);
     154    }
    117155  }
    118156}
     
    179217            c = *p2;
    180218            *p2 = '\0';
    181             if ((code = atoi(p)) < 256) {
    182               *p2 = c;
     219            code = atoi(p);
     220            *p2 = c;
     221            if (code == 8 && *p2 == '#') {
     222              code = 0;
     223              for (++p2; *p2 >= '0' && *p2 <= '7'; ++p2) {
     224                code = code * 8 + (*p2 - '0');
     225              }
     226            }
     227            if (code < 256) {
    183228              for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
    184229              if (*p == '/') {
  • trunk/poppler/mypoppler/fofi/FoFiType1C.cc

    r2 r250  
    130130}
    131131
    132 void FoFiType1C::convertToType1(char **newEncoding, GBool ascii,
     132void FoFiType1C::convertToType1(char *psName, char **newEncoding, GBool ascii,
    133133                                FoFiOutputFunc outputFunc,
    134134                                void *outputStream) {
     135  int psNameLen;
    135136  Type1CEexecBuf eb;
    136137  Type1CIndex subrIdx;
    137138  Type1CIndexVal val;
    138   char buf[512];
     139  GooString *buf;
     140  char buf2[256];
    139141  char **enc;
    140142  GBool ok;
    141143  int i;
    142144
     145  if (psName) {
     146    psNameLen = strlen(psName);
     147  } else {
     148    psName = name->getCString();
     149    psNameLen = name->getLength();
     150  }
     151
    143152  // write header and font dictionary, up to encoding
    144153  ok = gTrue;
    145154  (*outputFunc)(outputStream, "%!FontType1-1.0: ", 17);
    146   (*outputFunc)(outputStream, name->getCString(), name->getLength());
     155  (*outputFunc)(outputStream, psName, psNameLen);
    147156  if (topDict.versionSID != 0) {
    148     getString(topDict.versionSID, buf, &ok);
    149     (*outputFunc)(outputStream, buf, strlen(buf));
     157    getString(topDict.versionSID, buf2, &ok);
     158    (*outputFunc)(outputStream, buf2, strlen(buf2));
    150159  }
    151160  (*outputFunc)(outputStream, "\n", 1);
     
    157166  if (topDict.versionSID != 0) {
    158167    (*outputFunc)(outputStream, "/version (", 10);
    159     (*outputFunc)(outputStream, buf, strlen(buf));
     168    (*outputFunc)(outputStream, buf2, strlen(buf2));
    160169    (*outputFunc)(outputStream, ") readonly def\n", 15);
    161170  }
    162171  if (topDict.noticeSID != 0) {
    163     getString(topDict.noticeSID, buf, &ok);
     172    getString(topDict.noticeSID, buf2, &ok);
    164173    (*outputFunc)(outputStream, "/Notice (", 9);
    165     (*outputFunc)(outputStream, buf, strlen(buf));
     174    (*outputFunc)(outputStream, buf2, strlen(buf2));
    166175    (*outputFunc)(outputStream, ") readonly def\n", 15);
    167176  }
    168177  if (topDict.copyrightSID != 0) {
    169     getString(topDict.copyrightSID, buf, &ok);
     178    getString(topDict.copyrightSID, buf2, &ok);
    170179    (*outputFunc)(outputStream, "/Copyright (", 12);
    171     (*outputFunc)(outputStream, buf, strlen(buf));
     180    (*outputFunc)(outputStream, buf2, strlen(buf2));
    172181    (*outputFunc)(outputStream, ") readonly def\n", 15);
    173182  }
    174183  if (topDict.fullNameSID != 0) {
    175     getString(topDict.fullNameSID, buf, &ok);
     184    getString(topDict.fullNameSID, buf2, &ok);
    176185    (*outputFunc)(outputStream, "/FullName (", 11);
    177     (*outputFunc)(outputStream, buf, strlen(buf));
     186    (*outputFunc)(outputStream, buf2, strlen(buf2));
    178187    (*outputFunc)(outputStream, ") readonly def\n", 15);
    179188  }
    180189  if (topDict.familyNameSID != 0) {
    181     getString(topDict.familyNameSID, buf, &ok);
     190    getString(topDict.familyNameSID, buf2, &ok);
    182191    (*outputFunc)(outputStream, "/FamilyName (", 13);
    183     (*outputFunc)(outputStream, buf, strlen(buf));
     192    (*outputFunc)(outputStream, buf2, strlen(buf2));
    184193    (*outputFunc)(outputStream, ") readonly def\n", 15);
    185194  }
    186195  if (topDict.weightSID != 0) {
    187     getString(topDict.weightSID, buf, &ok);
     196    getString(topDict.weightSID, buf2, &ok);
    188197    (*outputFunc)(outputStream, "/Weight (", 9);
    189     (*outputFunc)(outputStream, buf, strlen(buf));
     198    (*outputFunc)(outputStream, buf2, strlen(buf2));
    190199    (*outputFunc)(outputStream, ") readonly def\n", 15);
    191200  }
     
    195204    (*outputFunc)(outputStream, "/isFixedPitch false def\n", 24);
    196205  }
    197   sprintf(buf, "/ItalicAngle %g def\n", topDict.italicAngle);
    198   (*outputFunc)(outputStream, buf, strlen(buf));
    199   sprintf(buf, "/UnderlinePosition %g def\n", topDict.underlinePosition);
    200   (*outputFunc)(outputStream, buf, strlen(buf));
    201   sprintf(buf, "/UnderlineThickness %g def\n", topDict.underlineThickness);
    202   (*outputFunc)(outputStream, buf, strlen(buf));
     206  buf = GooString::format("/ItalicAngle {0:.4g} def\n", topDict.italicAngle);
     207  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     208  delete buf;
     209  buf = GooString::format("/UnderlinePosition {0:.4g} def\n",
     210                        topDict.underlinePosition);
     211  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     212  delete buf;
     213  buf = GooString::format("/UnderlineThickness {0:.4g} def\n",
     214                        topDict.underlineThickness);
     215  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     216  delete buf;
    203217  (*outputFunc)(outputStream, "end readonly def\n", 17);
    204218  (*outputFunc)(outputStream, "/FontName /", 11);
    205   (*outputFunc)(outputStream, name->getCString(), name->getLength());
     219  (*outputFunc)(outputStream, psName, psNameLen);
    206220  (*outputFunc)(outputStream, " def\n", 5);
    207   sprintf(buf, "/PaintType %d def\n", topDict.paintType);
    208   (*outputFunc)(outputStream, buf, strlen(buf));
     221  buf = GooString::format("/PaintType {0:d} def\n", topDict.paintType);
     222  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     223  delete buf;
    209224  (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
    210   sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
    211           topDict.fontMatrix[0], topDict.fontMatrix[1], topDict.fontMatrix[2],
    212           topDict.fontMatrix[3], topDict.fontMatrix[4], topDict.fontMatrix[5]);
    213   (*outputFunc)(outputStream, buf, strlen(buf));
    214   sprintf(buf, "/FontBBox [%g %g %g %g] readonly def\n",
    215           topDict.fontBBox[0], topDict.fontBBox[1],
    216           topDict.fontBBox[2], topDict.fontBBox[3]);
    217   (*outputFunc)(outputStream, buf, strlen(buf));
    218   sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
    219   (*outputFunc)(outputStream, buf, strlen(buf));
     225  buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] readonly def\n",
     226                        topDict.fontMatrix[0], topDict.fontMatrix[1],
     227                        topDict.fontMatrix[2], topDict.fontMatrix[3],
     228                        topDict.fontMatrix[4], topDict.fontMatrix[5]);
     229  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     230  delete buf;
     231  buf = GooString::format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] readonly def\n",
     232                        topDict.fontBBox[0], topDict.fontBBox[1],
     233                        topDict.fontBBox[2], topDict.fontBBox[3]);
     234  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     235  delete buf;
     236  buf = GooString::format("/StrokeWidth {0:.4g} def\n", topDict.strokeWidth);
     237  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     238  delete buf;
    220239  if (topDict.uniqueID != 0) {
    221     sprintf(buf, "/UniqueID %d def\n", topDict.uniqueID);
    222     (*outputFunc)(outputStream, buf, strlen(buf));
     240    buf = GooString::format("/UniqueID {0:d} def\n", topDict.uniqueID);
     241    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     242    delete buf;
    223243  }
    224244
     
    234254    for (i = 0; i < 256; ++i) {
    235255      if (enc[i]) {
    236         sprintf(buf, "dup %d /%s put\n", i, enc[i]);
    237         (*outputFunc)(outputStream, buf, strlen(buf));
     256        buf = GooString::format("dup {0:d} /{1:s} put\n", i, enc[i]);
     257        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     258        delete buf;
    238259      }
    239260    }
     
    262283    eexecWrite(&eb, "/BlueValues [");
    263284    for (i = 0; i < privateDicts[0].nBlueValues; ++i) {
    264       sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].blueValues[i]);
    265       eexecWrite(&eb, buf);
     285      buf = GooString::format("{0:s}{1:d}",
     286                            i > 0 ? " " : "", privateDicts[0].blueValues[i]);
     287      eexecWrite(&eb, buf->getCString());
     288      delete buf;
    266289    }
    267290    eexecWrite(&eb, "] def\n");
     
    270293    eexecWrite(&eb, "/OtherBlues [");
    271294    for (i = 0; i < privateDicts[0].nOtherBlues; ++i) {
    272       sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].otherBlues[i]);
    273       eexecWrite(&eb, buf);
     295      buf = GooString::format("{0:s}{1:d}",
     296                            i > 0 ? " " : "", privateDicts[0].otherBlues[i]);
     297      eexecWrite(&eb, buf->getCString());
     298      delete buf;
    274299    }
    275300    eexecWrite(&eb, "] def\n");
     
    278303    eexecWrite(&eb, "/FamilyBlues [");
    279304    for (i = 0; i < privateDicts[0].nFamilyBlues; ++i) {
    280       sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].familyBlues[i]);
    281       eexecWrite(&eb, buf);
     305      buf = GooString::format("{0:s}{1:d}",
     306                            i > 0 ? " " : "", privateDicts[0].familyBlues[i]);
     307      eexecWrite(&eb, buf->getCString());
     308      delete buf;
    282309    }
    283310    eexecWrite(&eb, "] def\n");
     
    286313    eexecWrite(&eb, "/FamilyOtherBlues [");
    287314    for (i = 0; i < privateDicts[0].nFamilyOtherBlues; ++i) {
    288       sprintf(buf, "%s%d", i > 0 ? " " : "",
    289               privateDicts[0].familyOtherBlues[i]);
    290       eexecWrite(&eb, buf);
     315      buf = GooString::format("{0:s}{1:d}", i > 0 ? " " : "",
     316                            privateDicts[0].familyOtherBlues[i]);
     317      eexecWrite(&eb, buf->getCString());
     318      delete buf;
    291319    }
    292320    eexecWrite(&eb, "] def\n");
    293321  }
    294322  if (privateDicts[0].blueScale != 0.039625) {
    295     sprintf(buf, "/BlueScale %g def\n", privateDicts[0].blueScale);
    296     eexecWrite(&eb, buf);
     323    buf = GooString::format("/BlueScale {0:.4g} def\n",
     324                          privateDicts[0].blueScale);
     325    eexecWrite(&eb, buf->getCString());
     326    delete buf;
    297327  }
    298328  if (privateDicts[0].blueShift != 7) {
    299     sprintf(buf, "/BlueShift %d def\n", privateDicts[0].blueShift);
    300     eexecWrite(&eb, buf);
     329    buf = GooString::format("/BlueShift {0:d} def\n", privateDicts[0].blueShift);
     330    eexecWrite(&eb, buf->getCString());
     331    delete buf;
    301332  }
    302333  if (privateDicts[0].blueFuzz != 1) {
    303     sprintf(buf, "/BlueFuzz %d def\n", privateDicts[0].blueFuzz);
    304     eexecWrite(&eb, buf);
     334    buf = GooString::format("/BlueFuzz {0:d} def\n", privateDicts[0].blueFuzz);
     335    eexecWrite(&eb, buf->getCString());
     336    delete buf;
    305337  }
    306338  if (privateDicts[0].hasStdHW) {
    307     sprintf(buf, "/StdHW [%g] def\n", privateDicts[0].stdHW);
    308     eexecWrite(&eb, buf);
     339    buf = GooString::format("/StdHW [{0:.4g}] def\n", privateDicts[0].stdHW);
     340    eexecWrite(&eb, buf->getCString());
     341    delete buf;
    309342  }
    310343  if (privateDicts[0].hasStdVW) {
    311     sprintf(buf, "/StdVW [%g] def\n", privateDicts[0].stdVW);
    312     eexecWrite(&eb, buf);
     344    buf = GooString::format("/StdVW [{0:.4g}] def\n", privateDicts[0].stdVW);
     345    eexecWrite(&eb, buf->getCString());
     346    delete buf;
    313347  }
    314348  if (privateDicts[0].nStemSnapH) {
    315349    eexecWrite(&eb, "/StemSnapH [");
    316350    for (i = 0; i < privateDicts[0].nStemSnapH; ++i) {
    317       sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapH[i]);
    318       eexecWrite(&eb, buf);
     351      buf = GooString::format("{0:s}{1:.4g}",
     352                            i > 0 ? " " : "", privateDicts[0].stemSnapH[i]);
     353      eexecWrite(&eb, buf->getCString());
     354      delete buf;
    319355    }
    320356    eexecWrite(&eb, "] def\n");
     
    323359    eexecWrite(&eb, "/StemSnapV [");
    324360    for (i = 0; i < privateDicts[0].nStemSnapV; ++i) {
    325       sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapV[i]);
    326       eexecWrite(&eb, buf);
     361      buf = GooString::format("{0:s}{1:.4g}",
     362                            i > 0 ? " " : "", privateDicts[0].stemSnapV[i]);
     363      eexecWrite(&eb, buf->getCString());
     364      delete buf;
    327365    }
    328366    eexecWrite(&eb, "] def\n");
    329367  }
    330368  if (privateDicts[0].hasForceBold) {
    331     sprintf(buf, "/ForceBold %s def\n",
    332             privateDicts[0].forceBold ? "true" : "false");
    333     eexecWrite(&eb, buf);
     369    buf = GooString::format("/ForceBold {0:s} def\n",
     370                          privateDicts[0].forceBold ? "true" : "false");
     371    eexecWrite(&eb, buf->getCString());
     372    delete buf;
    334373  }
    335374  if (privateDicts[0].forceBoldThreshold != 0) {
    336     sprintf(buf, "/ForceBoldThreshold %g def\n",
    337             privateDicts[0].forceBoldThreshold);
    338     eexecWrite(&eb, buf);
     375    buf = GooString::format("/ForceBoldThreshold {0:.4g} def\n",
     376                          privateDicts[0].forceBoldThreshold);
     377    eexecWrite(&eb, buf->getCString());
     378    delete buf;
    339379  }
    340380  if (privateDicts[0].languageGroup != 0) {
    341     sprintf(buf, "/LanguageGroup %d def\n", privateDicts[0].languageGroup);
    342     eexecWrite(&eb, buf);
     381    buf = GooString::format("/LanguageGroup {0:d} def\n",
     382                          privateDicts[0].languageGroup);
     383    eexecWrite(&eb, buf->getCString());
     384    delete buf;
    343385  }
    344386  if (privateDicts[0].expansionFactor != 0.06) {
    345     sprintf(buf, "/ExpansionFactor %g def\n", privateDicts[0].expansionFactor);
    346     eexecWrite(&eb, buf);
     387    buf = GooString::format("/ExpansionFactor {0:.4g} def\n",
     388                          privateDicts[0].expansionFactor);
     389    eexecWrite(&eb, buf->getCString());
     390    delete buf;
    347391  }
    348392
     
    355399
    356400  // write the CharStrings
    357   sprintf(buf, "2 index /CharStrings %d dict dup begin\n", nGlyphs);
    358   eexecWrite(&eb, buf);
     401  buf = GooString::format("2 index /CharStrings {0:d} dict dup begin\n",
     402                        nGlyphs);
     403  eexecWrite(&eb, buf->getCString());
     404  delete buf;
    359405  for (i = 0; i < nGlyphs; ++i) {
    360406    ok = gTrue;
    361407    getIndexVal(&charStringsIdx, i, &val, &ok);
    362408    if (ok) {
    363       getString(charset[i], buf, &ok);
     409      getString(charset[i], buf2, &ok);
    364410      if (ok) {
    365         eexecCvtGlyph(&eb, buf, val.pos, val.len, &subrIdx, &privateDicts[0]);
     411        eexecCvtGlyph(&eb, buf2, val.pos, val.len, &subrIdx, &privateDicts[0]);
    366412      }
    367413    }
     
    393439  Type1CIndexVal val;
    394440  int nCIDs, gdBytes;
    395   char buf[512], buf2[512];
     441  GooString *buf;
     442  char buf2[256];
    396443  GBool ok;
    397444  int gid, offset, n, i, j, k;
     
    457504  if (topDict.registrySID > 0 && topDict.orderingSID > 0) {
    458505    ok = gTrue;
    459     getString(topDict.registrySID, buf, &ok);
     506    getString(topDict.registrySID, buf2, &ok);
    460507    if (ok) {
    461508      (*outputFunc)(outputStream, "  /Registry (", 13);
    462       (*outputFunc)(outputStream, buf, strlen(buf));
     509      (*outputFunc)(outputStream, buf2, strlen(buf2));
    463510      (*outputFunc)(outputStream, ") def\n", 6);
    464511    }
    465512    ok = gTrue;
    466     getString(topDict.orderingSID, buf, &ok);
     513    getString(topDict.orderingSID, buf2, &ok);
    467514    if (ok) {
    468515      (*outputFunc)(outputStream, "  /Ordering (", 13);
    469       (*outputFunc)(outputStream, buf, strlen(buf));
     516      (*outputFunc)(outputStream, buf2, strlen(buf2));
    470517      (*outputFunc)(outputStream, ") def\n", 6);
    471518    }
     
    474521    (*outputFunc)(outputStream, "  /Ordering (Identity) def\n", 27);
    475522  }
    476   sprintf(buf, "  /Supplement %d def\n", topDict.supplement);
    477   (*outputFunc)(outputStream, buf, strlen(buf));
     523  buf = GooString::format("  /Supplement {0:d} def\n", topDict.supplement);
     524  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     525  delete buf;
    478526  (*outputFunc)(outputStream, "end def\n", 8);
    479527  if (topDict.hasFontMatrix) {
    480     sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
    481             topDict.fontMatrix[0], topDict.fontMatrix[1],
    482             topDict.fontMatrix[2], topDict.fontMatrix[3],
    483             topDict.fontMatrix[4], topDict.fontMatrix[5]);
    484     (*outputFunc)(outputStream, buf, strlen(buf));
     528    buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n",
     529                          topDict.fontMatrix[0], topDict.fontMatrix[1],
     530                          topDict.fontMatrix[2], topDict.fontMatrix[3],
     531                          topDict.fontMatrix[4], topDict.fontMatrix[5]);
     532    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     533    delete buf;
    485534  } else if (privateDicts[0].hasFontMatrix) {
    486535    (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
     
    489538                  "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38);
    490539  }
    491   sprintf(buf, "/FontBBox [%g %g %g %g] def\n",
    492           topDict.fontBBox[0], topDict.fontBBox[1],
    493           topDict.fontBBox[2], topDict.fontBBox[3]);
    494   (*outputFunc)(outputStream, buf, strlen(buf));
     540  buf = GooString::format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] def\n",
     541                        topDict.fontBBox[0], topDict.fontBBox[1],
     542                        topDict.fontBBox[2], topDict.fontBBox[3]);
     543  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     544  delete buf;
    495545  (*outputFunc)(outputStream, "/FontInfo 1 dict dup begin\n", 27);
    496546  (*outputFunc)(outputStream, "  /FSType 8 def\n", 16);
     
    498548
    499549  // CIDFont-specific entries
    500   sprintf(buf, "/CIDCount %d def\n", nCIDs);
    501   (*outputFunc)(outputStream, buf, strlen(buf));
     550  buf = GooString::format("/CIDCount {0:d} def\n", nCIDs);
     551  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     552  delete buf;
    502553  (*outputFunc)(outputStream, "/FDBytes 1 def\n", 15);
    503   sprintf(buf, "/GDBytes %d def\n", gdBytes);
    504   (*outputFunc)(outputStream, buf, strlen(buf));
     554  buf = GooString::format("/GDBytes {0:d} def\n", gdBytes);
     555  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     556  delete buf;
    505557  (*outputFunc)(outputStream, "/CIDMapOffset 0 def\n", 20);
    506558  if (topDict.paintType != 0) {
    507     sprintf(buf, "/PaintType %d def\n", topDict.paintType);
    508     (*outputFunc)(outputStream, buf, strlen(buf));
    509     sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
    510     (*outputFunc)(outputStream, buf, strlen(buf));
     559    buf = GooString::format("/PaintType {0:d} def\n", topDict.paintType);
     560    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     561    delete buf;
     562    buf = GooString::format("/StrokeWidth {0:.4g} def\n", topDict.strokeWidth);
     563    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     564    delete buf;
    511565  }
    512566
    513567  // FDArray entry
    514   sprintf(buf, "/FDArray %d array\n", nFDs);
    515   (*outputFunc)(outputStream, buf, strlen(buf));
     568  buf = GooString::format("/FDArray {0:d} array\n", nFDs);
     569  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     570  delete buf;
    516571  for (i = 0; i < nFDs; ++i) {
    517     sprintf(buf, "dup %d 10 dict begin\n", i);
    518     (*outputFunc)(outputStream, buf, strlen(buf));
     572    buf = GooString::format("dup {0:d} 10 dict begin\n", i);
     573    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     574    delete buf;
    519575    (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
    520576    if (privateDicts[i].hasFontMatrix) {
    521       sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
    522               privateDicts[i].fontMatrix[0],
    523               privateDicts[i].fontMatrix[1],
    524               privateDicts[i].fontMatrix[2],
    525               privateDicts[i].fontMatrix[3],
    526               privateDicts[i].fontMatrix[4],
    527               privateDicts[i].fontMatrix[5]);
    528       (*outputFunc)(outputStream, buf, strlen(buf));
     577      buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n",
     578                            privateDicts[i].fontMatrix[0],
     579                            privateDicts[i].fontMatrix[1],
     580                            privateDicts[i].fontMatrix[2],
     581                            privateDicts[i].fontMatrix[3],
     582                            privateDicts[i].fontMatrix[4],
     583                            privateDicts[i].fontMatrix[5]);
     584      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     585      delete buf;
    529586    } else {
    530587      (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
    531588    }
    532     sprintf(buf, "/PaintType %d def\n", topDict.paintType);
    533     (*outputFunc)(outputStream, buf, strlen(buf));
     589    buf = GooString::format("/PaintType {0:d} def\n", topDict.paintType);
     590    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     591    delete buf;
    534592    (*outputFunc)(outputStream, "/Private 32 dict begin\n", 23);
    535593    if (privateDicts[i].nBlueValues) {
    536594      (*outputFunc)(outputStream, "/BlueValues [", 13);
    537595      for (j = 0; j < privateDicts[i].nBlueValues; ++j) {
    538         sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].blueValues[j]);
    539         (*outputFunc)(outputStream, buf, strlen(buf));
     596        buf = GooString::format("{0:s}{1:d}",
     597                              j > 0 ? " " : "", privateDicts[i].blueValues[j]);
     598        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     599        delete buf;
    540600      }
    541601      (*outputFunc)(outputStream, "] def\n", 6);
     
    544604      (*outputFunc)(outputStream, "/OtherBlues [", 13);
    545605      for (j = 0; j < privateDicts[i].nOtherBlues; ++j) {
    546         sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].otherBlues[j]);
    547         (*outputFunc)(outputStream, buf, strlen(buf));
     606        buf = GooString::format("{0:s}{1:d}",
     607                              j > 0 ? " " : "", privateDicts[i].otherBlues[j]);
     608        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     609        delete buf;
    548610      }
    549611      (*outputFunc)(outputStream, "] def\n", 6);
     
    552614      (*outputFunc)(outputStream, "/FamilyBlues [", 14);
    553615      for (j = 0; j < privateDicts[i].nFamilyBlues; ++j) {
    554         sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].familyBlues[j]);
    555         (*outputFunc)(outputStream, buf, strlen(buf));
     616        buf = GooString::format("{0:s}{1:d}",
     617                              j > 0 ? " " : "",
     618                              privateDicts[i].familyBlues[j]);
     619        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     620        delete buf;
    556621      }
    557622      (*outputFunc)(outputStream, "] def\n", 6);
     
    560625      (*outputFunc)(outputStream, "/FamilyOtherBlues [", 19);
    561626      for (j = 0; j < privateDicts[i].nFamilyOtherBlues; ++j) {
    562         sprintf(buf, "%s%d", j > 0 ? " " : "",
    563                 privateDicts[i].familyOtherBlues[j]);
    564         (*outputFunc)(outputStream, buf, strlen(buf));
     627        buf = GooString::format("{0:s}{1:d}", j > 0 ? " " : "",
     628                              privateDicts[i].familyOtherBlues[j]);
     629        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     630        delete buf;
    565631      }
    566632      (*outputFunc)(outputStream, "] def\n", 6);
    567633    }
    568634    if (privateDicts[i].blueScale != 0.039625) {
    569       sprintf(buf, "/BlueScale %g def\n", privateDicts[i].blueScale);
    570       (*outputFunc)(outputStream, buf, strlen(buf));
     635      buf = GooString::format("/BlueScale {0:.4g} def\n",
     636                            privateDicts[i].blueScale);
     637      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     638      delete buf;
    571639    }
    572640    if (privateDicts[i].blueShift != 7) {
    573       sprintf(buf, "/BlueShift %d def\n", privateDicts[i].blueShift);
    574       (*outputFunc)(outputStream, buf, strlen(buf));
     641      buf = GooString::format("/BlueShift {0:d} def\n",
     642                            privateDicts[i].blueShift);
     643      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     644      delete buf;
    575645    }
    576646    if (privateDicts[i].blueFuzz != 1) {
    577       sprintf(buf, "/BlueFuzz %d def\n", privateDicts[i].blueFuzz);
    578       (*outputFunc)(outputStream, buf, strlen(buf));
     647      buf = GooString::format("/BlueFuzz {0:d} def\n", privateDicts[i].blueFuzz);
     648      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     649      delete buf;
    579650    }
    580651    if (privateDicts[i].hasStdHW) {
    581       sprintf(buf, "/StdHW [%g] def\n", privateDicts[i].stdHW);
    582       (*outputFunc)(outputStream, buf, strlen(buf));
     652      buf = GooString::format("/StdHW [{0:.4g}] def\n", privateDicts[i].stdHW);
     653      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     654      delete buf;
    583655    }
    584656    if (privateDicts[i].hasStdVW) {
    585       sprintf(buf, "/StdVW [%g] def\n", privateDicts[i].stdVW);
    586       (*outputFunc)(outputStream, buf, strlen(buf));
     657      buf = GooString::format("/StdVW [{0:.4g}] def\n", privateDicts[i].stdVW);
     658      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     659      delete buf;
    587660    }
    588661    if (privateDicts[i].nStemSnapH) {
    589662      (*outputFunc)(outputStream, "/StemSnapH [", 12);
    590663      for (j = 0; j < privateDicts[i].nStemSnapH; ++j) {
    591         sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapH[j]);
    592         (*outputFunc)(outputStream, buf, strlen(buf));
     664        buf = GooString::format("{0:s}{1:.4g}",
     665                              j > 0 ? " " : "", privateDicts[i].stemSnapH[j]);
     666        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     667        delete buf;
    593668      }
    594669      (*outputFunc)(outputStream, "] def\n", 6);
     
    597672      (*outputFunc)(outputStream, "/StemSnapV [", 12);
    598673      for (j = 0; j < privateDicts[i].nStemSnapV; ++j) {
    599         sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapV[j]);
    600         (*outputFunc)(outputStream, buf, strlen(buf));
     674        buf = GooString::format("{0:s}{1:.4g}",
     675                              j > 0 ? " " : "", privateDicts[i].stemSnapV[j]);
     676        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     677        delete buf;
    601678      }
    602679      (*outputFunc)(outputStream, "] def\n", 6);
    603680    }
    604681    if (privateDicts[i].hasForceBold) {
    605       sprintf(buf, "/ForceBold %s def\n",
    606               privateDicts[i].forceBold ? "true" : "false");
    607       (*outputFunc)(outputStream, buf, strlen(buf));
     682      buf = GooString::format("/ForceBold {0:s} def\n",
     683                            privateDicts[i].forceBold ? "true" : "false");
     684      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     685      delete buf;
    608686    }
    609687    if (privateDicts[i].forceBoldThreshold != 0) {
    610       sprintf(buf, "/ForceBoldThreshold %g def\n",
    611               privateDicts[i].forceBoldThreshold);
    612       (*outputFunc)(outputStream, buf, strlen(buf));
     688      buf = GooString::format("/ForceBoldThreshold {0:.4g} def\n",
     689                            privateDicts[i].forceBoldThreshold);
     690      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     691      delete buf;
    613692    }
    614693    if (privateDicts[i].languageGroup != 0) {
    615       sprintf(buf, "/LanguageGroup %d def\n", privateDicts[i].languageGroup);
    616       (*outputFunc)(outputStream, buf, strlen(buf));
     694      buf = GooString::format("/LanguageGroup {0:d} def\n",
     695                            privateDicts[i].languageGroup);
     696      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     697      delete buf;
    617698    }
    618699    if (privateDicts[i].expansionFactor != 0.06) {
    619       sprintf(buf, "/ExpansionFactor %g def\n",
    620               privateDicts[i].expansionFactor);
    621       (*outputFunc)(outputStream, buf, strlen(buf));
     700      buf = GooString::format("/ExpansionFactor {0:.4g} def\n",
     701                            privateDicts[i].expansionFactor);
     702      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     703      delete buf;
    622704    }
    623705    (*outputFunc)(outputStream, "currentdict end def\n", 20);
     
    628710  // start the binary section
    629711  offset = (nCIDs + 1) * (1 + gdBytes);
    630   sprintf(buf, "(Hex) %d StartData\n",
    631           offset + charStrings->getLength());
    632   (*outputFunc)(outputStream, buf, strlen(buf));
     712  buf = GooString::format("(Hex) {0:d} StartData\n",
     713                        offset + charStrings->getLength());
     714  (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     715  delete buf;
    633716
    634717  // write the charstring offset (CIDMap) table
     
    636719    for (j = 0; j < 6 && i+j <= nCIDs; ++j) {
    637720      if (i+j < nCIDs && cidMap[i+j] >= 0) {
    638         buf[0] = (char)fdSelect[cidMap[i+j]];
     721        buf2[0] = (char)fdSelect[cidMap[i+j]];
    639722      } else {
    640         buf[0] = (char)0;
     723        buf2[0] = (char)0;
    641724      }
    642725      n = offset + charStringOffsets[i+j];
    643726      for (k = gdBytes; k >= 1; --k) {
    644         buf[k] = (char)(n & 0xff);
     727        buf2[k] = (char)(n & 0xff);
    645728        n >>= 8;
    646729      }
    647730      for (k = 0; k <= gdBytes; ++k) {
    648         sprintf(buf2, "%02x", buf[k] & 0xff);
    649         (*outputFunc)(outputStream, buf2, 2);
     731        buf = GooString::format("{0:02x}", buf2[k] & 0xff);
     732        (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     733        delete buf;
    650734      }
    651735    }
     
    657741  for (i = 0; i < n; i += 32) {
    658742    for (j = 0; j < 32 && i+j < n; ++j) {
    659       sprintf(buf, "%02x", charStrings->getChar(i+j) & 0xff);
    660       (*outputFunc)(outputStream, buf, strlen(buf));
     743      buf = GooString::format("{0:02x}", charStrings->getChar(i+j) & 0xff);
     744      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     745      delete buf;
    661746    }
    662747    if (i + 32 >= n) {
     
    678763  Type1CIndexVal val;
    679764  int nCIDs;
    680   char buf[512];
     765  GooString *buf;
    681766  Type1CEexecBuf eb;
    682767  GBool ok;
     
    703788    //~ this assumes that all CIDs in this block have the same FD --
    704789    //~ to handle multiple FDs correctly, need to somehow divide the
    705     //~ font up by FD
     790    //~ font up by FD; as a kludge we ignore CID 0, which is .notdef
    706791    fd = 0;
    707     for (j = 0; j < 256 && i+j < nCIDs; ++j) {
     792    for (j = i==0 ? 1 : 0; j < 256 && i+j < nCIDs; ++j) {
    708793      if (cidMap[i+j] >= 0) {
    709794        fd = fdSelect[cidMap[i+j]];
     
    716801    (*outputFunc)(outputStream, "/FontName /", 11);
    717802    (*outputFunc)(outputStream, psName, strlen(psName));
    718     sprintf(buf, "_%02x def\n", i >> 8);
    719     (*outputFunc)(outputStream, buf, strlen(buf));
     803    buf = GooString::format("_{0:02x} def\n", i >> 8);
     804    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     805    delete buf;
    720806    (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
    721807    if (privateDicts[fd].hasFontMatrix) {
    722       sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
    723               privateDicts[fd].fontMatrix[0],
    724               privateDicts[fd].fontMatrix[1],
    725               privateDicts[fd].fontMatrix[2],
    726               privateDicts[fd].fontMatrix[3],
    727               privateDicts[fd].fontMatrix[4],
    728               privateDicts[fd].fontMatrix[5]);
    729       (*outputFunc)(outputStream, buf, strlen(buf));
     808      buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n",
     809                            privateDicts[fd].fontMatrix[0],
     810                            privateDicts[fd].fontMatrix[1],
     811                            privateDicts[fd].fontMatrix[2],
     812                            privateDicts[fd].fontMatrix[3],
     813                            privateDicts[fd].fontMatrix[4],
     814                            privateDicts[fd].fontMatrix[5]);
     815      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     816      delete buf;
    730817    } else if (topDict.hasFontMatrix) {
    731818      (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
     
    734821                    "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38);
    735822    }
    736     sprintf(buf, "/FontBBox [%g %g %g %g] def\n",
    737             topDict.fontBBox[0], topDict.fontBBox[1],
    738             topDict.fontBBox[2], topDict.fontBBox[3]);
    739     (*outputFunc)(outputStream, buf, strlen(buf));
    740     sprintf(buf, "/PaintType %d def\n", topDict.paintType);
    741     (*outputFunc)(outputStream, buf, strlen(buf));
     823    buf = GooString::format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] def\n",
     824                          topDict.fontBBox[0], topDict.fontBBox[1],
     825                          topDict.fontBBox[2], topDict.fontBBox[3]);
     826    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     827    delete buf;
     828    buf = GooString::format("/PaintType {0:d} def\n", topDict.paintType);
     829    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     830    delete buf;
    742831    if (topDict.paintType != 0) {
    743       sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
    744       (*outputFunc)(outputStream, buf, strlen(buf));
     832      buf = GooString::format("/StrokeWidth {0:.4g} def\n", topDict.strokeWidth);
     833      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     834      delete buf;
    745835    }
    746836    (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
    747837    for (j = 0; j < 256 && i+j < nCIDs; ++j) {
    748       sprintf(buf, "dup %d /c%02x put\n", j, j);
    749       (*outputFunc)(outputStream, buf, strlen(buf));
     838      buf = GooString::format("dup {0:d} /c{1:02x} put\n", j, j);
     839      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     840      delete buf;
    750841    }
    751842    if (j < 256) {
    752       sprintf(buf, "%d 1 255 { 1 index exch /.notdef put } for\n", j);
    753       (*outputFunc)(outputStream, buf, strlen(buf));
     843      buf = GooString::format("{0:d} 1 255 {{ 1 index exch /.notdef put }} for\n",
     844                            j);
     845      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     846      delete buf;
    754847    }
    755848    (*outputFunc)(outputStream, "readonly def\n", 13);
     
    776869      eexecWrite(&eb, "/BlueValues [");
    777870      for (k = 0; k < privateDicts[fd].nBlueValues; ++k) {
    778         sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].blueValues[k]);
    779         eexecWrite(&eb, buf);
     871        buf = GooString::format("{0:s}{1:d}",
     872                              k > 0 ? " " : "",
     873                              privateDicts[fd].blueValues[k]);
     874        eexecWrite(&eb, buf->getCString());
     875        delete buf;
    780876      }
    781877      eexecWrite(&eb, "] def\n");
     
    784880      eexecWrite(&eb, "/OtherBlues [");
    785881      for (k = 0; k < privateDicts[fd].nOtherBlues; ++k) {
    786         sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].otherBlues[k]);
    787         eexecWrite(&eb, buf);
     882        buf = GooString::format("{0:s}{1:d}",
     883                              k > 0 ? " " : "",
     884                              privateDicts[fd].otherBlues[k]);
     885        eexecWrite(&eb, buf->getCString());
     886        delete buf;
    788887      }
    789888      eexecWrite(&eb, "] def\n");
     
    792891      eexecWrite(&eb, "/FamilyBlues [");
    793892      for (k = 0; k < privateDicts[fd].nFamilyBlues; ++k) {
    794         sprintf(buf, "%s%d", k > 0 ? " " : "",
    795                 privateDicts[fd].familyBlues[k]);
    796         eexecWrite(&eb, buf);
     893        buf = GooString::format("{0:s}{1:d}", k > 0 ? " " : "",
     894                              privateDicts[fd].familyBlues[k]);
     895        eexecWrite(&eb, buf->getCString());
     896        delete buf;
    797897      }
    798898      eexecWrite(&eb, "] def\n");
     
    801901      eexecWrite(&eb, "/FamilyOtherBlues [");
    802902      for (k = 0; k < privateDicts[fd].nFamilyOtherBlues; ++k) {
    803         sprintf(buf, "%s%d", k > 0 ? " " : "",
    804                 privateDicts[fd].familyOtherBlues[k]);
    805         eexecWrite(&eb, buf);
     903        buf = GooString::format("{0:s}{1:d}", k > 0 ? " " : "",
     904                              privateDicts[fd].familyOtherBlues[k]);
     905        eexecWrite(&eb, buf->getCString());
     906        delete buf;
    806907      }
    807908      eexecWrite(&eb, "] def\n");
    808909    }
    809910    if (privateDicts[fd].blueScale != 0.039625) {
    810       sprintf(buf, "/BlueScale %g def\n", privateDicts[fd].blueScale);
    811       eexecWrite(&eb, buf);
     911      buf = GooString::format("/BlueScale {0:.4g} def\n",
     912                            privateDicts[fd].blueScale);
     913      eexecWrite(&eb, buf->getCString());
     914      delete buf;
    812915    }
    813916    if (privateDicts[fd].blueShift != 7) {
    814       sprintf(buf, "/BlueShift %d def\n", privateDicts[fd].blueShift);
    815       eexecWrite(&eb, buf);
     917      buf = GooString::format("/BlueShift {0:d} def\n",
     918                            privateDicts[fd].blueShift);
     919      eexecWrite(&eb, buf->getCString());
     920      delete buf;
    816921    }
    817922    if (privateDicts[fd].blueFuzz != 1) {
    818       sprintf(buf, "/BlueFuzz %d def\n", privateDicts[fd].blueFuzz);
    819       eexecWrite(&eb, buf);
     923      buf = GooString::format("/BlueFuzz {0:d} def\n",
     924                            privateDicts[fd].blueFuzz);
     925      eexecWrite(&eb, buf->getCString());
     926      delete buf;
    820927    }
    821928    if (privateDicts[fd].hasStdHW) {
    822       sprintf(buf, "/StdHW [%g] def\n", privateDicts[fd].stdHW);
    823       eexecWrite(&eb, buf);
     929      buf = GooString::format("/StdHW [{0:.4g}] def\n", privateDicts[fd].stdHW);
     930      eexecWrite(&eb, buf->getCString());
     931      delete buf;
    824932    }
    825933    if (privateDicts[fd].hasStdVW) {
    826       sprintf(buf, "/StdVW [%g] def\n", privateDicts[fd].stdVW);
    827       eexecWrite(&eb, buf);
     934      buf = GooString::format("/StdVW [{0:.4g}] def\n", privateDicts[fd].stdVW);
     935      eexecWrite(&eb, buf->getCString());
     936      delete buf;
    828937    }
    829938    if (privateDicts[fd].nStemSnapH) {
    830939      eexecWrite(&eb, "/StemSnapH [");
    831940      for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) {
    832         sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapH[k]);
    833         eexecWrite(&eb, buf);
     941        buf = GooString::format("{0:s}{1:.4g}",
     942                              k > 0 ? " " : "", privateDicts[fd].stemSnapH[k]);
     943        eexecWrite(&eb, buf->getCString());
     944        delete buf;
    834945      }
    835946      eexecWrite(&eb, "] def\n");
     
    838949      eexecWrite(&eb, "/StemSnapV [");
    839950      for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) {
    840         sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapV[k]);
    841         eexecWrite(&eb, buf);
     951        buf = GooString::format("{0:s}{1:.4g}",
     952                              k > 0 ? " " : "", privateDicts[fd].stemSnapV[k]);
     953        eexecWrite(&eb, buf->getCString());
     954        delete buf;
    842955      }
    843956      eexecWrite(&eb, "] def\n");
    844957    }
    845958    if (privateDicts[fd].hasForceBold) {
    846       sprintf(buf, "/ForceBold %s def\n",
    847               privateDicts[fd].forceBold ? "true" : "false");
    848       eexecWrite(&eb, buf);
     959      buf = GooString::format("/ForceBold {0:s} def\n",
     960                            privateDicts[fd].forceBold ? "true" : "false");
     961      eexecWrite(&eb, buf->getCString());
     962      delete buf;
    849963    }
    850964    if (privateDicts[fd].forceBoldThreshold != 0) {
    851       sprintf(buf, "/ForceBoldThreshold %g def\n",
    852               privateDicts[fd].forceBoldThreshold);
    853       eexecWrite(&eb, buf);
     965      buf = GooString::format("/ForceBoldThreshold {0:.4g} def\n",
     966                            privateDicts[fd].forceBoldThreshold);
     967      eexecWrite(&eb, buf->getCString());
     968      delete buf;
    854969    }
    855970    if (privateDicts[fd].languageGroup != 0) {
    856       sprintf(buf, "/LanguageGroup %d def\n", privateDicts[fd].languageGroup);
    857       eexecWrite(&eb, buf);
     971      buf = GooString::format("/LanguageGroup {0:d} def\n",
     972                            privateDicts[fd].languageGroup);
     973      eexecWrite(&eb, buf->getCString());
     974      delete buf;
    858975    }
    859976    if (privateDicts[fd].expansionFactor != 0.06) {
    860       sprintf(buf, "/ExpansionFactor %g def\n",
    861               privateDicts[fd].expansionFactor);
    862       eexecWrite(&eb, buf);
     977      buf = GooString::format("/ExpansionFactor {0:.4g} def\n",
     978                            privateDicts[fd].expansionFactor);
     979      eexecWrite(&eb, buf->getCString());
     980      delete buf;
    863981    }
    864982
     
    871989
    872990    // start the CharStrings
    873     sprintf(buf, "2 index /CharStrings 256 dict dup begin\n");
    874     eexecWrite(&eb, buf);
     991    eexecWrite(&eb, "2 index /CharStrings 256 dict dup begin\n");
    875992
    876993    // write the .notdef CharString
     
    8881005        getIndexVal(&charStringsIdx, cidMap[i+j], &val, &ok);
    8891006        if (ok) {
    890           sprintf(buf, "c%02x", j);
    891           eexecCvtGlyph(&eb, buf, val.pos, val.len,
     1007          buf = GooString::format("c{0:02x}", j);
     1008          eexecCvtGlyph(&eb, buf->getCString(), val.pos, val.len,
    8921009                        &subrIdx, &privateDicts[fd]);
     1010          delete buf;
    8931011        }
    8941012      }
     
    9181036  (*outputFunc)(outputStream, "/FontType 0 def\n", 16);
    9191037  if (topDict.hasFontMatrix) {
    920     sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
    921             topDict.fontMatrix[0], topDict.fontMatrix[1],
    922             topDict.fontMatrix[2], topDict.fontMatrix[3],
    923             topDict.fontMatrix[4], topDict.fontMatrix[5]);
    924     (*outputFunc)(outputStream, buf, strlen(buf));
     1038    buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n",
     1039                          topDict.fontMatrix[0], topDict.fontMatrix[1],
     1040                          topDict.fontMatrix[2], topDict.fontMatrix[3],
     1041                          topDict.fontMatrix[4], topDict.fontMatrix[5]);
     1042    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1043    delete buf;
    9251044  } else {
    9261045    (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
     
    9291048  (*outputFunc)(outputStream, "/Encoding [\n", 12);
    9301049  for (i = 0; i < nCIDs; i += 256) {
    931     sprintf(buf, "%d\n", i >> 8);
    932     (*outputFunc)(outputStream, buf, strlen(buf));
     1050    buf = GooString::format("{0:d}\n", i >> 8);
     1051    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1052    delete buf;
    9331053  }
    9341054  (*outputFunc)(outputStream, "] def\n", 6);
     
    9371057    (*outputFunc)(outputStream, "/", 1);
    9381058    (*outputFunc)(outputStream, psName, strlen(psName));
    939     sprintf(buf, "_%02x findfont\n", i >> 8);
    940     (*outputFunc)(outputStream, buf, strlen(buf));
     1059    buf = GooString::format("_{0:02x} findfont\n", i >> 8);
     1060    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
     1061    delete buf;
    9411062  }
    9421063  (*outputFunc)(outputStream, "] def\n", 6);
     
    9501071                               Type1CIndex *subrIdx,
    9511072                               Type1CPrivateDict *pDict) {
    952   char buf[512];
     1073  GooString *buf;
    9531074  GooString *charBuf;
    9541075
     
    9571078  cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue);
    9581079
    959   sprintf(buf, "/%s %d RD ", glyphName, charBuf->getLength());
    960   eexecWrite(eb, buf);
     1080  buf = GooString::format("/{0:s} {1:d} RD ", glyphName, charBuf->getLength());
     1081  eexecWrite(eb, buf->getCString());
     1082  delete buf;
    9611083  eexecWriteCharstring(eb, (Guchar *)charBuf->getCString(),
    9621084                       charBuf->getLength());
     
    19222044void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) {
    19232045  int pos, pSize, pOffset;
    1924   double fontMatrix[6];
     2046  double fontMatrix[6] = {0};
    19252047  GBool hasFontMatrix;
    19262048
     
    19362058    if (!ops[nOps - 1].isNum) {
    19372059      if (ops[nOps - 1].op == 0x0012) {
    1938         if (nOps < 3) {
    1939           parsedOk = gFalse;
    1940           return;
    1941         }
    1942         pSize = (int)ops[0].num;
    1943         pOffset = (int)ops[1].num;
    1944         break;
     2060        if (nOps < 3) {
     2061          parsedOk = gFalse;
     2062          return;
     2063        }
     2064        pSize = (int)ops[0].num;
     2065        pOffset = (int)ops[1].num;
     2066        break;
    19452067      } else if (ops[nOps - 1].op == 0x0c07) {
    1946         fontMatrix[0] = ops[0].num;
    1947         fontMatrix[1] = ops[1].num;
    1948         fontMatrix[2] = ops[2].num;
    1949         fontMatrix[3] = ops[3].num;
    1950         fontMatrix[4] = ops[4].num;
    1951         fontMatrix[5] = ops[5].num;
    1952         hasFontMatrix = gTrue;
     2068        fontMatrix[0] = ops[0].num;
     2069        fontMatrix[1] = ops[1].num;
     2070        fontMatrix[2] = ops[2].num;
     2071        fontMatrix[3] = ops[3].num;
     2072        fontMatrix[4] = ops[4].num;
     2073        fontMatrix[5] = ops[5].num;
     2074        hasFontMatrix = gTrue;
    19532075      }
    19542076      nOps = 0;
  • trunk/poppler/mypoppler/fofi/FoFiType1C.h

    r2 r250  
    139139  static FoFiType1C *load(char *fileName);
    140140
    141   FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
    142141  virtual ~FoFiType1C();
    143142
     
    157156  // not NULL, it will be used in place of the encoding in the Type 1C
    158157  // font.  If <ascii> is true the eexec section will be hex-encoded,
    159   // otherwise it will be left as binary data.
    160   void convertToType1(char **newEncoding, GBool ascii,
     158  // otherwise it will be left as binary data.  If <psName> is non-NULL,
     159  // it will be used as the PostScript font name.
     160  void convertToType1(char *psName, char **newEncoding, GBool ascii,
    161161                      FoFiOutputFunc outputFunc, void *outputStream);
    162162
     
    175175private:
    176176
     177  FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
    177178  void eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName,
    178179                     int offset, int nBytes,
Note: See TracChangeset for help on using the changeset viewer.