1 #include "pdfdocumentreference.h"
2 #include "pdfpagereference.h"
3 
4 #include <stdexcept>
5 #include <QFile>
6 #include "debug.h"
7 
popplerDocument() const8 QSharedPointer< const Poppler::Document > PDFDocumentReference::popplerDocument() const
9 {
10 	// Make sure this function is "single threaded"
11 	Lock lk{mutex_};
12 
13 	if ( ! popplerDocument_ ) {
14 		/** No document defined yet. Create it from the disk/memory cache. */
15 
16 		QSharedPointer<Poppler::Document> m_document;
17 		if ( cacheOption() == PDFCacheOption::rereadFromDisk ) {
18 			DEBUGOUT << "Trying to build a Poppler::Document from file" << filename();
19 			QSharedPointer<Poppler::Document> diskDocument( Poppler::Document::load(filename()) );
20 			m_document.swap(diskDocument);
21 		}
22 		else if ( cacheOption() == PDFCacheOption::keepPDFinMemory ) {
23 			DEBUGOUT << "Trying to build a document from" << fileContents_.size() << "byte memory cache";
24 			QSharedPointer<Poppler::Document> memoryDocument( Poppler::Document::loadFromData(fileContents_) );
25 			m_document.swap(memoryDocument);
26 		}
27 		if ( !m_document || m_document->isLocked() )
28 			throw std::runtime_error("Document not readable");
29 		m_document->setRenderHint(Poppler::Document::Antialiasing, true);
30 		m_document->setRenderHint(Poppler::Document::TextAntialiasing, true);
31 		m_document->setRenderHint(Poppler::Document::TextHinting, true);
32 		popplerDocument_ = m_document;
33 	}
34   return popplerDocument_;
35 }
36 
page(unsigned int pageNumber) const37 PDFPageReference PDFDocumentReference::page(unsigned int pageNumber) const
38 {
39   PDFPageReference ppr(*this, pageNumber);
40   return ppr;
41 }
42 
PDFDocumentReference(const QString & theFilename,const PDFCacheOption & theCacheOption)43 PDFDocumentReference::PDFDocumentReference(const QString& theFilename, const PDFCacheOption& theCacheOption):
44 filename_(theFilename),
45 fileContents_(),
46 cacheOption_(theCacheOption),
47 mutex_(),
48 popplerDocument_()
49 {
50   if ( cacheOption() == PDFCacheOption::keepPDFinMemory ) {
51     DEBUGOUT << "Reading file into memory";
52     QFile file(filename());
53     file.open(QIODevice::ReadOnly);
54     fileContents_ = file.readAll();
55     DEBUGOUT << fileContents_.size() << "bytes read";
56   }
57 }
cacheOption() const58 const PDFCacheOption& PDFDocumentReference::cacheOption() const
59 {
60   return cacheOption_;
61 }
62 
filename() const63 const QString& PDFDocumentReference::filename() const
64 {
65   return filename_;
66 }
67 
operator =(const PDFDocumentReference & rhs)68 PDFDocumentReference& PDFDocumentReference::operator=(const PDFDocumentReference& rhs)
69 {
70   if ( rhs.filename() != filename() ) {
71     throw std::runtime_error("This PDFDocumentReference has a different filename");
72   }
73   if ( rhs.cacheOption() != cacheOption() ) {
74     throw std::runtime_error("This PDFDocumentReference has a different cache setting");
75   }
76   fileContents_=rhs.fileContents_;
77   popplerDocument_=rhs.popplerDocument_;
78   return *this;
79 }
80 
operator ==(const PDFDocumentReference & lhs,const PDFDocumentReference & rhs)81 bool operator==(const PDFDocumentReference& lhs, const PDFDocumentReference& rhs)
82 {
83   if ( lhs.cacheOption() != rhs.cacheOption() ) {
84     return false;
85   }
86   else if ( lhs.cacheOption() == PDFCacheOption::keepPDFinMemory ) {
87 	  DEBUGOUT << "Using memory cache, comparing byte-by-byte.";
88     return lhs.fileContents_ == rhs.fileContents_;
89   }
90   else {
91 	  DEBUGOUT << "Not using memory cache, just comparing the filename.";
92     return lhs.filename() == rhs.filename();
93   }
94 }
95 
96