[poppler] poppler/poppler: FontInfo.cc, NONE, 1.1 FontInfo.h, NONE, 1.1

Kristian Hogsberg krh at freedesktop.org
Mon Jun 13 10:18:34 PDT 2005


Update of /cvs/poppler/poppler/poppler
In directory gabe:/tmp/cvs-serv2424/poppler

Added Files:
	FontInfo.cc FontInfo.h 
Log Message:
Forgot to add new files.

--- NEW FILE: FontInfo.cc ---
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <math.h>
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
#include "Dict.h"
#include "GfxFont.h"
#include "Annot.h"
#include "PDFDoc.h"
#include "config.h"
#include "FontInfo.h"

static char *fontTypeNames[] = {
  "unknown",
  "Type 1",
  "Type 1C",
  "Type 3",
  "TrueType",
  "CID Type 0",
  "CID Type 0C",
  "CID TrueType"
};

FontInfoScanner::FontInfoScanner(PDFDoc *docA) {
  doc = docA;
  currentPage = 1;
  fonts = NULL;
  fontsLen = fontsSize = 0;
}

FontInfoScanner::~FontInfoScanner() {
  gfree(fonts);
}

GooList *FontInfoScanner::scan(int nPages) {
  GooList *result;
  Page *page;
  Dict *resDict;
  Annots *annots;
  Object obj1, obj2;
  int pg, i, lastPage;

  if (currentPage > doc->getNumPages()) {
    return NULL;
  }
 
  result = new GooList();

  lastPage = currentPage + nPages;
  if (lastPage > doc->getNumPages()) {
    lastPage = doc->getNumPages();
  }

  for (pg = currentPage; pg <= lastPage; ++pg) {
    page = doc->getCatalog()->getPage(pg);
    if ((resDict = page->getResourceDict())) {
      scanFonts(resDict, result);
    }
    annots = new Annots(doc->getXRef(), 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(), result);
	}
	obj2.free();
      }
      obj1.free();
    }
    delete annots;
  }

  currentPage = lastPage + 1;

  return result;
}

void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) {
  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))) {
        Ref fontRef = *font->getID();
	GBool alreadySeen = gFalse;

        // check for an already-seen font
        for (i = 0; i < fontsLen; ++i) {
          if (fontRef.num == fonts[i].num && fontRef.gen == fonts[i].gen) {
            alreadySeen = gTrue;
          }
        }

	// add this font to the list
        if (!alreadySeen) {
          fontsList->append(new FontInfo(font, doc));
          if (fontsLen == fontsSize) {
            fontsSize += 32;
            fonts = (Ref *)grealloc(fonts, fontsSize * sizeof(Ref));
          }
          fonts[fontsLen++] = *font->getID();
        }
      }
    }
    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(), fontsList);
	}
	resObj.free();
      }
      xObj.free();
    }
  }
  xObjDict.free();
}

FontInfo::FontInfo(GfxFont *font, PDFDoc *doc) {
  Ref embRef;
  Object fontObj, toUnicodeObj;
  int i;

  fontRef = *font->getID();

  // font name
  name = font->getOrigName()->copy();

  // 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) == '+';
  }
}

FontInfo::FontInfo(FontInfo& f) {
  name = f.name->copy();
  emb = f.emb;
  subset = f.subset;
  hasToUnicode = f.hasToUnicode;
  fontRef = f.fontRef;
}

FontInfo::~FontInfo() {
  delete name;
}

--- NEW FILE: FontInfo.h ---
#ifndef FONT_INFO_H
#define FONT_INFO_H

#include "goo/gtypes.h"
#include "goo/GooList.h"

class FontInfo {
public:

  // Constructor.
  FontInfo(GfxFont *fontA, PDFDoc *doc);
  // Copy constructor
  FontInfo(FontInfo& f);
  // Destructor.
  ~FontInfo();

  GooString *getName()      { return name; };
  GBool      getEmbedded()  { return emb; };
  GBool      getSubset()    { return subset; };
  GBool      getToUnicode() { return hasToUnicode; };

private:
  GooString *name;
  GBool emb;
  GBool subset;
  GBool hasToUnicode;
  Ref fontRef;
};

class FontInfoScanner {
public:

  // Constructor.
  FontInfoScanner(PDFDoc *doc);
  // Destructor.
  ~FontInfoScanner();

  GooList *scan(int nPages);

private:

  PDFDoc *doc;
  int currentPage;
  Ref *fonts;
  int fontsLen;
  int fontsSize;

  void scanFonts(Dict *resDict, GooList *fontsList);
};

#endif



More information about the poppler mailing list