root/middleware-offline/trunk/_src/eidmw/pteid-poppler/poppler/FontInfo.cc @ 226

Revision 226, 6.2 KB (checked in by vsilva, 8 years ago)

Improve PDF native Signature

Line 
1//========================================================================
2//
3// FontInfo.cc
4//
5// Copyright (C) 2005, 2006 Kristian HÞgsberg <krh@redhat.com>
6// Copyright (C) 2005-2008, 2010 Albert Astals Cid <aacid@kde.org>
7// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
8// Copyright (C) 2006 Kouhei Sutou <kou@cozmixng.org>
9// Copyright (C) 2009 Pino Toscano <pino@kde.org>
10// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
11// Copyright (C) 2010, 2012 Adrian Johnson <ajohnson@redneon.com>
12// Copyright (C) 2010 Thomas Freitag <Thomas.Freitag@alfa.de>
13// Copyright (C) 2011 Carlos Garcia Campos <carlosgc@gnome.org>
14// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
15//
16// To see a description of the changes please see the Changelog file that
17// came with your tarball or type make ChangeLog if you are building from git
18//
19//========================================================================
20
21//========================================================================
22//
23// Based on code from pdffonts.cc
24//
25// Copyright 2001-2007 Glyph & Cog, LLC
26//
27//========================================================================
28
29#include "config.h"
30#include <stdio.h>
31#include <stdlib.h>
32#include <stddef.h>
33#include <string.h>
34#include <math.h>
35#include "GlobalParams.h"
36#include "Error.h"
37#include "Object.h"
38#include "Dict.h"
39#include "GfxFont.h"
40#include "Annot.h"
41#include "PDFDoc.h"
42#include "FontInfo.h"
43
44FontInfoScanner::FontInfoScanner(PDFDoc *docA, int firstPage) {
45  doc = docA;
46  currentPage = firstPage + 1;
47}
48
49FontInfoScanner::~FontInfoScanner() {
50}
51
52GooList *FontInfoScanner::scan(int nPages) {
53  GooList *result;
54  Page *page;
55  Dict *resDict;
56  Annots *annots;
57  Object obj1;
58  int lastPage;
59
60  if (currentPage > doc->getNumPages()) {
61    return NULL;
62  }
63 
64  result = new GooList();
65
66  lastPage = currentPage + nPages;
67  if (lastPage > doc->getNumPages() + 1) {
68    lastPage = doc->getNumPages() + 1;
69  }
70
71  for (int pg = currentPage; pg < lastPage; ++pg) {
72    page = doc->getPage(pg);
73    if (!page) continue;
74
75    if ((resDict = page->getResourceDict())) {
76      scanFonts(resDict, result);
77    }
78    annots = page->getAnnots();
79    for (int i = 0; i < annots->getNumAnnots(); ++i) {
80      if (annots->getAnnot(i)->getAppearanceResDict(&obj1)->isDict()) {
81        scanFonts(obj1.getDict(), result);
82      }
83      obj1.free();
84    }
85  }
86
87  currentPage = lastPage;
88
89  return result;
90}
91
92void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) {
93  Object obj1, obj2, objDict, resObj;
94  Ref r;
95  GfxFontDict *gfxFontDict;
96  GfxFont *font;
97  int i;
98
99  // scan the fonts in this resource dictionary
100  gfxFontDict = NULL;
101  resDict->lookupNF("Font", &obj1);
102  if (obj1.isRef()) {
103    obj1.fetch(doc->getXRef(), &obj2);
104    if (obj2.isDict()) {
105      r = obj1.getRef();
106      gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict());
107    }
108    obj2.free();
109  } else if (obj1.isDict()) {
110    gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict());
111  }
112  if (gfxFontDict) {
113    for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {
114      if ((font = gfxFontDict->getFont(i))) {
115        Ref fontRef = *font->getID();
116
117        // add this font to the list if not already found
118        if (fonts.find(fontRef.num) == fonts.end()) {
119          fontsList->append(new FontInfo(font, doc));
120          fonts.insert(fontRef.num);
121        }
122      }
123    }
124    delete gfxFontDict;
125  }
126  obj1.free();
127
128  // recursively scan any resource dictionaries in objects in this
129  // resource dictionary
130  const char *resTypes[] = { "XObject", "Pattern" };
131  for (Guint resType = 0; resType < sizeof(resTypes) / sizeof(resTypes[0]); ++resType) {
132    resDict->lookup(resTypes[resType], &objDict);
133    if (objDict.isDict()) {
134      for (i = 0; i < objDict.dictGetLength(); ++i) {
135        objDict.dictGetValNF(i, &obj1);
136        if (obj1.isRef()) {
137          // check for an already-seen object
138          const Ref r = obj1.getRef();
139          if (visitedObjects.find(r.num) != visitedObjects.end()) {
140            obj1.free();
141            continue;
142          }
143
144          visitedObjects.insert(r.num);
145        }
146
147        obj1.fetch(doc->getXRef(), &obj2);
148
149        if (obj2.isStream()) {
150          obj2.streamGetDict()->lookup("Resources", &resObj);
151          if (resObj.isDict() && resObj.getDict() != resDict) {
152            scanFonts(resObj.getDict(), fontsList);
153          }
154          resObj.free();
155        }
156        obj1.free();
157        obj2.free();
158      }
159    }
160    objDict.free();
161  }
162}
163
164FontInfo::FontInfo(GfxFont *font, PDFDoc *doc) {
165  GooString *origName;
166  Object fontObj, toUnicodeObj;
167  int i;
168
169  fontRef = *font->getID();
170
171  // font name
172  origName = font->getName();
173  if (origName != NULL) {
174    name = font->getName()->copy();
175  } else {
176    name = NULL;
177  }
178
179  // font type
180  type = (FontInfo::Type)font->getType();
181
182  // check for an embedded font
183  if (font->getType() == fontType3) {
184    emb = gTrue;
185  } else {
186    emb = font->getEmbeddedFontID(&embRef);
187  }
188
189  file = NULL;
190  substituteName = NULL;
191  if (!emb)
192  {
193    SysFontType dummy;
194    int dummy2;
195    GooString substituteNameAux;
196    file = globalParams->findSystemFontFile(font, &dummy, &dummy2, &substituteNameAux);
197    if (substituteNameAux.getLength() > 0)
198        substituteName = substituteNameAux.copy();
199  }
200  encoding = font->getEncodingName()->copy();
201
202  // look for a ToUnicode map
203  hasToUnicode = gFalse;
204  if (doc->getXRef()->fetch(fontRef.num, fontRef.gen, &fontObj)->isDict()) {
205    hasToUnicode = fontObj.dictLookup("ToUnicode", &toUnicodeObj)->isStream();
206    toUnicodeObj.free();
207  }
208  fontObj.free();
209
210  // check for a font subset name: capital letters followed by a '+'
211  // sign
212  subset = gFalse;
213  if (name) {
214    for (i = 0; i < name->getLength(); ++i) {
215      if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') {
216        break;
217      }
218    }
219    subset = i > 0 && i < name->getLength() && name->getChar(i) == '+';
220  }
221}
222
223FontInfo::FontInfo(FontInfo& f) {
224  name = f.name ? f.name->copy() : NULL;
225  file = f.file ? f.file->copy() : NULL;
226  encoding = f.encoding ? f.encoding->copy() : NULL;
227  type = f.type;
228  emb = f.emb;
229  subset = f.subset;
230  hasToUnicode = f.hasToUnicode;
231  fontRef = f.fontRef;
232  embRef = f.embRef;
233}
234
235FontInfo::~FontInfo() {
236  delete name;
237  delete file;
238  delete encoding;
239  if (substituteName)
240    delete substituteName;
241}
Note: See TracBrowser for help on using the browser.