[poppler] utils/pdffonts.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Sun Nov 28 04:51:12 PST 2010


 utils/pdffonts.cc |  185 +++++++-----------------------------------------------
 1 file changed, 26 insertions(+), 159 deletions(-)

New commits:
commit 4c20bf14c0b1d7f1d5e530ded890186487da32b5
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sun Nov 28 12:50:24 2010 +0000

    Use FontInfoScanner
    
    No idea why we didn't do this before, duplicate code is evil and now
    pdffonts doesn't crash on pdf from bug 20486

diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc
index 30e25dc..e3d8960 100644
--- a/utils/pdffonts.cc
+++ b/utils/pdffonts.cc
@@ -33,13 +33,10 @@
 #include "goo/GooString.h"
 #include "goo/gmem.h"
 #include "GlobalParams.h"
-#include "Error.h"
 #include "Object.h"
-#include "Dict.h"
-#include "GfxFont.h"
-#include "Annot.h"
 #include "PDFDoc.h"
 #include "PDFDocFactory.h"
+#include "FontInfo.h"
 
 static char *fontTypeNames[] = {
   "unknown",
@@ -56,9 +53,6 @@ static char *fontTypeNames[] = {
   "CID TrueType (OT)"
 };
 
-static void scanFonts(Dict *resDict, PDFDoc *doc);
-static void scanFont(GfxFont *font, PDFDoc *doc);
-
 static int firstPage = 1;
 static int lastPage = 0;
 static char ownerPassword[33] = "\001";
@@ -88,20 +82,11 @@ static const ArgDesc argDesc[] = {
   {NULL}
 };
 
-static Ref *fonts;
-static int fontsLen;
-static int fontsSize;
-
 int main(int argc, char *argv[]) {
   PDFDoc *doc;
   GooString *fileName;
   GooString *ownerPW, *userPW;
   GBool ok;
-  Page *page;
-  Dict *resDict;
-  Annots *annots;
-  Object obj1, obj2;
-  int pg, i;
   int exitCode;
 
   exitCode = 99;
@@ -160,41 +145,37 @@ int main(int argc, char *argv[]) {
     lastPage = doc->getNumPages();
   }
 
-  // scan the fonts
-  printf("name                                 type              emb sub uni object ID\n");
-  printf("------------------------------------ ----------------- --- --- --- ---------\n");
-  fonts = NULL;
-  fontsLen = fontsSize = 0;
-  for (pg = firstPage; pg <= lastPage; ++pg) {
-    page = doc->getPage(pg);
-    if (!page) {
-      error(-1, "Failed to read fonts from page %d", pg);
-      continue;
-    }
-    if ((resDict = page->getResourceDict())) {
-      scanFonts(resDict, doc);
-    }
-    annots = new Annots(doc->getXRef(),
-			doc->getCatalog(),
-			page->getAnnots(&obj1));
-    obj1.free();
-    for (i = 0; i < annots->getNumAnnots(); ++i) {
-      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
-	obj1.streamGetDict()->lookup("Resources", &obj2);
-	if (obj2.isDict()) {
-	  scanFonts(obj2.getDict(), doc);
-	}
-	obj2.free();
+  // get the fonts
+  {
+    FontInfoScanner scanner(doc, firstPage - 1);
+    GooList *fonts = scanner.scan(lastPage - firstPage + 1);
+
+    // print the font info
+    printf("name                                 type              emb sub uni object ID\n");
+    printf("------------------------------------ ----------------- --- --- --- ---------\n");
+    if (fonts) {
+      for (int i = 0; i < fonts->getLength(); ++i) {
+        FontInfo *font = (FontInfo *)fonts->get(i);
+        printf("%-36s %-17s %-3s %-3s %-3s",
+              font->getName() ? font->getName()->getCString() : "[none]",
+              fontTypeNames[font->getType()],
+              font->getEmbedded() ? "yes" : "no",
+              font->getSubset() ? "yes" : "no",
+              font->getToUnicode() ? "yes" : "no");
+        const Ref fontRef = font->getRef();
+        if (fontRef.gen >= 100000) {
+          printf(" [none]\n");
+        } else {
+          printf(" %6d %2d\n", fontRef.num, fontRef.gen);
+        }
+        delete font;
       }
-      obj1.free();
+      delete fonts;
     }
-    delete annots;
   }
 
   exitCode = 0;
 
-  // clean up
-  gfree(fonts);
  err1:
   delete doc;
   delete globalParams;
@@ -207,118 +188,4 @@ int main(int argc, char *argv[]) {
   return exitCode;
 }
 
-static void scanFonts(Dict *resDict, PDFDoc *doc) {
-  Object obj1, obj2, xObjDict, xObj, resObj;
-  Ref r;
-  GfxFontDict *gfxFontDict;
-  GfxFont *font;
-  int i;
-
-  // scan the fonts in this resource dictionary
-  gfxFontDict = NULL;
-  resDict->lookupNF("Font", &obj1);
-  if (obj1.isRef()) {
-    obj1.fetch(doc->getXRef(), &obj2);
-    if (obj2.isDict()) {
-      r = obj1.getRef();
-      gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict());
-    }
-    obj2.free();
-  } else if (obj1.isDict()) {
-    gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict());
-  }
-  if (gfxFontDict) {
-    for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {
-      if ((font = gfxFontDict->getFont(i))) {
-	scanFont(font, doc);
-      }
-    }
-    delete gfxFontDict;
-  }
-  obj1.free();
-
-  // recursively scan any resource dictionaries in objects in this
-  // resource dictionary
-  resDict->lookup("XObject", &xObjDict);
-  if (xObjDict.isDict()) {
-    for (i = 0; i < xObjDict.dictGetLength(); ++i) {
-      xObjDict.dictGetVal(i, &xObj);
-      if (xObj.isStream()) {
-	xObj.streamGetDict()->lookup("Resources", &resObj);
-	if (resObj.isDict()) {
-	  scanFonts(resObj.getDict(), doc);
-	}
-	resObj.free();
-      }
-      xObj.free();
-    }
-  }
-  xObjDict.free();
-}
-
-static void scanFont(GfxFont *font, PDFDoc *doc) {
-  Ref fontRef, embRef;
-  Object fontObj, toUnicodeObj;
-  GooString *name;
-  GBool emb, subset, hasToUnicode;
-  int i;
 
-  fontRef = *font->getID();
-
-  // check for an already-seen font
-  for (i = 0; i < fontsLen; ++i) {
-    if (fontRef.num == fonts[i].num && fontRef.gen == fonts[i].gen) {
-      return;
-    }
-  }
-
-  // font name
-  name = font->getOrigName();
-
-  // check for an embedded font
-  if (font->getType() == fontType3) {
-    emb = gTrue;
-  } else {
-    emb = font->getEmbeddedFontID(&embRef);
-  }
-
-  // look for a ToUnicode map
-  hasToUnicode = gFalse;
-  if (doc->getXRef()->fetch(fontRef.num, fontRef.gen, &fontObj)->isDict()) {
-    hasToUnicode = fontObj.dictLookup("ToUnicode", &toUnicodeObj)->isStream();
-    toUnicodeObj.free();
-  }
-  fontObj.free();
-
-  // check for a font subset name: capital letters followed by a '+'
-  // sign
-  subset = gFalse;
-  if (name) {
-    for (i = 0; i < name->getLength(); ++i) {
-      if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') {
-	break;
-      }
-    }
-    subset = i > 0 && i < name->getLength() && name->getChar(i) == '+';
-  }
-
-  // print the font info
-  printf("%-36s %-17s %-3s %-3s %-3s",
-	 name ? name->getCString() : "[none]",
-	 fontTypeNames[font->getType()],
-	 emb ? "yes" : "no",
-	 subset ? "yes" : "no",
-	 hasToUnicode ? "yes" : "no");
-  if (fontRef.gen >= 100000) {
-    printf(" [none]\n");
-  } else {
-    printf(" %6d %2d\n", fontRef.num, fontRef.gen);
-  }
-
-  // add this font to the list
-  if (fontsLen == fontsSize) {
-    fontsSize += 32;
-    fonts = (Ref *)grealloc(fonts, fontsSize * sizeof(Ref));
-  }
-  fonts[fontsLen++] = *font->getID();
-}


More information about the poppler mailing list