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

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

poppler updated to version 0.5.2, also needed changes to be compatible with new poppler

File size: 4.9 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  if (!emb)
167  {
168    DisplayFontParam *dfp = globalParams->getDisplayFont(font);
169    if (dfp)
170    {
171      if (dfp->kind == displayFontT1) file = dfp->t1.fileName->copy();
172      else file = dfp->tt.fileName->copy();
173    }
174    else file = NULL;
175  }
176  else file = NULL;
177
178  // look for a ToUnicode map
179  hasToUnicode = gFalse;
180  if (doc->getXRef()->fetch(fontRef.num, fontRef.gen, &fontObj)->isDict()) {
181    hasToUnicode = fontObj.dictLookup("ToUnicode", &toUnicodeObj)->isStream();
182    toUnicodeObj.free();
183  }
184  fontObj.free();
185
186  // check for a font subset name: capital letters followed by a '+'
187  // sign
188  subset = gFalse;
189  if (name) {
190    for (i = 0; i < name->getLength(); ++i) {
191      if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') {
192        break;
193      }
194    }
195    subset = i > 0 && i < name->getLength() && name->getChar(i) == '+';
196  }
197}
198
199FontInfo::FontInfo(FontInfo& f) {
200  name = f.name ? f.name->copy() : NULL;
201  file = f.file ? f.file->copy() : NULL;
202  type = f.type;
203  emb = f.emb;
204  subset = f.subset;
205  hasToUnicode = f.hasToUnicode;
206  fontRef = f.fontRef;
207}
208
209FontInfo::~FontInfo() {
210  delete name;
211  delete file;
212}
Note: See TracBrowser for help on using the repository browser.