~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/poppler/poppler/FontInfo.cc

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
Import upstream version 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

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