1 /* poppler-private.h: qt interface to poppler
2  * Copyright (C) 2005, Net Integration Technologies, Inc.
3  * Copyright (C) 2005, 2008, Brad Hards <bradh@frogmouth.net>
4  * Copyright (C) 2006-2009, 2011 by Albert Astals Cid <aacid@kde.org>
5  * Copyright (C) 2007-2009 by Pino Toscano <pino@kde.org>
6  * Inspired on code by
7  * Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es>
8  * Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2, or (at your option)
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 #ifndef _POPPLER_PRIVATE_H_
26 #define _POPPLER_PRIVATE_H_
27 
28 #include <QtCore/QPointer>
29 #include <QtCore/QVector>
30 
31 #include <config.h>
32 #include <GfxState.h>
33 #include <GlobalParams.h>
34 #include <PDFDoc.h>
35 #include <FontInfo.h>
36 #include <OutputDev.h>
37 #include <Error.h>
38 #if defined(HAVE_SPLASH)
39 #include <SplashOutputDev.h>
40 #endif
41 
42 #include "poppler-qt4.h"
43 
44 class LinkDest;
45 class FormWidget;
46 
47 namespace Poppler {
48 
49     /* borrowed from kpdf */
50     QString unicodeToQString(Unicode* u, int len);
51 
52     QString UnicodeParsedString(GooString *s1);
53 
54     GooString *QStringToUnicodeGooString(const QString &s);
55 
56     GooString *QStringToGooString(const QString &s);
57 
58     void qt4ErrorFunction(int pos, char *msg, va_list args);
59 
60     class LinkDestinationData
61     {
62         public:
LinkDestinationData(LinkDest * l,GooString * nd,Poppler::DocumentData * pdfdoc,bool external)63             LinkDestinationData( LinkDest *l, GooString *nd, Poppler::DocumentData *pdfdoc, bool external )
64              : ld(l), namedDest(nd), doc(pdfdoc), externalDest(external)
65             {
66             }
67 
68             LinkDest *ld;
69             GooString *namedDest;
70             Poppler::DocumentData *doc;
71             bool externalDest;
72     };
73 
74     class DocumentData {
75     public:
DocumentData(GooString * filePath,GooString * ownerPassword,GooString * userPassword)76 	DocumentData(GooString *filePath, GooString *ownerPassword, GooString *userPassword)
77 	    {
78 		doc = new PDFDoc(filePath, ownerPassword, userPassword);
79 		init(ownerPassword, userPassword);
80 	    }
81 
DocumentData(const QByteArray & data,GooString * ownerPassword,GooString * userPassword)82 	DocumentData(const QByteArray &data, GooString *ownerPassword, GooString *userPassword)
83 	    {
84 		Object obj;
85 		fileContents = data;
86 		obj.initNull();
87 		MemStream *str = new MemStream((char*)fileContents.data(), 0, fileContents.length(), &obj);
88 	        doc = new PDFDoc(str, ownerPassword, userPassword);
89 		init(ownerPassword, userPassword);
90 	    }
91 
92 	void init(GooString *ownerPassword, GooString *userPassword);
93 
94 	~DocumentData();
95 
getOutputDev()96 	OutputDev *getOutputDev()
97 	{
98 		if (!m_outputDev)
99 		{
100 			switch (m_backend)
101 			{
102 			case Document::ArthurBackend:
103 			// create a splash backend even in case of the Arthur Backend
104 			case Document::SplashBackend:
105 			{
106 #if defined(HAVE_SPLASH)
107 			SplashColor bgColor;
108 			bgColor[0] = paperColor.blue();
109 			bgColor[1] = paperColor.green();
110 			bgColor[2] = paperColor.red();
111 			GBool AA = m_hints & Document::TextAntialiasing ? gTrue : gFalse;
112 			SplashOutputDev * splashOutputDev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue, AA);
113 			splashOutputDev->setVectorAntialias(m_hints & Document::Antialiasing ? gTrue : gFalse);
114 			splashOutputDev->setFreeTypeHinting(m_hints & Document::TextHinting ? gTrue : gFalse);
115 			splashOutputDev->startDoc(doc->getXRef());
116 			m_outputDev = splashOutputDev;
117 #endif
118 			break;
119 			}
120 			}
121 		}
122 		return m_outputDev;
123 	}
124 
125 	void addTocChildren( QDomDocument * docSyn, QDomNode * parent, GooList * items );
126 
setPaperColor(const QColor & color)127 	void setPaperColor(const QColor &color)
128 	{
129 		if (color == paperColor)
130 			return;
131 
132 		paperColor = color;
133 		if ( m_outputDev == NULL )
134 			return;
135 
136 		switch ( m_backend )
137 		{
138 			case Document::SplashBackend:
139 			{
140 #if defined(HAVE_SPLASH)
141 				SplashOutputDev *splash_output = static_cast<SplashOutputDev *>( m_outputDev );
142 				SplashColor bgColor;
143 				bgColor[0] = paperColor.blue();
144 				bgColor[1] = paperColor.green();
145 				bgColor[2] = paperColor.red();
146 				splash_output->setPaperColor(bgColor);
147 #endif
148 				break;
149 			}
150 			default: ;
151 		}
152 	}
153 
fillMembers()154 	void fillMembers()
155 	{
156 		m_fontInfoIterator = new FontIterator(0, this);
157 		int numEmb = doc->getCatalog()->numEmbeddedFiles();
158 		if (!(0 == numEmb)) {
159 			// we have some embedded documents, build the list
160 			for (int yalv = 0; yalv < numEmb; ++yalv) {
161 				EmbFile *ef = doc->getCatalog()->embeddedFile(yalv);
162 				m_embeddedFiles.append(new EmbeddedFile(ef));
163 			}
164 		}
165 	}
166 
167 	static Document *checkDocument(DocumentData *doc);
168 
169 	PDFDoc *doc;
170 	QByteArray fileContents;
171 	bool locked;
172 	FontIterator *m_fontInfoIterator;
173 	Document::RenderBackend m_backend;
174 	OutputDev *m_outputDev;
175 	QList<EmbeddedFile*> m_embeddedFiles;
176 	QPointer<OptContentModel> m_optContentModel;
177 	QColor paperColor;
178 	int m_hints;
179 	static int count;
180     };
181 
182     class FontInfoData
183     {
184 	public:
FontInfoData()185 		FontInfoData()
186 		{
187 			isEmbedded = false;
188 			isSubset = false;
189 			type = FontInfo::unknown;
190 		}
191 
FontInfoData(const FontInfoData & fid)192 		FontInfoData( const FontInfoData &fid )
193 		{
194 			fontName = fid.fontName;
195 			fontFile = fid.fontFile;
196 			isEmbedded = fid.isEmbedded;
197 			isSubset = fid.isSubset;
198 			type = fid.type;
199 			embRef = fid.embRef;
200 		}
201 
FontInfoData(::FontInfo * fi)202 		FontInfoData( ::FontInfo* fi )
203 		{
204 			if (fi->getName()) fontName = fi->getName()->getCString();
205 			if (fi->getFile()) fontFile = fi->getFile()->getCString();
206 			isEmbedded = fi->getEmbedded();
207 			isSubset = fi->getSubset();
208 			type = (Poppler::FontInfo::Type)fi->getType();
209 			embRef = fi->getEmbRef();
210 		}
211 
212 		QString fontName;
213 		QString fontFile;
214 		bool isEmbedded : 1;
215 		bool isSubset : 1;
216 		FontInfo::Type type;
217 		Ref embRef;
218     };
219 
220     class FontIteratorData
221     {
222 	public:
FontIteratorData(int startPage,DocumentData * dd)223 		FontIteratorData( int startPage, DocumentData *dd )
224 		  : fontInfoScanner( dd->doc, startPage )
225 		  , totalPages( dd->doc->getNumPages() )
226 		  , currentPage( qMax( startPage, 0 ) - 1 )
227 		{
228 		}
229 
~FontIteratorData()230 		~FontIteratorData()
231 		{
232 		}
233 
234 		FontInfoScanner fontInfoScanner;
235 		int totalPages;
236 		int currentPage;
237     };
238 
239     class TextBoxData
240     {
241 	public:
TextBoxData()242 		TextBoxData()
243 		  : nextWord(0), hasSpaceAfter(false)
244 		{
245 		}
246 
247 		QString text;
248 		QRectF bBox;
249 		TextBox *nextWord;
250 		QVector<QRectF> charBBoxes; // the boundingRect of each character
251 		bool hasSpaceAfter;
252     };
253 
254     class FormFieldData
255     {
256 	public:
FormFieldData(DocumentData * _doc,::Page * p,::FormWidget * w)257 		FormFieldData(DocumentData *_doc, ::Page *p, ::FormWidget *w) :
258 		doc(_doc), page(p), fm(w), flags(0), annoflags(0)
259 		{
260 		}
261 
textAlignment(Object * obj)262 		Qt::Alignment textAlignment(Object *obj) const
263 		{
264 			Object tmp;
265 			int align = 0;
266 			if (obj->dictLookup("Q", &tmp)->isInt())
267 			{
268 				align = tmp.getInt();
269 			}
270 			tmp.free();
271 			Qt::Alignment qtalign;
272 			switch ( align )
273 			{
274 				case 1:
275 					qtalign = Qt::AlignHCenter;
276 					break;
277 				case 2:
278 					qtalign = Qt::AlignRight;
279 					break;
280 				case 0:
281 				default:
282 					qtalign = Qt::AlignLeft;
283 			}
284 			return qtalign;
285 		}
286 
287 		DocumentData *doc;
288 		::Page *page;
289 		::FormWidget *fm;
290 		QRectF box;
291 		int flags;
292 		int annoflags;
293     };
294 
295 }
296 
297 #endif
298