2018-11-17 16:48:30 +01:00
|
|
|
// Copyright (C) 2018 Jakub Melka
|
|
|
|
//
|
|
|
|
// This file is part of PdfForQt.
|
|
|
|
//
|
|
|
|
// PdfForQt is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// PdfForQt is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef PDFDOCUMENT_H
|
|
|
|
#define PDFDOCUMENT_H
|
|
|
|
|
|
|
|
#include "pdfglobal.h"
|
2018-11-25 14:48:08 +01:00
|
|
|
#include "pdfobject.h"
|
2018-11-17 16:48:30 +01:00
|
|
|
|
2018-12-02 17:53:19 +01:00
|
|
|
#include <QtCore>
|
|
|
|
#include <QDateTime>
|
|
|
|
|
2018-11-17 16:48:30 +01:00
|
|
|
namespace pdf
|
|
|
|
{
|
|
|
|
|
2018-11-25 14:48:08 +01:00
|
|
|
/// Storage for objects. This class is not thread safe for writing (calling non-const functions). Caller must ensure
|
|
|
|
/// locking, if this object is used from multiple threads. Calling const functions should be thread safe.
|
|
|
|
class PDFObjectStorage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
constexpr inline PDFObjectStorage() = default;
|
|
|
|
|
|
|
|
constexpr inline PDFObjectStorage(const PDFObjectStorage&) = default;
|
|
|
|
constexpr inline PDFObjectStorage(PDFObjectStorage&&) = default;
|
|
|
|
|
|
|
|
constexpr inline PDFObjectStorage& operator=(const PDFObjectStorage&) = default;
|
|
|
|
constexpr inline PDFObjectStorage& operator=(PDFObjectStorage&&) = default;
|
|
|
|
|
|
|
|
struct Entry
|
|
|
|
{
|
|
|
|
constexpr inline explicit Entry() = default;
|
|
|
|
inline explicit Entry(PDFInteger generation, PDFObject object) : generation(generation), object(std::move(object)) { }
|
|
|
|
|
|
|
|
PDFInteger generation = 0;
|
|
|
|
PDFObject object;
|
|
|
|
};
|
|
|
|
|
|
|
|
using PDFObjects = std::vector<Entry>;
|
|
|
|
|
2018-12-01 11:36:07 +01:00
|
|
|
explicit PDFObjectStorage(PDFObjects&& objects, PDFObject&& trailerDictionary) :
|
|
|
|
m_objects(std::move(objects)),
|
|
|
|
m_trailerDictionary(std::move(trailerDictionary))
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-12-02 17:53:19 +01:00
|
|
|
/// Returns object from the object storage. If invalid reference is passed,
|
|
|
|
/// then null object is returned (no exception is thrown).
|
|
|
|
const PDFObject& getObject(PDFObjectReference reference) const;
|
|
|
|
|
2018-12-01 11:36:07 +01:00
|
|
|
/// Returns array of objects stored in this storage
|
|
|
|
const PDFObjects& getObjects() const { return m_objects; }
|
|
|
|
|
|
|
|
/// Returns trailer dictionary
|
|
|
|
const PDFObject& getTrailerDictionary() const { return m_trailerDictionary; }
|
|
|
|
|
2018-11-25 14:48:08 +01:00
|
|
|
private:
|
2018-12-01 11:36:07 +01:00
|
|
|
PDFObjects m_objects;
|
|
|
|
PDFObject m_trailerDictionary;
|
2018-11-25 14:48:08 +01:00
|
|
|
};
|
|
|
|
|
2018-12-01 11:36:07 +01:00
|
|
|
/// PDF document main class.
|
2018-11-17 16:48:30 +01:00
|
|
|
class PDFDocument
|
|
|
|
{
|
2018-12-02 17:53:19 +01:00
|
|
|
Q_DECLARE_TR_FUNCTIONS(pdf::PDFDocument)
|
|
|
|
|
2018-11-17 16:48:30 +01:00
|
|
|
public:
|
|
|
|
explicit PDFDocument() = default;
|
2018-11-25 14:48:08 +01:00
|
|
|
|
2018-12-01 11:36:07 +01:00
|
|
|
const PDFObjectStorage& getStorage() const { return m_pdfObjectStorage; }
|
|
|
|
|
2018-12-02 17:53:19 +01:00
|
|
|
/// Info about the document. Title, Author, Keywords...
|
|
|
|
struct Info
|
|
|
|
{
|
|
|
|
/// Indicates, that document was modified that it includes trapping information.
|
|
|
|
/// See PDF Reference 1.7, Section 10.10.5 "Trapping Support".
|
|
|
|
enum class Trapped
|
|
|
|
{
|
|
|
|
True, ///< Fully trapped
|
|
|
|
False, ///< Not yet trapped
|
|
|
|
Unknown ///< Either unknown, or it has been trapped partly, not fully
|
|
|
|
};
|
|
|
|
|
|
|
|
QString title;
|
|
|
|
QString author;
|
|
|
|
QString subject;
|
|
|
|
QString keywords;
|
|
|
|
QString creator;
|
|
|
|
QString producer;
|
|
|
|
QDateTime creationDate;
|
|
|
|
QDateTime modifiedDate;
|
|
|
|
Trapped trapped = Trapped::Unknown;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Returns info about the document (title, author, etc.)
|
|
|
|
const Info* getInfo() const { return &m_info; }
|
|
|
|
|
2018-12-14 19:41:12 +01:00
|
|
|
/// If object is reference, the dereference attempt is performed
|
|
|
|
/// and object is returned. If it is not a reference, then self
|
|
|
|
/// is returned. If dereference attempt fails, then null object
|
|
|
|
/// is returned (no exception is thrown).
|
|
|
|
const PDFObject& getObject(const PDFObject& object) const;
|
|
|
|
|
2018-11-25 14:48:08 +01:00
|
|
|
private:
|
2018-12-01 11:36:07 +01:00
|
|
|
friend class PDFDocumentReader;
|
|
|
|
|
|
|
|
explicit PDFDocument(PDFObjectStorage&& storage) :
|
|
|
|
m_pdfObjectStorage(std::move(storage))
|
|
|
|
{
|
2018-12-02 17:53:19 +01:00
|
|
|
init();
|
2018-12-01 11:36:07 +01:00
|
|
|
}
|
|
|
|
|
2018-12-02 17:53:19 +01:00
|
|
|
/// Initialize data based on object in the storage.
|
|
|
|
/// Can throw exception if error is detected.
|
|
|
|
void init();
|
|
|
|
|
|
|
|
/// Initialize the document info from the trailer dictionary.
|
|
|
|
/// If document info is not present, then default document
|
|
|
|
/// info is used. If error is detected, exception is thrown.
|
|
|
|
void initInfo();
|
|
|
|
|
2018-11-25 14:48:08 +01:00
|
|
|
/// Storage of objects
|
|
|
|
PDFObjectStorage m_pdfObjectStorage;
|
2018-12-02 17:53:19 +01:00
|
|
|
|
|
|
|
/// Info about the PDF document
|
|
|
|
Info m_info;
|
2018-11-17 16:48:30 +01:00
|
|
|
};
|
|
|
|
|
2018-12-02 17:53:19 +01:00
|
|
|
inline
|
|
|
|
const PDFObject& PDFDocument::getObject(const PDFObject& object) const
|
|
|
|
{
|
|
|
|
if (object.isReference())
|
|
|
|
{
|
|
|
|
// Try to dereference the object
|
|
|
|
return m_pdfObjectStorage.getObject(object.getReference());
|
|
|
|
}
|
|
|
|
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
2018-11-17 16:48:30 +01:00
|
|
|
} // namespace pdf
|
|
|
|
|
|
|
|
#endif // PDFDOCUMENT_H
|