source: trunk/poppler/mypoppler/poppler/FontInfo.cc @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 4.6 KB
Line 
1#include "config.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <stddef.h>
5#include <string.h>
6#include <math.h>
7#include "GlobalParams.h"
8#include "Error.h"
9#include "Object.h"
10#include "Dict.h"
11#include "GfxFont.h"
12#include "Annot.h"
13#include "PDFDoc.h"
14#include "FontInfo.h"
15#include "UGooString.h"
16
17FontInfoScanner::FontInfoScanner(PDFDoc *docA) {
18  doc = docA;
19  currentPage = 1;
20  fonts = NULL;
21  fontsLen = fontsSize = 0;
22}
23
24FontInfoScanner::~FontInfoScanner() {
25  gfree(fonts);
26}
27
28GooList *FontInfoScanner::scan(int nPages) {
29  GooList *result;
30  Page *page;
31  Dict *resDict;
32  Annots *annots;
33  Object obj1, obj2;
34  int pg, i, lastPage;
35
36  if (currentPage > doc->getNumPages()) {
37    return NULL;
38  }
39 
40  result = new GooList();
41
42  lastPage = currentPage + nPages;
43  if (lastPage > doc->getNumPages()) {
44    lastPage = doc->getNumPages();
45  }
46
47  for (pg = currentPage; pg <= lastPage; ++pg) {
48    page = doc->getCatalog()->getPage(pg);
49    if ((resDict = page->getResourceDict())) {
50      scanFonts(resDict, result);
51    }
52    annots = new Annots(doc->getXRef(), doc->getCatalog(), page->getAnnots(&obj1));
53    obj1.free();
54    for (i = 0; i < annots->getNumAnnots(); ++i) {
55      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
56        obj1.streamGetDict()->lookup("Resources", &obj2);
57        if (obj2.isDict()) {
58          scanFonts(obj2.getDict(), result);
59        }
60        obj2.free();
61      }
62      obj1.free();
63    }
64    delete annots;
65  }
66
67  currentPage = lastPage + 1;
68
69  return result;
70}
71
72void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) {
73  Object obj1, obj2, xObjDict, xObj, resObj;
74  Ref r;
75  GfxFontDict *gfxFontDict;
76  GfxFont *font;
77  int i;
78
79  // scan the fonts in this resource dictionary
80  gfxFontDict = NULL;
81  resDict->lookupNF("Font", &obj1);
82  if (obj1.isRef()) {
83    obj1.fetch(doc->getXRef(), &obj2);
84    if (obj2.isDict()) {
85      r = obj1.getRef();
86      gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict());
87    }
88    obj2.free();
89  } else if (obj1.isDict()) {
90    gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict());
91  }
92  if (gfxFontDict) {
93    for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {
94      int k;
95      if ((font = gfxFontDict->getFont(i))) {
96        Ref fontRef = *font->getID();
97        GBool alreadySeen = gFalse;
98
99        // check for an already-seen font
100        for (k = 0; k < fontsLen; ++k) {
101          if (fontRef.num == fonts[k].num && fontRef.gen == fonts[k].gen) {
102            alreadySeen = gTrue;
103          }
104        }
105
106        // add this font to the list
107        if (!alreadySeen) {
108          fontsList->append(new FontInfo(font, doc));
109          if (fontsLen == fontsSize) {
110            fontsSize += 32;
111            fonts = (Ref *)grealloc(fonts, fontsSize * sizeof(Ref));
112          }
113          fonts[fontsLen++] = *font->getID();
114        }
115      }
116    }
117    delete gfxFontDict;
118  }
119  obj1.free();
120
121  // recursively scan any resource dictionaries in objects in this
122  // resource dictionary
123  resDict->lookup("XObject", &xObjDict);
124  if (xObjDict.isDict()) {
125    for (i = 0; i < xObjDict.dictGetLength(); ++i) {
126      xObjDict.dictGetVal(i, &xObj);
127      if (xObj.isStream()) {
128        xObj.streamGetDict()->lookup("Resources", &resObj);
129        if (resObj.isDict()) {
130          scanFonts(resObj.getDict(), fontsList);
131        }
132        resObj.free();
133      }
134      xObj.free();
135    }
136  }
137  xObjDict.free();
138}
139
140FontInfo::FontInfo(GfxFont *font, PDFDoc *doc) {
141  GooString *origName;
142  Ref embRef;
143  Object fontObj, toUnicodeObj;
144  int i;
145
146  fontRef = *font->getID();
147
148  // font name
149  origName = font->getOrigName();
150  if (origName != NULL) {
151    name = font->getOrigName()->copy();
152  } else {
153    name = NULL;
154  }
155 
156  // font type
157  type = (FontInfo::Type)font->getType();
158
159  // check for an embedded font
160  if (font->getType() == fontType3) {
161    emb = gTrue;
162  } else {
163    emb = font->getEmbeddedFontID(&embRef);
164  }
165
166  // look for a ToUnicode map
167  hasToUnicode = gFalse;
168  if (doc->getXRef()->fetch(fontRef.num, fontRef.gen, &fontObj)->isDict()) {
169    hasToUnicode = fontObj.dictLookup("ToUnicode", &toUnicodeObj)->isStream();
170    toUnicodeObj.free();
171  }
172  fontObj.free();
173
174  // check for a font subset name: capital letters followed by a '+'
175  // sign
176  subset = gFalse;
177  if (name) {
178    for (i = 0; i < name->getLength(); ++i) {
179      if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') {
180        break;
181      }
182    }
183    subset = i > 0 && i < name->getLength() && name->getChar(i) == '+';
184  }
185}
186
187FontInfo::FontInfo(FontInfo& f) {
188  name = f.name->copy();
189  type = f.type;
190  emb = f.emb;
191  subset = f.subset;
192  hasToUnicode = f.hasToUnicode;
193  fontRef = f.fontRef;
194}
195
196FontInfo::~FontInfo() {
197  delete name;
198}
Note: See TracBrowser for help on using the repository browser.