Ignore:
Timestamp:
Sep 7, 2012, 8:38:55 AM (9 years ago)
Author:
Silvan Scherrer
Message:

updated poppler to 0.20.3

File:
1 edited

Legend:

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

    r277 r515  
    1717// Copyright (C) 2007 Koji Otani <sho@bbr.jp>
    1818// Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
    19 // Copyright (C) 2008, 2009 Albert Astals Cid <aacid@kde.org>
     19// Copyright (C) 2008, 2009, 2012 Albert Astals Cid <aacid@kde.org>
    2020// Copyright (C) 2008 Tomas Are Haavet <tomasare@gmail.com>
     21// Copyright (C) 2012 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
     22// Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com>
    2123//
    2224// To see a description of the changes please see the Changelog file that
     
    3335#include <stdlib.h>
    3436#include <string.h>
     37#include <algorithm>
    3538#include "goo/gtypes.h"
    3639#include "goo/gmem.h"
     
    138141#define vertTag 0x76657274
    139142
    140 static int cmpTrueTypeLocaOffset(const void *p1, const void *p2) {
    141   TrueTypeLoca *loca1 = (TrueTypeLoca *)p1;
    142   TrueTypeLoca *loca2 = (TrueTypeLoca *)p2;
    143 
    144   if (loca1->origOffset == loca2->origOffset) {
    145     return loca1->idx - loca2->idx;
    146   }
    147   return loca1->origOffset - loca2->origOffset;
    148 }
    149 
    150 static int cmpTrueTypeLocaIdx(const void *p1, const void *p2) {
    151   TrueTypeLoca *loca1 = (TrueTypeLoca *)p1;
    152   TrueTypeLoca *loca2 = (TrueTypeLoca *)p2;
    153 
    154   return loca1->idx - loca2->idx;
    155 }
    156 
    157 static int cmpTrueTypeTableTag(const void *p1, const void *p2) {
    158   TrueTypeTable *tab1 = (TrueTypeTable *)p1;
    159   TrueTypeTable *tab2 = (TrueTypeTable *)p2;
    160 
    161   return (int)tab1->tag - (int)tab2->tag;
    162 }
     143struct cmpTrueTypeLocaOffsetFunctor {
     144  bool operator()(const TrueTypeLoca &loca1, const TrueTypeLoca &loca2) {
     145    if (loca1.origOffset == loca2.origOffset) {
     146      return loca1.idx < loca2.idx;
     147    }
     148    return loca1.origOffset < loca2.origOffset;
     149  }
     150};
     151
     152struct cmpTrueTypeLocaIdxFunctor {
     153  bool operator()(const TrueTypeLoca &loca1, const TrueTypeLoca &loca2) {
     154    return loca1.idx < loca2.idx;
     155  }
     156};
     157
     158struct cmpTrueTypeTableTagFunctor {
     159  bool operator()(const TrueTypeTable &tab1, const TrueTypeTable &tab2) {
     160    return tab1.tag < tab2.tag;
     161  }
     162};
    163163
    164164//------------------------------------------------------------------------
    165165
    166166struct T42Table {
    167   char *tag;                    // 4-byte tag
     167  const char *tag;              // 4-byte tag
    168168  GBool required;               // required by the TrueType spec?
    169169};
     
    195195// Glyph names in some arbitrary standard order that Apple uses for
    196196// their TrueType fonts.
    197 static char *macGlyphNames[258] = {
     197static const char *macGlyphNames[258] = {
    198198  ".notdef",        "null",           "CR",             "space",
    199199  "exclam",         "quotedbl",       "numbersign",     "dollar",
     
    233233  "trademark",      "acute",          "dieresis",       "notequal",
    234234  "AE",             "Oslash",         "infinity",       "plusminus",
    235   "lessequal",      "greaterequal",   "yen",            "mu1",
     235  "lessequal",      "greaterequal",   "yen",            "mu",
    236236  "partialdiff",    "summation",      "product",        "pi",
    237   "integral",       "ordfeminine",    "ordmasculine",   "Ohm",
     237  "integral",       "ordfeminine",    "ordmasculine",   "Omega",
    238238  "ae",             "oslash",         "questiondown",   "exclamdown",
    239239  "logicalnot",     "radical",        "florin",         "approxequal",
     
    341341}
    342342
    343 Gushort FoFiTrueType::mapCodeToGID(int i, Guint c) {
    344   Gushort gid;
     343int FoFiTrueType::mapCodeToGID(int i, Guint c) {
     344  int gid;
    345345  Guint segCnt, segEnd, segStart, segDelta, segOffset;
    346346  Guint cmapFirst, cmapLen;
     
    445445}
    446446
    447 Gushort *FoFiTrueType::getCIDToGIDMap(int *nCIDs) {
    448   FoFiType1C *ff;
    449   Gushort *map;
     447GBool FoFiTrueType::getCFFBlock(char **start, int *length) {
    450448  int i;
    451449
    452   *nCIDs = 0;
    453450  if (!openTypeCFF) {
    454     return NULL;
     451    return gFalse;
    455452  }
    456453  i = seekTable("CFF ");
    457454  if (!checkRegion(tables[i].offset, tables[i].len)) {
     455    return gFalse;
     456  }
     457  *start = (char *)file + tables[i].offset;
     458  *length = tables[i].len;
     459  return gTrue;
     460}
     461
     462int *FoFiTrueType::getCIDToGIDMap(int *nCIDs) {
     463  char *start;
     464  int length;
     465  FoFiType1C *ff;
     466  int *map;
     467
     468  *nCIDs = 0;
     469  if (!getCFFBlock(&start, &length)) {
    458470    return NULL;
    459471  }
    460   if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
    461                               tables[i].len))) {
     472  if (!(ff = FoFiType1C::make(start, length))) {
    462473    return NULL;
    463474  }
     
    491502}
    492503
     504void FoFiTrueType::getFontMatrix(double *mat) {
     505  char *start;
     506  int length;
     507  FoFiType1C *ff;
     508
     509  if (!getCFFBlock(&start, &length)) {
     510    return;
     511  }
     512  if (!(ff = FoFiType1C::make(start, length))) {
     513    return;
     514  }
     515  ff->getFontMatrix(mat);
     516  delete ff;
     517}
     518
    493519void FoFiTrueType::convertToType42(char *psName, char **encoding,
    494                                    Gushort *codeToGID,
     520                                   int *codeToGID,
    495521                                   FoFiOutputFunc outputFunc,
    496522                                   void *outputStream) {
    497523  GooString *buf;
     524  int maxUsedGlyph;
    498525  GBool ok;
    499526
     
    525552  cvtEncoding(encoding, outputFunc, outputStream);
    526553  cvtCharStrings(encoding, codeToGID, outputFunc, outputStream);
    527   cvtSfnts(outputFunc, outputStream, NULL, gFalse);
     554  cvtSfnts(outputFunc, outputStream, NULL, gFalse, &maxUsedGlyph);
    528555
    529556  // end the dictionary and define the font
     
    531558}
    532559
    533 void FoFiTrueType::convertToType1(char *psName, char **newEncoding,
     560void FoFiTrueType::convertToType1(char *psName, const char **newEncoding,
    534561                                  GBool ascii, FoFiOutputFunc outputFunc,
    535562                                  void *outputStream) {
     563  char *start;
     564  int length;
    536565  FoFiType1C *ff;
    537   int i;
    538 
    539   if (!openTypeCFF) {
     566
     567  if (!getCFFBlock(&start, &length)) {
    540568    return;
    541569  }
    542   i = seekTable("CFF ");
    543   if (!checkRegion(tables[i].offset, tables[i].len)) {
    544     return;
    545   }
    546   if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
    547                               tables[i].len))) {
     570  if (!(ff = FoFiType1C::make(start, length))) {
    548571    return;
    549572  }
     
    553576
    554577void FoFiTrueType::convertToCIDType2(char *psName,
    555                                      Gushort *cidMap, int nCIDs,
     578                                     int *cidMap, int nCIDs,
    556579                                     GBool needVerticalMetrics,
    557580                                     FoFiOutputFunc outputFunc,
    558581                                     void *outputStream) {
    559582  GooString *buf;
    560   Gushort cid;
     583  int cid, maxUsedGlyph;
    561584  GBool ok;
    562585  int i, j, k;
     
    674697
    675698  // write the guts of the dictionary
    676   cvtSfnts(outputFunc, outputStream, NULL, needVerticalMetrics);
     699  cvtSfnts(outputFunc, outputStream, NULL, needVerticalMetrics, &maxUsedGlyph);
    677700
    678701  // end the dictionary and define the font
     
    682705}
    683706
    684 void FoFiTrueType::convertToCIDType0(char *psName,
     707void FoFiTrueType::convertToCIDType0(char *psName, int *cidMap, int nCIDs,
    685708                                     FoFiOutputFunc outputFunc,
    686709                                     void *outputStream) {
     710  char *start;
     711  int length;
    687712  FoFiType1C *ff;
    688   int i;
    689 
    690   if (!openTypeCFF) {
     713
     714  if (!getCFFBlock(&start, &length)) {
    691715    return;
    692716  }
    693   i = seekTable("CFF ");
    694   if (!checkRegion(tables[i].offset, tables[i].len)) {
     717  if (!(ff = FoFiType1C::make(start, length))) {
    695718    return;
    696719  }
    697   if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
    698                               tables[i].len))) {
    699     return;
    700   }
    701   ff->convertToCIDType0(psName, outputFunc, outputStream);
     720  ff->convertToCIDType0(psName, cidMap, nCIDs, outputFunc, outputStream);
    702721  delete ff;
    703722}
    704723
    705 void FoFiTrueType::convertToType0(char *psName, Gushort *cidMap, int nCIDs,
     724void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs,
    706725                                  GBool needVerticalMetrics,
    707726                                  FoFiOutputFunc outputFunc,
     
    709728  GooString *buf;
    710729  GooString *sfntsName;
    711   int n, i, j;
     730  int maxUsedGlyph, n, i, j;
    712731
    713732  if (openTypeCFF) {
     
    717736  // write the Type 42 sfnts array
    718737  sfntsName = (new GooString(psName))->append("_sfnts");
    719   cvtSfnts(outputFunc, outputStream, sfntsName, needVerticalMetrics);
     738  cvtSfnts(outputFunc, outputStream, sfntsName, needVerticalMetrics,
     739           &maxUsedGlyph);
    720740  delete sfntsName;
    721741
    722742  // write the descendant Type 42 fonts
    723   n = cidMap ? nCIDs : nGlyphs;
     743  // (The following is a kludge: nGlyphs is the glyph count from the
     744  // maxp table; maxUsedGlyph is the max glyph number that has a
     745  // non-zero-length description, from the loca table.  The problem is
     746  // that some TrueType font subsets fail to change the glyph count,
     747  // i.e., nGlyphs is much larger than maxUsedGlyph+1, which results
     748  // in an unnecessarily huge Type 0 font.  But some other PDF files
     749  // have fonts with only zero or one used glyph, and a content stream
     750  // that refers to one of the unused glyphs -- this results in PS
     751  // errors if we simply use maxUsedGlyph+1 for the Type 0 font.  So
     752  // we compromise by always defining at least 256 glyphs.)
     753  if (cidMap) {
     754    n = nCIDs;
     755  } else if (nGlyphs > maxUsedGlyph + 256) {
     756    if (maxUsedGlyph <= 255) {
     757      n = 256;
     758    } else {
     759      n = maxUsedGlyph + 1;
     760    }
     761  } else {
     762    n = nGlyphs;
     763  }
    724764  for (i = 0; i < n; i += 256) {
    725765    (*outputFunc)(outputStream, "10 dict begin\n", 14);
     
    786826}
    787827
    788 void FoFiTrueType::convertToType0(char *psName,
     828void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs,
    789829                                  FoFiOutputFunc outputFunc,
    790830                                  void *outputStream) {
     831  char *start;
     832  int length;
    791833  FoFiType1C *ff;
    792   int i;
    793 
    794   if (!openTypeCFF) {
     834
     835  if (!getCFFBlock(&start, &length)) {
    795836    return;
    796837  }
    797   i = seekTable("CFF ");
    798   if (!checkRegion(tables[i].offset, tables[i].len)) {
     838  if (!(ff = FoFiType1C::make(start, length))) {
    799839    return;
    800840  }
    801   if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
    802                               tables[i].len))) {
    803     return;
    804   }
    805   ff->convertToType0(psName, outputFunc, outputStream);
     841  ff->convertToType0(psName, cidMap, nCIDs, outputFunc, outputStream);
    806842  delete ff;
    807843}
     
    809845void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
    810846                            void *outputStream, char *name,
    811                             Gushort *codeToGID) {
    812   // this substitute cmap table maps char codes 0000-ffff directly to
    813   // glyphs 0000-ffff
    814   static char cmapTab[36] = {
     847                            int *codeToGID) {
     848  // this substitute cmap table maps char code ffff to glyph 0,
     849  // with tables for MacRoman and MS Unicode
     850  static char cmapTab[44] = {
    815851    0, 0,                       // table version number
    816     0, 1,                       // number of encoding tables
     852    0, 2,                       // number of encoding tables
    817853    0, 1,                       // platform ID
    818854    0, 0,                       // encoding ID
    819     0, 0, 0, 12,                // offset of subtable
     855    0, 0, 0, 20,                // offset of subtable
     856    0, 3,                       // platform ID
     857    0, 1,                       // encoding ID
     858    0, 0, 0, 20,                // offset of subtable
    820859    0, 4,                       // subtable format
    821860    0, 24,                      // subtable length
     
    827866    (char)0xff, (char)0xff,     // endCount[0]
    828867    0, 0,                       // reserved
    829     0, 0,                       // startCount[0]
    830     0, 0,                       // idDelta[0]
    831     0, 0                        // pad to a mulitple of four bytes
     868    (char)0xff, (char)0xff,     // startCount[0]
     869    0, 1,                       // idDelta[0]
     870    0, 0                        // idRangeOffset[0]
    832871  };
    833872  static char nameTab[8] = {
     
    851890    0, 1,                       // version
    852891    0, 1,                       // xAvgCharWidth
    853     0, 0,                       // usWeightClass
    854     0, 0,                       // usWidthClass
     892    0x01, (char)0x90,           // usWeightClass
     893    0, 5,                       // usWidthClass
    855894    0, 0,                       // fsType
    856895    0, 0,                       // ySubscriptXSize
     
    878917    0, 0,                       // sTypoDescender
    879918    0, 0,                       // sTypoLineGap
    880     0, 0,                       // usWinAscent
    881     0, 0,                       // usWinDescent
    882     0, 0, 0, 0,                 // ulCodePageRange1
     919    0x20, 0x00,                 // usWinAscent
     920    0x20, 0x00,                 // usWinDescent
     921    0, 0, 0, 1,                 // ulCodePageRange1
    883922    0, 0, 0, 0                  // ulCodePageRange2
    884923  };
    885924  GBool missingCmap, missingName, missingPost, missingOS2;
    886   GBool unsortedLoca, badCmapLen, abbrevHMTX;
    887   int nZeroLengthTables;
     925  GBool unsortedLoca, emptyCmap, badCmapLen, abbrevHMTX;
     926  int nZeroLengthTables, nBogusTables;
    888927  int nHMetrics, advWidth, lsb;
    889928  TrueTypeLoca *locaTable;
     
    949988  }
    950989
    951   // check for zero-length tables
    952   nZeroLengthTables = 0;
     990  // check for zero-length tables and bogus tags
     991  nZeroLengthTables = nBogusTables = 0;
    953992  for (i = 0; i < nTables; ++i) {
    954993    if (tables[i].len == 0) {
    955994      ++nZeroLengthTables;
    956     }
    957   }
    958 
    959   // check for an incorrect cmap table length
    960   badCmapLen = gFalse;
     995      if (tables[i].tag == cmapTag) {
     996        missingCmap = gTrue;
     997      } else if (tables[i].tag == nameTag) {
     998        missingName = gTrue;
     999      } else if (tables[i].tag == postTag) {
     1000        missingPost = gTrue;
     1001      } else if (tables[i].tag == os2Tag) {
     1002        missingOS2 = gTrue;
     1003      }
     1004    } else if (!(tables[i].tag & 0xe0000000) ||
     1005               !(tables[i].tag & 0x00e00000) ||
     1006               !(tables[i].tag & 0x0000e000) ||
     1007               !(tables[i].tag & 0x000000e0)) {
     1008      // tags where any of the bytes are < 0x20 are probably bogus
     1009      // (the TrueType spec uses ASCII sequences for tags) -- this
     1010      // catches problems where the number of tables given in the
     1011      // header is too large, and so gibberish data is read at the end
     1012      // of the table directory
     1013      ++nBogusTables;
     1014    }
     1015  }
     1016
     1017  // check for an empty cmap table or an incorrect cmap table length
     1018  emptyCmap = badCmapLen = gFalse;
    9611019  cmapLen = 0; // make gcc happy
    9621020  if (!missingCmap) {
    963     if (nCmaps > 0) {
     1021    if (nCmaps == 0) {
     1022      emptyCmap = gTrue;
     1023    } else {
    9641024      cmapLen = cmaps[0].offset + cmaps[0].len;
    9651025      for (i = 1; i < nCmaps; ++i) {
    966         if (cmaps[i].offset + cmaps[i].len > cmapLen) {
     1026        if (cmaps[i].offset + cmaps[i].len > cmapLen) {
    9671027          cmapLen = cmaps[i].offset + cmaps[i].len;
    968         }
    969       }
    970     }
    971     cmapLen -= tables[cmapIdx].offset;
    972     if (cmapLen > tables[cmapIdx].len) {
    973       badCmapLen = gTrue;
     1028        }
     1029      }
     1030      cmapLen -= tables[cmapIdx].offset;
     1031      if (cmapLen > tables[cmapIdx].len) {
     1032        badCmapLen = gTrue;
     1033      }
    9741034    }
    9751035  }
     
    9841044  // if nothing is broken, just write the TTF file as is
    9851045  if (!missingCmap && !missingName && !missingPost && !missingOS2 &&
    986       !unsortedLoca && !badCmapLen && !abbrevHMTX && nZeroLengthTables == 0 &&
     1046      !unsortedLoca && !emptyCmap && !badCmapLen && !abbrevHMTX &&
     1047      nZeroLengthTables == 0 && nBogusTables == 0 &&
    9871048      !name && !codeToGID) {
    9881049    (*outputFunc)(outputStream, (char *)file, len);
     
    9981059  glyfLen = 0; // make gcc happy
    9991060  if (unsortedLoca) {
    1000     qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
    1001           &cmpTrueTypeLocaOffset);
     1061    std::sort(locaTable, locaTable + nGlyphs + 1,
     1062              cmpTrueTypeLocaOffsetFunctor());
    10021063    for (i = 0; i < nGlyphs; ++i) {
    10031064      locaTable[i].len = locaTable[i+1].origOffset - locaTable[i].origOffset;
    10041065    }
    10051066    locaTable[nGlyphs].len = 0;
    1006     qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
    1007           &cmpTrueTypeLocaIdx);
     1067    std::sort(locaTable, locaTable + nGlyphs + 1, cmpTrueTypeLocaIdxFunctor());
     1068    // if the last entry in the loca is not the max offset (size of
     1069    // the glyf table), something is wrong -- work around the problem
     1070    // by forcing the last sorted entry to have a zero length
     1071    locaTable[nGlyphs].len = 0;
    10081072    pos = 0;
    10091073    for (i = 0; i <= nGlyphs; ++i) {
     
    11351199    newCmapTab[43] = 0;
    11361200    for (i = 0; i < 256; ++i) {
    1137       newCmapTab[44 + 2*i] = codeToGID[i] >> 8;
    1138       newCmapTab[44 + 2*i + 1] = codeToGID[i] & 0xff;
     1201      if (codeToGID[i] < 0) {
     1202        //~ this may not be correct - we want this character to never be
     1203        //~ displayed, but mapping it to the notdef glyph may result in
     1204        //~ little boxes being displayed
     1205        newCmapTab[44 + 2*i] = 0;
     1206        newCmapTab[44 + 2*i + 1] = 0;
     1207      } else {
     1208        newCmapTab[44 + 2*i] = codeToGID[i] >> 8;
     1209        newCmapTab[44 + 2*i + 1] = codeToGID[i] & 0xff;
     1210      }
    11391211    }
    11401212  } else {
     
    11881260  // - compute new table positions, including 4-byte alignment
    11891261  // - (re)compute table checksums
    1190   nNewTables = nTables - nZeroLengthTables +
     1262  nNewTables = nTables - nZeroLengthTables - nBogusTables +
    11911263               (missingCmap ? 1 : 0) + (missingName ? 1 : 0) +
    11921264               (missingPost ? 1 : 0) + (missingOS2 ? 1 : 0);
     
    11941266  j = 0;
    11951267  for (i = 0; i < nTables; ++i) {
    1196     if (tables[i].len > 0) {
     1268    if (tables[i].len > 0 &&
     1269        (tables[i].tag & 0xe0000000) &&
     1270        (tables[i].tag & 0x00e00000) &&
     1271        (tables[i].tag & 0x0000e000) &&
     1272        (tables[i].tag & 0x000000e0)) {
    11971273      newTables[j] = tables[i];
    11981274      newTables[j].origOffset = tables[i].offset;
    1199       if (checkRegion(tables[i].offset, newTables[i].len)) {
     1275      if (checkRegion(tables[i].offset, tables[i].len)) {
    12001276        newTables[j].checksum =
    12011277            computeTableChecksum(file + tables[i].offset, tables[i].len);
     
    12091285        newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
    12101286                                                     newCmapLen);
     1287      } else if (newTables[j].tag == cmapTag && emptyCmap) {
     1288        newTables[j].checksum = computeTableChecksum((Guchar *)cmapTab,
     1289                                                     sizeof(cmapTab));
     1290        newTables[j].len = sizeof(cmapTab);
    12111291      } else if (newTables[j].tag == cmapTag && badCmapLen) {
    12121292        newTables[j].len = cmapLen;
     
    12731353    ++j;
    12741354  }
    1275   qsort(newTables, nNewTables, sizeof(TrueTypeTable),
    1276         &cmpTrueTypeTableTag);
     1355  std::sort(newTables, newTables + nNewTables, cmpTrueTypeTableTagFunctor());
    12771356  pos = 12 + nNewTables * 16;
    12781357  for (i = 0; i < nNewTables; ++i) {
     
    14251504                               FoFiOutputFunc outputFunc,
    14261505                               void *outputStream) {
    1427   char *name;
     1506  const char *name;
    14281507  GooString *buf;
    14291508  int i;
     
    14521531
    14531532void FoFiTrueType::cvtCharStrings(char **encoding,
    1454                                   Gushort *codeToGID,
     1533                                  int *codeToGID,
    14551534                                  FoFiOutputFunc outputFunc,
    14561535                                  void *outputStream) {
     
    15051584void FoFiTrueType::cvtSfnts(FoFiOutputFunc outputFunc,
    15061585                            void *outputStream, GooString *name,
    1507                             GBool needVerticalMetrics) {
     1586                            GBool needVerticalMetrics,
     1587                            int *maxUsedGlyph) {
    15081588  Guchar headData[54];
    15091589  TrueTypeLoca *locaTable;
     
    15141594  Guint checksum;
    15151595  int nNewTables;
    1516   int length, pos, glyfPos, i, j, k;
     1596  int glyfTableLen, length, pos, glyfPos, i, j, k;
    15171597  Guchar vheaTab[36] = {
    15181598    0, 1, 0, 0,                 // table version number
     
    15501630  headData[8] = headData[9] = headData[10] = headData[11] = (Guchar)0;
    15511631
     1632  // check for a bogus loca format field in the 'head' table
     1633  // (I've encountered fonts with loca format set to 0x0100 instead of 0x0001)
     1634  if (locaFmt != 0 && locaFmt != 1) {
     1635    headData[50] = 0;
     1636    headData[51] = 1;
     1637  }
     1638
    15521639  // read the original 'loca' table, pad entries out to 4 bytes, and
    15531640  // sort it into proper order -- some (non-compliant) fonts have
    15541641  // out-of-order loca tables; in order to correctly handle the case
    15551642  // where (compliant) fonts have empty entries in the middle of the
    1556   // table, cmpTrueTypeLocaPos uses offset as its primary sort key,
     1643  // table, cmpTrueTypeLocaOffset uses offset as its primary sort key,
    15571644  // and idx as its secondary key (ensuring that adjacent entries with
    15581645  // the same pos value remain in the same order)
     
    15601647  i = seekTable("loca");
    15611648  pos = tables[i].offset;
     1649  i = seekTable("glyf");
     1650  glyfTableLen = tables[i].len;
    15621651  ok = gTrue;
    15631652  for (i = 0; i <= nGlyphs; ++i) {
     
    15681657      locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
    15691658    }
    1570   }
    1571   qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
    1572         &cmpTrueTypeLocaOffset);
     1659    if (locaTable[i].origOffset > glyfTableLen) {
     1660      locaTable[i].origOffset = glyfTableLen;
     1661    }
     1662  }
     1663  std::sort(locaTable, locaTable + nGlyphs + 1,
     1664            cmpTrueTypeLocaOffsetFunctor());
    15731665  for (i = 0; i < nGlyphs; ++i) {
    15741666    locaTable[i].len = locaTable[i+1].origOffset - locaTable[i].origOffset;
    15751667  }
    15761668  locaTable[nGlyphs].len = 0;
    1577   qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
    1578         &cmpTrueTypeLocaIdx);
     1669  std::sort(locaTable, locaTable + nGlyphs + 1, cmpTrueTypeLocaIdxFunctor());
    15791670  pos = 0;
     1671  *maxUsedGlyph = -1;
    15801672  for (i = 0; i <= nGlyphs; ++i) {
    15811673    locaTable[i].newOffset = pos;
     
    15831675    if (pos & 3) {
    15841676      pos += 4 - (pos & 3);
     1677    }
     1678    if (locaTable[i].len > 0) {
     1679      *maxUsedGlyph = i;
    15851680    }
    15861681  }
     
    16661761        checksum = computeTableChecksum(vheaTab, length);
    16671762      } else if (needVerticalMetrics && i == t42VmtxTable) {
    1668         length = 4 + (nGlyphs - 1) * 4;
     1763        length = 4 + (nGlyphs - 1) * 2;
    16691764        vmtxTab = (Guchar *)gmalloc(length);
    16701765        vmtxTab[0] = advance / 256;
     
    17841879        } else if (needVerticalMetrics && i == t42VmtxTable) {
    17851880          dumpString(vmtxTab, length, outputFunc, outputStream);
    1786           gfree(vmtxTab);
    17871881        }
    17881882      }
     
    17951889  gfree(locaData);
    17961890  gfree(locaTable);
     1891  if (vmtxTab) {
     1892    gfree(vmtxTab);
     1893  }
    17971894}
    17981895
     
    19011998  tables = (TrueTypeTable *)gmallocn(nTables, sizeof(TrueTypeTable));
    19021999  pos += 12;
    1903   int wrongTables = 0;
     2000  j = 0;
    19042001  for (i = 0; i < nTables; ++i) {
    1905     tables[i].tag = getU32BE(pos, &parsedOk);
    1906     tables[i].checksum = getU32BE(pos + 4, &parsedOk);
    1907     tables[i].offset = (int)getU32BE(pos + 8, &parsedOk);
    1908     tables[i].len = (int)getU32BE(pos + 12, &parsedOk);
    1909     if (tables[i].offset + tables[i].len < tables[i].offset ||
    1910         tables[i].offset + tables[i].len > len) {
    1911       i--;
    1912       wrongTables++;
    1913       error(-1, "Found a bad table definition on true type definition, trying to continue...");
     2002    tables[j].tag = getU32BE(pos, &parsedOk);
     2003    tables[j].checksum = getU32BE(pos + 4, &parsedOk);
     2004    tables[j].offset = (int)getU32BE(pos + 8, &parsedOk);
     2005    tables[j].len = (int)getU32BE(pos + 12, &parsedOk);
     2006    if (tables[j].offset + tables[j].len >= tables[j].offset &&
     2007        tables[j].offset + tables[j].len <= len) {
     2008      // ignore any bogus entries in the table directory
     2009      ++j;
    19142010    }
    19152011    pos += 16;
    19162012  }
    1917   nTables -= wrongTables;
    1918   tables = (TrueTypeTable *)greallocn_checkoverflow(tables, nTables, sizeof(TrueTypeTable));
     2013  if (nTables != j) {
     2014    nTables = j;
     2015    tables = (TrueTypeTable *)greallocn_checkoverflow(tables, nTables, sizeof(TrueTypeTable));
     2016  }
    19192017  if (!parsedOk || tables == NULL) {
    19202018    return;
     
    20862184}
    20872185
    2088 int FoFiTrueType::seekTable(char *tag) {
     2186int FoFiTrueType::seekTable(const char *tag) {
    20892187  Guint tagI;
    20902188  int i;
     
    21242222  Only supporting vertical text substitution.
    21252223*/
    2126 int FoFiTrueType::setupGSUB(const char *tagName)
     2224int FoFiTrueType::setupGSUB(const char *scriptName)
     2225{
     2226  return setupGSUB(scriptName, NULL);
     2227}
     2228
     2229/*
     2230  setup GSUB table data
     2231  Only supporting vertical text substitution.
     2232*/
     2233int FoFiTrueType::setupGSUB(const char *scriptName,
     2234                            const char *languageName)
    21272235{
    21282236  Guint gsubTable;
     
    21412249  Guint pos;
    21422250
    2143   if (tagName == 0) {
     2251  if (scriptName == 0) {
    21442252    gsubFeatureTable = 0;
    21452253    return 0;
    21462254  }
    2147   scriptTag = charToTag(tagName);
     2255  scriptTag = charToTag(scriptName);
    21482256  /* read GSUB Header */
    21492257  if ((x = seekTable("GSUB")) < 0) {
     
    21822290  /* use default language system */
    21832291  pos = gsubTable+scriptList+scriptTable;
    2184   langSys = getU16BE(pos,&parsedOk);/* default language system */
     2292  langSys = 0;
     2293  if (languageName) {
     2294    Guint langTag = charToTag(languageName);
     2295    Guint langCount = getU16BE(pos+2,&parsedOk);
     2296    for (i = 0;i < langCount && langSys == 0;i++) {
     2297      tag = getU32BE(pos+4+i*(4+2),&parsedOk);
     2298      if (tag == langTag) {
     2299        langSys = getU16BE(pos+4+i*(4+2)+4,&parsedOk);
     2300      }
     2301    }
     2302  }
     2303  if (langSys == 0) {
     2304    /* default language system */
     2305    langSys = getU16BE(pos,&parsedOk);
     2306  }
    21852307
    21862308  /* read LangSys table */
    21872309  if (langSys == 0) {
    2188     /* no ldefault LangSys */
     2310    /* no default LangSys */
    21892311    return 0;
    21902312  }
     
    23582480    count = getU16BE(pos,&parsedOk);
    23592481    pos += 2;
     2482    // In some poor CJK fonts, key GIDs are not sorted,
     2483    // thus we cannot finish checking even when the range
     2484    // including orgGID seems to have already passed.
    23602485    for (i = 0;i < count;i++) {
    23612486      Guint gid;
     
    23662491        /* found */
    23672492        index = i;
    2368         break;
    2369       } else if (gid > orgGID) {
    2370         /* not found */
    23712493        break;
    23722494      }
     
    23862508      startIndex = getU16BE(pos,&parsedOk);
    23872509      pos += 2;
     2510      // In some poor CJK fonts, key GIDs are not sorted,
     2511      // thus we cannot finish checking even when the range
     2512      // including orgGID seems to have already passed.
    23882513      if (startGID <= orgGID && orgGID <= endGID) {
    23892514        /* found */
    23902515        index = startIndex+orgGID-startGID;
    23912516        break;
    2392       } else if (orgGID <= endGID) {
    2393         /* not found */
    2394         break;
    23952517      }
    23962518    }
Note: See TracChangeset for help on using the changeset viewer.