1
//========================================================================
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>
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
17
//========================================================================
19
//========================================================================
21
// Based on code from pdffonts.cc
23
// Copyright 2001-2007 Glyph & Cog, LLC
25
//========================================================================
33
#include "GlobalParams.h"
42
FontInfoScanner::FontInfoScanner(PDFDoc *docA, int firstPage) {
44
currentPage = firstPage + 1;
47
FontInfoScanner::~FontInfoScanner() {
50
GooList *FontInfoScanner::scan(int nPages) {
58
if (currentPage > doc->getNumPages()) {
62
result = new GooList();
64
lastPage = currentPage + nPages;
65
if (lastPage > doc->getNumPages() + 1) {
66
lastPage = doc->getNumPages() + 1;
69
for (int pg = currentPage; pg < lastPage; ++pg) {
70
page = doc->getPage(pg);
73
if ((resDict = page->getResourceDict())) {
74
scanFonts(resDict, result);
76
annots = new Annots(doc->getXRef(), doc->getCatalog(), page->getAnnots(&obj1));
78
for (int i = 0; i < annots->getNumAnnots(); ++i) {
79
if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
80
obj1.streamGetDict()->lookup("Resources", &obj2);
82
scanFonts(obj2.getDict(), result);
91
currentPage = lastPage;
96
void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) {
97
Object obj1, obj2, objDict, resObj;
99
GfxFontDict *gfxFontDict;
103
// scan the fonts in this resource dictionary
105
resDict->lookupNF("Font", &obj1);
107
obj1.fetch(doc->getXRef(), &obj2);
110
gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict());
113
} else if (obj1.isDict()) {
114
gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict());
117
for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {
118
if ((font = gfxFontDict->getFont(i))) {
119
Ref fontRef = *font->getID();
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);
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);
141
// check for an already-seen object
142
const Ref r = obj1.getRef();
143
if (visitedObjects.find(r.num) != visitedObjects.end()) {
148
visitedObjects.insert(r.num);
151
obj1.fetch(doc->getXRef(), &obj2);
153
if (obj2.isStream()) {
154
obj2.streamGetDict()->lookup("Resources", &resObj);
155
if (resObj.isDict() && resObj.getDict() != resDict) {
156
scanFonts(resObj.getDict(), fontsList);
168
FontInfo::FontInfo(GfxFont *font, PDFDoc *doc) {
170
Object fontObj, toUnicodeObj;
173
fontRef = *font->getID();
176
origName = font->getOrigName();
177
if (origName != NULL) {
178
name = font->getOrigName()->copy();
184
type = (FontInfo::Type)font->getType();
186
// check for an embedded font
187
if (font->getType() == fontType3) {
190
emb = font->getEmbeddedFontID(&embRef);
195
DisplayFontParam *dfp = globalParams->getDisplayFont(font);
198
if (dfp->kind == displayFontT1) file = dfp->t1.fileName->copy();
199
else file = dfp->tt.fileName->copy();
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();
213
// check for a font subset name: capital letters followed by a '+'
217
for (i = 0; i < name->getLength(); ++i) {
218
if (name->getChar(i) < 'A' || name->getChar(i) > 'Z') {
222
subset = i > 0 && i < name->getLength() && name->getChar(i) == '+';
226
FontInfo::FontInfo(FontInfo& f) {
227
name = f.name ? f.name->copy() : NULL;
228
file = f.file ? f.file->copy() : NULL;
232
hasToUnicode = f.hasToUnicode;
237
FontInfo::~FontInfo() {