~ubuntu-branches/ubuntu/intrepid/poppler/intrepid-security

« back to all changes in this revision

Viewing changes to poppler/GfxFont.cc

  • Committer: Bazaar Package Importer
  • Author(s): Loic Minier
  • Date: 2008-05-15 12:33:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080515123318-4ou7y7oa1wz54f3u
Tags: 0.8.2-2
* Upload to unstable.
* Set myself as Maintainer instead of Uploader, taking over from Ondřej Surý
  but I wish we move to an official team; closes: #481323.

Show diffs side-by-side

added added

removed removed

Lines of Context:
96
96
  { "TimesNewRomanPSMT,Italic",     "Times-Italic" }
97
97
};
98
98
 
 
99
static int parseCharName(char *charName, Unicode *uBuf, int uLen,
 
100
                         GBool names, GBool ligatures, 
 
101
                         GBool numeric, GBool hex, GBool variants);
 
102
 
99
103
//------------------------------------------------------------------------
100
104
// GfxFont
101
105
//------------------------------------------------------------------------
404
408
    error(-1, "External font file '%s' vanished", extFontFile->getCString());
405
409
    return NULL;
406
410
  }
407
 
  fseek(f, 0, SEEK_END);
 
411
  if (fseek(f, 0, SEEK_END) != 0) {
 
412
    error(-1, "Cannot seek to end of '%s'", extFontFile->getCString());
 
413
    fclose(f);
 
414
    return NULL;
 
415
  }
408
416
  *len = (int)ftell(f);
409
 
  fseek(f, 0, SEEK_SET);
 
417
  if (fseek(f, 0, SEEK_SET) != 0) {
 
418
    error(-1, "Cannot seek to start of '%s'", extFontFile->getCString());
 
419
    fclose(f);
 
420
    return NULL;
 
421
  }
410
422
  buf = (char *)gmalloc(*len);
411
423
  if ((int)fread(buf, 1, *len, f) != *len) {
412
424
    error(-1, "Error reading external font file '%s'",
787
799
    }
788
800
  }
789
801
 
790
 
  // pass 2: try to fill in the missing chars, looking for names of
791
 
  // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'
792
 
  // are any letters, 'xx' is two hex digits, and 'nn' is 2-4
793
 
  // decimal digits
794
 
  if (missing && globalParams->getMapNumericCharNames()) {
795
 
    for (code = 0; code < 256; ++code) {
796
 
      if ((charName = enc[code]) && !toUnicode[code] &&
797
 
          strcmp(charName, ".notdef")) {
798
 
        n = strlen(charName);
799
 
        code2 = -1;
800
 
        if (hex && n == 3 && isalpha(charName[0]) &&
801
 
            isxdigit(charName[1]) && isxdigit(charName[2])) {
802
 
          sscanf(charName+1, "%x", &code2);
803
 
        } else if (hex && n == 2 &&
804
 
                   isxdigit(charName[0]) && isxdigit(charName[1])) {
805
 
          sscanf(charName, "%x", &code2);
806
 
        } else if (!hex && n >= 2 && n <= 4 &&
807
 
                   isdigit(charName[0]) && isdigit(charName[1])) {
808
 
          code2 = atoi(charName);
809
 
        } else if (n >= 3 && n <= 5 &&
810
 
                   isdigit(charName[1]) && isdigit(charName[2])) {
811
 
          code2 = atoi(charName+1);
812
 
        } else if (n >= 4 && n <= 6 &&
813
 
                   isdigit(charName[2]) && isdigit(charName[3])) {
814
 
          code2 = atoi(charName+2);
815
 
        }
816
 
        if (code2 >= 0 && code2 <= 0xff) {
817
 
          toUnicode[code] = (Unicode)code2;
818
 
        }
819
 
      }
820
 
    }
821
 
 
822
 
  // if the 'mapUnknownCharNames' flag is set, do a simple pass-through
823
 
  // mapping for unknown character names
824
 
  } else if (missing && globalParams->getMapUnknownCharNames()) {
825
 
    for (code = 0; code < 256; ++code) {
826
 
      if (!toUnicode[code]) {
827
 
        toUnicode[code] = code;
828
 
      }
829
 
    }
830
 
  }
831
 
 
832
802
  // construct the char code -> Unicode mapping object
833
803
  ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode);
834
804
 
 
805
  // pass 2: try to fill in the missing chars, looking for ligatures, numeric
 
806
  // references and variants
 
807
  if (missing) {
 
808
    for (code = 0; code < 256; ++code) {
 
809
      if (!toUnicode[code]) {
 
810
        if ((charName = enc[code]) && strcmp(charName, ".notdef")
 
811
            && (n = parseCharName(charName, uBuf, sizeof(uBuf)/sizeof(*uBuf), 
 
812
                                  gFalse, // don't check simple names (pass 1)
 
813
                                  gTrue, // do check ligatures
 
814
                                  globalParams->getMapNumericCharNames(),
 
815
                                  hex,
 
816
                                  gTrue))) { // do check variants
 
817
          ctu->setMapping((CharCode)code, uBuf, n);
 
818
        } else if (globalParams->getMapUnknownCharNames()) {
 
819
          // if the 'mapUnknownCharNames' flag is set, do a simple pass-through
 
820
          // mapping for unknown character names
 
821
          if (charName && charName[0]) {
 
822
            for (n = 0; n < sizeof(uBuf)/sizeof(*uBuf); ++n)
 
823
              if (!(uBuf[n] = charName[n]))
 
824
                break;
 
825
            ctu->setMapping((CharCode)code, uBuf, n);
 
826
          } else {
 
827
            uBuf[0] = code;
 
828
            ctu->setMapping((CharCode)code, uBuf, 1);
 
829
          }
 
830
        }
 
831
      }
 
832
    }
 
833
  }
 
834
 
835
835
  // merge in a ToUnicode CMap, if there is one -- this overwrites
836
836
  // existing entries in ctu, i.e., the ToUnicode CMap takes
837
837
  // precedence, but the other encoding info is allowed to fill in any
961
961
  }
962
962
}
963
963
 
 
964
// This function is in part a derived work of the Adobe Glyph Mapping
 
965
// Convention: http://www.adobe.com/devnet/opentype/archives/glyph.html
 
966
// Algorithmic comments are excerpted from that document to aid
 
967
// maintainability.
 
968
static int parseCharName(char *charName, Unicode *uBuf, int uLen,
 
969
                         GBool names, GBool ligatures,
 
970
                         GBool numeric, GBool hex, GBool variants)
 
971
{
 
972
  if (uLen <= 0) {
 
973
    error(-1, "Zero-length output buffer (recursion overflow?) in "
 
974
          "parseCharName, component \"%s\"", charName);
 
975
    return 0;
 
976
  }
 
977
  // Step 1: drop all the characters from the glyph name starting with the
 
978
  // first occurrence of a period (U+002E FULL STOP), if any.
 
979
  if (variants) {
 
980
    char *var_part = strchr(charName, '.');
 
981
    if (var_part == charName) {
 
982
      return 0; // .notdef or similar
 
983
    } else if (var_part != NULL) {
 
984
      // parse names of the form 7.oldstyle, P.swash, s.sc, etc.
 
985
      char *main_part = gstrndup(charName, var_part - charName);
 
986
      GBool namesRecurse = gTrue, variantsRecurse = gFalse;
 
987
      int n = parseCharName(main_part, uBuf, uLen, namesRecurse, ligatures,
 
988
                            numeric, hex, variantsRecurse);
 
989
      gfree(main_part);
 
990
      return n;
 
991
    }
 
992
  }
 
993
  // Step 2: split the remaining string into a sequence of components, using
 
994
  // underscore (U+005F LOW LINE) as the delimiter.
 
995
  if (ligatures && strchr(charName, '_')) {
 
996
    // parse names of the form A_a (e.g. f_i, T_h, l_quotesingle)
 
997
    char *lig_part, *lig_end, *lig_copy;
 
998
    int n = 0, m;
 
999
    lig_part = lig_copy = copyString(charName);
 
1000
    do {
 
1001
      if ((lig_end = strchr(lig_part, '_')))
 
1002
        *lig_end = '\0';
 
1003
      if (lig_part[0] != '\0') {
 
1004
        GBool namesRecurse = gTrue, ligaturesRecurse = gFalse;
 
1005
        if ((m = parseCharName(lig_part, uBuf + n, uLen - n, namesRecurse,
 
1006
                               ligaturesRecurse, numeric, hex, variants)))
 
1007
          n += m;
 
1008
        else
 
1009
          error(-1, "Could not parse ligature component \"%s\" of \"%s\" in "
 
1010
                "parseCharName", lig_part, charName);
 
1011
      }
 
1012
      lig_part = lig_end + 1;
 
1013
    } while (lig_end && n < uLen);
 
1014
    gfree(lig_copy);
 
1015
    return n;
 
1016
  }
 
1017
  // Step 3: map each component to a character string according to the
 
1018
  // procedure below, and concatenate those strings; the result is the
 
1019
  // character string to which the glyph name is mapped.
 
1020
  // 3.1. if the font is Zapf Dingbats (PostScript FontName ZapfDingbats), and
 
1021
  // the component is in the ZapfDingbats list, then map it to the
 
1022
  // corresponding character in that list.
 
1023
  // 3.2. otherwise, if the component is in the Adobe Glyph List, then map it
 
1024
  // to the corresponding character in that list.
 
1025
  if (names && (uBuf[0] = globalParams->mapNameToUnicode(charName))) {
 
1026
    return 1;
 
1027
  }
 
1028
  if (numeric) {
 
1029
    unsigned int n = strlen(charName);
 
1030
    // 3.3. otherwise, if the component is of the form "uni" (U+0075 U+006E
 
1031
    // U+0069) followed by a sequence of uppercase hexadecimal digits (0 .. 9,
 
1032
    // A .. F, i.e. U+0030 .. U+0039, U+0041 .. U+0046), the length of that
 
1033
    // sequence is a multiple of four, and each group of four digits represents
 
1034
    // a number in the set {0x0000 .. 0xD7FF, 0xE000 .. 0xFFFF}, then interpret
 
1035
    // each such number as a Unicode scalar value and map the component to the
 
1036
    // string made of those scalar values. Note that the range and digit length
 
1037
    // restrictions mean that the "uni" prefix can be used only with Unicode
 
1038
    // values from the Basic Multilingual Plane (BMP).
 
1039
    if (n >= 7 && (n % 4) == 3 && !strncmp(charName, "uni", 3)) {
 
1040
      unsigned int i, m;
 
1041
      for (i = 0, m = 3; i < uLen && m < n; m += 4) {
 
1042
        if (isxdigit(charName[m]) && isxdigit(charName[m + 1]) && 
 
1043
            isxdigit(charName[m + 2]) && isxdigit(charName[m + 3])) {
 
1044
          unsigned int u;
 
1045
          sscanf(charName + m, "%4x", &u);
 
1046
          if (u <= 0xD7FF || (0xE000 <= u && u <= 0xFFFF)) {
 
1047
            uBuf[i++] = u;
 
1048
          }
 
1049
        }
 
1050
      }
 
1051
      return i;
 
1052
    }
 
1053
    // 3.4. otherwise, if the component is of the form "u" (U+0075) followed by
 
1054
    // a sequence of four to six uppercase hexadecimal digits {0 .. 9, A .. F}
 
1055
    // (U+0030 .. U+0039, U+0041 .. U+0046), and those digits represent a
 
1056
    // number in {0x0000 .. 0xD7FF, 0xE000 .. 0x10FFFF}, then interpret this
 
1057
    // number as a Unicode scalar value and map the component to the string
 
1058
    // made of this scalar value.
 
1059
    if (n >= 5 && n <= 7 && charName[0] == 'u' && isxdigit(charName[1]) &&
 
1060
        isxdigit(charName[2]) && isxdigit(charName[3]) && isxdigit(charName[4])
 
1061
        && (n <= 5 || isxdigit(charName[5]))
 
1062
        && (n <= 6 || isxdigit(charName[6]))) {
 
1063
      unsigned int u;
 
1064
      sscanf(charName + 1, "%x", &u);
 
1065
      if (u <= 0xD7FF || (0xE000 <= u && u <= 0x10FFFF)) {
 
1066
        uBuf[0] = u;
 
1067
        return 1;
 
1068
      }
 
1069
    }
 
1070
    // Not in Adobe Glyph Mapping convention: look for names of the form 'Axx',
 
1071
    // 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B' are any letters, 'xx' is
 
1072
    // two hex digits, and 'nn' is 2-4 decimal digits
 
1073
    if (hex && n == 3 && isalpha(charName[0]) &&
 
1074
        isxdigit(charName[1]) && isxdigit(charName[2])) {
 
1075
      sscanf(charName+1, "%x", (unsigned int *)uBuf);
 
1076
      return 1;
 
1077
    } else if (hex && n == 2 &&
 
1078
               isxdigit(charName[0]) && isxdigit(charName[1])) {
 
1079
      sscanf(charName, "%x", (unsigned int *)uBuf);
 
1080
      return 1;
 
1081
    } else if (!hex && n >= 2 && n <= 4 &&
 
1082
               isdigit(charName[0]) && isdigit(charName[1])) {
 
1083
      uBuf[0] = (Unicode)atoi(charName);
 
1084
      return 1;
 
1085
    } else if (n >= 3 && n <= 5 &&
 
1086
               isdigit(charName[1]) && isdigit(charName[2])) {
 
1087
      uBuf[0] = (Unicode)atoi(charName+1);
 
1088
      return 1;
 
1089
    } else if (n >= 4 && n <= 6 &&
 
1090
               isdigit(charName[2]) && isdigit(charName[3])) {
 
1091
      uBuf[0] = (Unicode)atoi(charName+2);
 
1092
      return 1;
 
1093
    }
 
1094
  }
 
1095
  // 3.5. otherwise, map the component to the empty string
 
1096
  return 0;
 
1097
}
 
1098
 
964
1099
int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
965
1100
                             Unicode *u, int uSize, int *uLen,
966
1101
                             double *dx, double *dy, double *ox, double *oy) {
1221
1356
 
1222
1357
      // look for a user-supplied .cidToUnicode file
1223
1358
      if (!(ctu = globalParams->getCIDToUnicode(collection))) {
 
1359
        // I'm not completely sure that this is the best thing to do
 
1360
        // but it seems to produce better results when the .cidToUnicode
 
1361
        // files from the poppler-data package are missing. At least
 
1362
        // we know that assuming the Identity mapping is definitely wrong.
 
1363
        //   -- jrmuizel
 
1364
        static const char * knownCollections [] = {
 
1365
          "Adobe-CNS1",
 
1366
          "Adobe-GB1",
 
1367
          "Adobe-Japan1",
 
1368
          "Adobe-Japan2",
 
1369
          "Adobe-Korea1",
 
1370
        };
 
1371
        for (size_t i = 0; i < sizeof(knownCollections)/sizeof(knownCollections[0]); i++) {
 
1372
          if (collection->cmp(knownCollections[i])) {
 
1373
            error(-1, "Missing language pack for '%s' mapping", collection->getCString());
 
1374
            delete collection;
 
1375
            goto err2;
 
1376
          }
 
1377
        }
1224
1378
        error(-1, "Unknown character collection '%s'",
1225
1379
              collection->getCString());
1226
1380
        // fall-through, assuming the Identity mapping -- this appears
1568
1722
}
1569
1723
 
1570
1724
Gushort *GfxCIDFont::getCodeToGIDMap(FoFiTrueType *ff, int *mapsizep) {
 
1725
#define N_UCS_CANDIDATES 2
1571
1726
  /* space characters */
1572
1727
  static unsigned long spaces[] = { 
1573
1728
    0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,
1575
1730
    0
1576
1731
  };
1577
1732
  static char *adobe_cns1_cmaps[] = {
 
1733
    "UniCNS-UTF32-V",
1578
1734
    "UniCNS-UCS2-V",
 
1735
    "UniCNS-UTF32-H",
1579
1736
    "UniCNS-UCS2-H",
1580
1737
    0
1581
1738
  };
1582
1739
  static char *adobe_gb1_cmaps[] = {
 
1740
    "UniGB-UTF32-V",
1583
1741
    "UniGB-UCS2-V",
 
1742
    "UniGB-UTF32-H",
1584
1743
    "UniGB-UCS2-H",
1585
1744
    0
1586
1745
  };
1587
1746
  static char *adobe_japan1_cmaps[] = {
 
1747
    "UniJIS-UTF32-V",
1588
1748
    "UniJIS-UCS2-V",
 
1749
    "UniJIS-UTF32-H",
1589
1750
    "UniJIS-UCS2-H",
1590
1751
    0
1591
1752
  };
1592
1753
  static char *adobe_japan2_cmaps[] = {
 
1754
    "UniHojo-UTF32-V",
1593
1755
    "UniHojo-UCS2-V",
 
1756
    "UniHojo-UTF32-H",
1594
1757
    "UniHojo-UCS2-H",
1595
1758
    0
1596
1759
  };
1597
1760
  static char *adobe_korea1_cmaps[] = {
 
1761
    "UniKS-UTF32-V",
1598
1762
    "UniKS-UCS2-V",
 
1763
    "UniKS-UTF32-H",
1599
1764
    "UniKS-UCS2-H",
1600
1765
    0
1601
1766
  };
1635
1800
      "Adobe-Korea1-UCS2",
1636
1801
      adobe_korea1_cmaps,
1637
1802
    },
1638
 
    0
 
1803
    {0, 0, 0, 0}
1639
1804
  };
1640
1805
  Unicode *humap = 0;
1641
1806
  Unicode *vumap = 0;
 
1807
  Unicode *tumap = 0;
1642
1808
  Gushort *codeToGID = 0;
1643
1809
  unsigned long n;
1644
1810
  int i;
1645
1811
  unsigned long code;
1646
 
  Unicode uBuf[8];
1647
1812
  int wmode;
1648
1813
  char **cmapName;
1649
1814
  CMap *cMap;
1650
 
  int nUsed;
1651
 
  Unicode u;
1652
1815
  CMapListEntry *lp;
1653
1816
  int cmap;
1654
1817
  int cmapPlatform, cmapEncoding;
 
1818
  Ref embID;
1655
1819
 
1656
1820
  *mapsizep = 0;
1657
1821
  if (!ctu) return NULL;
1658
1822
  if (getCollection()->cmp("Adobe-Identity") == 0) return NULL;
 
1823
  if (getEmbeddedFontID(&embID)) {
 
1824
   /* if this font is embedded font, 
 
1825
    * CIDToGIDMap should be embedded in PDF file
 
1826
    * and already set. So return it.
 
1827
    */
 
1828
    *mapsizep = getCIDToGIDLen();
 
1829
    return getCIDToGID();
 
1830
  }
1659
1831
 
1660
1832
  /* we use only unicode cmap */
1661
1833
  cmap = -1;
1662
1834
  for (i = 0; i < ff->getNumCmaps(); ++i) {
1663
1835
    cmapPlatform = ff->getCmapPlatform(i);
1664
1836
    cmapEncoding = ff->getCmapEncoding(i);
1665
 
    if ((cmapPlatform == 3 && cmapEncoding == 1) || cmapPlatform == 0)
1666
 
      cmap = i;
 
1837
    if (cmapPlatform == 3 && cmapEncoding == 10) {
 
1838
        /* UCS-4 */
 
1839
        cmap = i;
 
1840
        /* use UCS-4 cmap */
 
1841
        break;
 
1842
    } else if (cmapPlatform == 3 && cmapEncoding == 1) {
 
1843
        /* Unicode */
 
1844
        cmap = i;
 
1845
    } else if (cmapPlatform == 0 && cmap < 0) {
 
1846
        cmap = i;
 
1847
    }
1667
1848
  }
1668
1849
  if (cmap < 0)
1669
1850
    return NULL;
1674
1855
      break;
1675
1856
    }
1676
1857
  }
1677
 
  n = ctu->getLength();
1678
 
  humap = new Unicode[n];
 
1858
  n = 65536;
 
1859
  tumap = new Unicode[n];
 
1860
  humap = new Unicode[n*N_UCS_CANDIDATES];
 
1861
  memset(humap,0,sizeof(Unicode)*n*N_UCS_CANDIDATES);
1679
1862
  if (lp->collection != 0) {
1680
1863
    CharCodeToUnicode *tctu;
1681
1864
    GooString tname(lp->toUnicodeMap);
1688
1871
 
1689
1872
        len = tctu->mapToUnicode(cid,ucodes,4);
1690
1873
        if (len == 1) {
1691
 
          humap[cid] = ucodes[0];
 
1874
          tumap[cid] = ucodes[0];
1692
1875
        } else {
1693
1876
          /* if not single character, ignore it */
1694
 
          humap[cid] = 0;
 
1877
          tumap[cid] = 0;
1695
1878
        }
1696
1879
      }
1697
1880
      delete tctu;
1703
1886
 
1704
1887
      if ((cMap = globalParams->getCMap(getCollection(),&cname))
1705
1888
           != 0) {
1706
 
        for (u = 0;u <= 65535;u++) {
1707
 
          CID cid;
1708
 
          char code[2];
1709
 
 
1710
 
          code[0] = (u >> 8) & 0xff;
1711
 
          code[1] = u & 0xff;
1712
 
          cid = cMap->getCID(code,2,&nUsed);
1713
 
          if (cid != 0) {
1714
1889
            if (cMap->getWMode()) {
1715
 
              if (cid < n && vumap[cid] == 0) {
1716
 
                vumap[cid] = u;
1717
 
              }
 
1890
                cMap->setReverseMap(vumap,n,1);
1718
1891
            } else {
1719
 
              if (cid < n && humap[cid] == 0) {
1720
 
                humap[cid] = u;
1721
 
              }
 
1892
                cMap->setReverseMap(humap,n,N_UCS_CANDIDATES);
1722
1893
            }
1723
 
          }
1724
 
        }
1725
1894
        cMap->decRefCnt();
1726
1895
      }
1727
1896
    }
1731
1900
      getCollection()->getCString());
1732
1901
    if ((ctu = getToUnicode()) != 0) {
1733
1902
      CharCode cid;
1734
 
      for (cid = 0;cid <= n ;cid++) {
 
1903
      for (cid = 0;cid < n ;cid++) {
1735
1904
        int len;
1736
 
        Unicode ucode;
 
1905
        Unicode ucode = 0;
1737
1906
 
1738
1907
        len = ctu->mapToUnicode(cid,&ucode,1);
1739
 
        humap[cid] = ucode;
 
1908
        humap[cid*N_UCS_CANDIDATES] = ucode;
 
1909
        for (i = 1;i < N_UCS_CANDIDATES;i++) {
 
1910
            humap[cid*N_UCS_CANDIDATES+i] = 0;
 
1911
        }
1740
1912
      }
1741
1913
      ctu->decRefCnt();
1742
1914
    }
1749
1921
 
1750
1922
    unicode = 0;
1751
1923
    gid = 0;
1752
 
    if (vumap != 0) unicode = vumap[code];
1753
 
    if (unicode != 0) {
1754
 
      gid = mapCodeToGID(ff,cmap,unicode,gTrue);
1755
 
      if (gid == 0 && humap != 0) {
1756
 
        if (humap != 0) unicode = humap[code];
1757
 
        if (unicode != 0) gid = mapCodeToGID(ff,cmap,unicode,gTrue);
1758
 
      }
1759
 
    }
1760
 
    if (gid == 0) {
1761
 
      if (humap != 0) unicode = humap[code];
1762
 
      if (unicode != 0) gid = mapCodeToGID(ff,cmap,unicode,wmode);
 
1924
    if (humap != 0) {
 
1925
      for (i = 0;i < N_UCS_CANDIDATES
 
1926
        && gid == 0 && (unicode = humap[code*N_UCS_CANDIDATES+i]) != 0;i++) {
 
1927
        gid = mapCodeToGID(ff,cmap,unicode,gFalse);
 
1928
      }
 
1929
    }
 
1930
    if (gid == 0 && vumap != 0) {
 
1931
      unicode = vumap[code];
 
1932
      if (unicode != 0) {
 
1933
        gid = mapCodeToGID(ff,cmap,unicode,gTrue);
 
1934
        if (gid == 0 && tumap != 0) {
 
1935
          if ((unicode = tumap[code]) != 0) {
 
1936
            gid = mapCodeToGID(ff,cmap,unicode,gTrue);
 
1937
          }
 
1938
        }
 
1939
      }
 
1940
    }
 
1941
    if (gid == 0 && tumap != 0) {
 
1942
      if ((unicode = tumap[code]) != 0) {
 
1943
        gid = mapCodeToGID(ff,cmap,unicode,gFalse);
 
1944
      }
1763
1945
    }
1764
1946
    if (gid == 0) {
1765
1947
      /* special handling space characters */
1781
1963
  }
1782
1964
  *mapsizep = n;
1783
1965
  if (humap != 0) delete[] humap;
 
1966
  if (tumap != 0) delete[] tumap;
1784
1967
  if (vumap != 0) delete[] vumap;
1785
 
end_0:
1786
1968
  return codeToGID;
1787
1969
}
1788
1970
 
1789
1971
double GfxCIDFont::getWidth (char* s, int len) {
1790
1972
  int nUsed;
1791
 
  double w, h, vx, vy;
 
1973
  double w;
1792
1974
  int a, b, m;
1793
1975
 
1794
1976
  CID cid = cMap->getCID(s, len, &nUsed);
1844
2026
      fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i),
1845
2027
                                   r, obj2.getDict());
1846
2028
      if (fonts[i] && !fonts[i]->isOk()) {
 
2029
        // XXX: it may be meaningful to distinguish between
 
2030
        // NULL and !isOk() so that when we do lookups
 
2031
        // we can tell the difference between a missing font
 
2032
        // and a font that is just !isOk()
1847
2033
        delete fonts[i];
1848
2034
        fonts[i] = NULL;
1849
2035
      }