upgraded to xpdf-3.01pl1
[swftools.git] / pdf2swf / xpdf / GfxFont.cc
index ed9f076..a4581c0 100644 (file)
@@ -55,8 +55,8 @@ static StdFontMapEntry stdFontMap[] = {
   { "Arial-ItalicMT",               "Helvetica-Oblique" },
   { "ArialMT",                      "Helvetica" },
   { "Courier,Bold",                 "Courier-Bold" },
-  { "Courier,Italic",               "Courier-Oblique" },
   { "Courier,BoldItalic",           "Courier-BoldOblique" },
+  { "Courier,Italic",               "Courier-Oblique" },
   { "CourierNew",                   "Courier" },
   { "CourierNew,Bold",              "Courier-Bold" },
   { "CourierNew,BoldItalic",        "Courier-BoldOblique" },
@@ -191,19 +191,19 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 
     // look for embedded font file
     if (obj1.dictLookupNF("FontFile", &obj2)->isRef()) {
-      if (type == fontType1) {
-       embFontID = obj2.getRef();
-      } else {
+      embFontID = obj2.getRef();
+      if (type != fontType1) {
        error(-1, "Mismatch between font type and embedded font file");
+       type = fontType1;
       }
     }
     obj2.free();
     if (embFontID.num == -1 &&
        obj1.dictLookupNF("FontFile2", &obj2)->isRef()) {
-      if (type == fontTrueType || type == fontCIDType2) {
-       embFontID = obj2.getRef();
-      } else {
+      embFontID = obj2.getRef();
+      if (type != fontTrueType && type != fontCIDType2) {
        error(-1, "Mismatch between font type and embedded font file");
+       type = type == fontCIDType0 ? fontCIDType2 : fontTrueType;
       }
     }
     obj2.free();
@@ -212,33 +212,29 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
       if (obj2.fetch(xref, &obj3)->isStream()) {
        obj3.streamGetDict()->lookup("Subtype", &obj4);
        if (obj4.isName("Type1")) {
-         if (type == fontType1) {
-           embFontID = obj2.getRef();
-         } else {
+         embFontID = obj2.getRef();
+         if (type != fontType1) {
            error(-1, "Mismatch between font type and embedded font file");
+           type = fontType1;
          }
        } else if (obj4.isName("Type1C")) {
-         if (type == fontType1) {
-           type = fontType1C;
-           embFontID = obj2.getRef();
-         } else if (type == fontType1C) {
-           embFontID = obj2.getRef();
-         } else {
+         embFontID = obj2.getRef();
+         if (type != fontType1 && type != fontType1C) {
            error(-1, "Mismatch between font type and embedded font file");
          }
+         type = fontType1C;
        } else if (obj4.isName("TrueType")) {
-         if (type == fontTrueType) {
-           embFontID = obj2.getRef();
-         } else {
+         embFontID = obj2.getRef();
+         if (type != fontTrueType) {
            error(-1, "Mismatch between font type and embedded font file");
+           type = fontTrueType;
          }
        } else if (obj4.isName("CIDFontType0C")) {
-         if (type == fontCIDType0) {
-           type = fontCIDType0C;
-           embFontID = obj2.getRef();
-         } else {
+         embFontID = obj2.getRef();
+         if (type != fontCIDType0) {
            error(-1, "Mismatch between font type and embedded font file");
          }
+         type = fontCIDType0C;
        } else {
          error(-1, "Unknown embedded font type '%s'",
                obj4.isName() ? obj4.getName() : "???");
@@ -399,6 +395,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
                         GfxFontType typeA, Dict *fontDict):
   GfxFont(tagA, idA, nameA)
 {
+  GString *name2;
   BuiltinFont *builtinFont;
   char **baseEnc;
   GBool baseEncFromFontFile;
@@ -424,20 +421,30 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
   // do font name substitution for various aliases of the Base 14 font
   // names
   if (name) {
+    name2 = name->copy();
+    i = 0;
+    while (i < name2->getLength()) {
+      if (name2->getChar(i) == ' ') {
+       name2->del(i);
+      } else {
+       ++i;
+      }
+    }
     a = 0;
     b = sizeof(stdFontMap) / sizeof(StdFontMapEntry);
-    // invariant: stdFontMap[a].altName <= name < stdFontMap[b].altName
+    // invariant: stdFontMap[a].altName <= name2 < stdFontMap[b].altName
     while (b - a > 1) {
       m = (a + b) / 2;
-      if (name->cmp(stdFontMap[m].altName) >= 0) {
+      if (name2->cmp(stdFontMap[m].altName) >= 0) {
        a = m;
       } else {
        b = m;
       }
     }
-    if (!name->cmp(stdFontMap[a].altName)) {
+    if (!name2->cmp(stdFontMap[a].altName)) {
       name = new GString(stdFontMap[a].properName);
     }
+    delete name2;
   }
 
   // is it a built-in font?
@@ -468,6 +475,17 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
   // get info from font descriptor
   readFontDescriptor(xref, fontDict);
 
+  // for non-embedded fonts, don't trust the ascent/descent/bbox
+  // values from the font descriptor
+  if (builtinFont && embFontID.num < 0) {
+    ascent = 0.001 * builtinFont->ascent;
+    descent = 0.001 * builtinFont->descent;
+    fontBBox[0] = 0.001 * builtinFont->bbox[0];
+    fontBBox[1] = 0.001 * builtinFont->bbox[1];
+    fontBBox[2] = 0.001 * builtinFont->bbox[2];
+    fontBBox[3] = 0.001 * builtinFont->bbox[3];
+  }
+
   // look for an external font file
   findExtFontFile();
 
@@ -513,7 +531,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
   //   2. embedded or external font file
   //   3. default:
   //        - builtin --> builtin encoding
-  //        - TrueType --> MacRomanEncoding
+  //        - TrueType --> WinAnsiEncoding
   //        - others --> StandardEncoding
   // and then add a list of differences (if any) from
   // FontDict.Encoding.Differences.
@@ -536,9 +554,6 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
     } else if (obj2.isName("WinAnsiEncoding")) {
       hasEncoding = gTrue;
       baseEnc = winAnsiEncoding;
-    } else if (obj2.isName("StandardEncoding")) {
-      hasEncoding = gTrue;
-      baseEnc = standardEncoding;
     }
     obj2.free();
   } else if (obj1.isName("MacRomanEncoding")) {
@@ -551,9 +566,6 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
   } else if (obj1.isName("WinAnsiEncoding")) {
     hasEncoding = gTrue;
     baseEnc = winAnsiEncoding;
-  } else if (obj1.isName("StandardEncoding")) {
-    hasEncoding = gTrue;
-    baseEnc = standardEncoding;
   }
 
   // check embedded or external font file for base encoding
@@ -607,7 +619,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
 
   // get default base encoding
   if (!baseEnc) {
-    if (builtinFont) {
+    if (builtinFont && embFontID.num < 0) {
       baseEnc = builtinFont->defaultBaseEnc;
       hasEncoding = gTrue;
     } else if (type == fontTrueType) {
@@ -899,7 +911,7 @@ Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
   Unicode u;
   int code, i, n;
 
-  map = (Gushort *)gmalloc(256 * sizeof(Gushort));
+  map = (Gushort *)gmallocn(256, sizeof(Gushort));
   for (i = 0; i < 256; ++i) {
     map[i] = 0;
   }
@@ -919,7 +931,8 @@ Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
   //        directly (possibly with an offset of 0xf000).
   //    1d. If the TrueType font has a Macintosh Roman cmap, use it,
   //        as in case 1a.
-  // 2. If the PDF font does not have an encoding:
+  // 2. If the PDF font does not have an encoding or the PDF font is
+  //    symbolic:
   //    2a. If the TrueType font has a Macintosh Roman cmap, use it,
   //        and use char codes directly (possibly with an offset of
   //        0xf000).
@@ -953,6 +966,8 @@ Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
       useUnicode = gTrue;
     } else if ((flags & fontSymbolic) && msSymbolCmap >= 0) {
       cmap = msSymbolCmap;
+    } else if ((flags & fontSymbolic) && macRomanCmap >= 0) {
+      cmap = macRomanCmap;
     } else if (macRomanCmap >= 0) {
       cmap = macRomanCmap;
       useMacRoman = gTrue;
@@ -979,7 +994,9 @@ Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
   // map Unicode through the cmap
   } else if (useUnicode) {
     for (i = 0; i < 256; ++i) {
-      if ((n = ctu->mapToUnicode((CharCode)i, &u, 1))) {
+      if (((charName = enc[i]) &&
+          (u = globalParams->mapNameToUnicode(charName))) ||
+         (n = ctu->mapToUnicode((CharCode)i, &u, 1))) {
        map[i] = ff->mapCodeToGID(cmap, u);
       }
     }
@@ -1043,8 +1060,11 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
   GString *collection, *cMapName;
   Object desFontDictObj;
   Object obj1, obj2, obj3, obj4, obj5, obj6;
+  CharCodeToUnicode *utu;
+  CharCode c;
+  Unicode uBuf[8];
   int c1, c2;
-  int excepsSize, i, j, k;
+  int excepsSize, i, j, k, n;
 
   ascent = 0.95;
   descent = -0.35;
@@ -1126,9 +1146,27 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
       if (!(ctu = globalParams->getCIDToUnicode(collection))) {
        error(-1, "Unknown character collection '%s'",
              collection->getCString());
-       delete collection;
-       goto err2;
+       // fall-through, assuming the Identity mapping -- this appears
+       // to match Adobe's behavior
+      }
+    }
+  }
+
+  // look for a Unicode-to-Unicode mapping
+  if (name && (utu = globalParams->getUnicodeToUnicode(name))) {
+    if (ctu) {
+      for (c = 0; c < ctu->getLength(); ++c) {
+       n = ctu->mapToUnicode(c, uBuf, 8);
+       if (n >= 1) {
+         n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8);
+         if (n >= 1) {
+           ctu->setMapping(c, uBuf, n);
+         }
+       }
       }
+      utu->decRefCnt();
+    } else {
+      ctu = utu;
     }
   }
 
@@ -1158,13 +1196,13 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
     if (obj1.isStream()) {
       cidToGIDLen = 0;
       i = 64;
-      cidToGID = (Gushort *)gmalloc(i * sizeof(Gushort));
+      cidToGID = (Gushort *)gmallocn(i, sizeof(Gushort));
       obj1.streamReset();
       while ((c1 = obj1.streamGetChar()) != EOF &&
             (c2 = obj1.streamGetChar()) != EOF) {
        if (cidToGIDLen == i) {
          i *= 2;
-         cidToGID = (Gushort *)grealloc(cidToGID, i * sizeof(Gushort));
+         cidToGID = (Gushort *)greallocn(cidToGID, i, sizeof(Gushort));
        }
        cidToGID[cidToGIDLen++] = (Gushort)((c1 << 8) + c2);
       }
@@ -1194,8 +1232,8 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
          if (widths.nExceps == excepsSize) {
            excepsSize += 16;
            widths.exceps = (GfxFontCIDWidthExcep *)
-             grealloc(widths.exceps,
-                      excepsSize * sizeof(GfxFontCIDWidthExcep));
+             greallocn(widths.exceps,
+                       excepsSize, sizeof(GfxFontCIDWidthExcep));
          }
          widths.exceps[widths.nExceps].first = obj2.getInt();
          widths.exceps[widths.nExceps].last = obj3.getInt();
@@ -1210,8 +1248,8 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
        if (widths.nExceps + obj3.arrayGetLength() > excepsSize) {
          excepsSize = (widths.nExceps + obj3.arrayGetLength() + 15) & ~15;
          widths.exceps = (GfxFontCIDWidthExcep *)
-           grealloc(widths.exceps,
-                    excepsSize * sizeof(GfxFontCIDWidthExcep));
+           greallocn(widths.exceps,
+                     excepsSize, sizeof(GfxFontCIDWidthExcep));
        }
        j = obj2.getInt();
        for (k = 0; k < obj3.arrayGetLength(); ++k) {
@@ -1267,8 +1305,8 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
          if (widths.nExcepsV == excepsSize) {
            excepsSize += 16;
            widths.excepsV = (GfxFontCIDWidthExcepV *)
-             grealloc(widths.excepsV,
-                      excepsSize * sizeof(GfxFontCIDWidthExcepV));
+             greallocn(widths.excepsV,
+                       excepsSize, sizeof(GfxFontCIDWidthExcepV));
          }
          widths.excepsV[widths.nExcepsV].first = obj2.getInt();
          widths.excepsV[widths.nExcepsV].last = obj3.getInt();
@@ -1288,8 +1326,8 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
          excepsSize =
            (widths.nExcepsV + obj3.arrayGetLength() / 3 + 15) & ~15;
          widths.excepsV = (GfxFontCIDWidthExcepV *)
-           grealloc(widths.excepsV,
-                    excepsSize * sizeof(GfxFontCIDWidthExcepV));
+           greallocn(widths.excepsV,
+                     excepsSize, sizeof(GfxFontCIDWidthExcepV));
        }
        j = obj2.getInt();
        for (k = 0; k < obj3.arrayGetLength(); k += 3) {
@@ -1452,7 +1490,7 @@ GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
   Ref r;
 
   numFonts = fontDict->getLength();
-  fonts = (GfxFont **)gmalloc(numFonts * sizeof(GfxFont *));
+  fonts = (GfxFont **)gmallocn(numFonts, sizeof(GfxFont *));
   for (i = 0; i < numFonts; ++i) {
     fontDict->getValNF(i, &obj1);
     obj1.fetch(xref, &obj2);