File indexing completed on 2024-05-12 16:06:47

0001 /*
0002     SPDX-FileCopyrightText: 2004-2008 Albert Astals Cid <aacid@kde.org>
0003     SPDX-FileCopyrightText: 2004 Enrico Ros <eros.kde@email.it>
0004 
0005     Work sponsored by the LiMux project of the city of Munich:
0006     SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #ifndef _OKULAR_GENERATOR_PDF_H_
0012 #define _OKULAR_GENERATOR_PDF_H_
0013 
0014 //#include "synctex/synctex_parser.h"
0015 
0016 #include <poppler-qt6.h>
0017 #include <poppler-version.h>
0018 
0019 #define POPPLER_VERSION_MACRO ((POPPLER_VERSION_MAJOR << 16) | (POPPLER_VERSION_MINOR << 8) | (POPPLER_VERSION_MICRO))
0020 
0021 #include <QBitArray>
0022 #include <QPointer>
0023 
0024 #include <core/annotations.h>
0025 #include <core/document.h>
0026 #include <core/generator.h>
0027 #include <core/printoptionswidget.h>
0028 #include <interfaces/configinterface.h>
0029 #include <interfaces/printinterface.h>
0030 #include <interfaces/saveinterface.h>
0031 
0032 #include <unordered_map>
0033 
0034 class PDFOptionsPage;
0035 class PopplerAnnotationProxy;
0036 
0037 /**
0038  * @short A generator that builds contents from a PDF document.
0039  *
0040  * All Generator features are supported and implemented by this one.
0041  * Internally this holds a reference to xpdf's core objects and provides
0042  * contents generation using the PDFDoc object and a couple of OutputDevices
0043  * called Okular::OutputDev and Okular::TextDev (both defined in gp_outputdev.h).
0044  *
0045  * For generating page contents we tell PDFDoc to render a page and grab
0046  * contents from out OutputDevs when rendering finishes.
0047  *
0048  */
0049 class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, public Okular::PrintInterface, public Okular::SaveInterface
0050 {
0051     Q_OBJECT
0052     Q_INTERFACES(Okular::Generator)
0053     Q_INTERFACES(Okular::ConfigInterface)
0054     Q_INTERFACES(Okular::PrintInterface)
0055     Q_INTERFACES(Okular::SaveInterface)
0056 
0057 public:
0058     PDFGenerator(QObject *parent, const QVariantList &args);
0059     ~PDFGenerator() override;
0060 
0061     // [INHERITED] load a document and fill up the pagesVector
0062     Okular::Document::OpenResult loadDocumentWithPassword(const QString &filePath, QVector<Okular::Page *> &pagesVector, const QString &password) override;
0063     Okular::Document::OpenResult loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector<Okular::Page *> &pagesVector, const QString &password) override;
0064     void loadPages(QVector<Okular::Page *> &pagesVector, int rotation = -1, bool clear = false);
0065     // [INHERITED] document information
0066     Okular::DocumentInfo generateDocumentInfo(const QSet<Okular::DocumentInfo::Key> &keys) const override;
0067     const Okular::DocumentSynopsis *generateDocumentSynopsis() override;
0068     Okular::FontInfo::List fontsForPage(int page) override;
0069     const QList<Okular::EmbeddedFile *> *embeddedFiles() const override;
0070     PageSizeMetric pagesSizeMetric() const override
0071     {
0072         return Pixels;
0073     }
0074     QAbstractItemModel *layersModel() const override;
0075     void opaqueAction(const Okular::BackendOpaqueAction *action) override;
0076     void freeOpaqueActionContents(const Okular::BackendOpaqueAction &action) override;
0077 
0078     // [INHERITED] document information
0079     bool isAllowed(Okular::Permission permission) const override;
0080 
0081     // [INHERITED] perform actions on document / pages
0082     QImage image(Okular::PixmapRequest *request) override;
0083 
0084     // [INHERITED] print page using an already configured kprinter
0085     Okular::Document::PrintError print(QPrinter &printer) override;
0086 
0087     // [INHERITED] reply to some metadata requests
0088     QVariant metaData(const QString &key, const QVariant &option) const override;
0089 
0090     // [INHERITED] reparse configuration
0091     bool reparseConfig() override;
0092     void addPages(KConfigDialog *) override;
0093 
0094     // [INHERITED] text exporting
0095     Okular::ExportFormat::List exportFormats() const override;
0096     bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override;
0097 
0098     // [INHERITED] print interface
0099     Okular::PrintOptionsWidget *printConfigurationWidget() const override;
0100 
0101     // [INHERITED] save interface
0102     bool supportsOption(SaveOption) const override;
0103     bool save(const QString &fileName, SaveOptions options, QString *errorText) override;
0104     Okular::AnnotationProxy *annotationProxy() const override;
0105 
0106     bool canSign() const override;
0107     bool sign(const Okular::NewSignatureData &oData, const QString &rFilename) override;
0108 
0109     Okular::CertificateStore *certificateStore() const override;
0110 
0111     QByteArray requestFontData(const Okular::FontInfo &font) override;
0112 
0113     static void okularToPoppler(const Okular::NewSignatureData &oData, Poppler::PDFConverter::NewSignatureData *pData);
0114 
0115 protected:
0116     SwapBackingFileResult swapBackingFile(QString const &newFileName, QVector<Okular::Page *> &newPagesVector) override;
0117     bool doCloseDocument() override;
0118     Okular::TextPage *textPage(Okular::TextRequest *request) override;
0119 
0120 private:
0121     Okular::Document::OpenResult init(QVector<Okular::Page *> &pagesVector, const QString &password);
0122 
0123     // create the document synopsis hierarchy
0124     void addSynopsisChildren(const QVector<Poppler::OutlineItem> &outlineItems, QDomNode *parentDestination);
0125     // fetch annotations from the pdf file and add they to the page
0126     void addAnnotations(Poppler::Page *popplerPage, Okular::Page *page);
0127     // fetch the transition information and add it to the page
0128     void addTransition(Poppler::Page *pdfPage, Okular::Page *page);
0129     // fetch the poppler page form fields
0130     QList<Okular::FormField *> getFormFields(Poppler::Page *popplerPage);
0131 
0132     Okular::TextPage *abstractTextPage(const std::vector<std::unique_ptr<Poppler::TextBox>> &text, double height, double width, int rot);
0133 
0134     void resolveMediaLinkReferences(Okular::Page *page);
0135     void resolveMediaLinkReference(Okular::Action *action);
0136 
0137     bool setDocumentRenderHints();
0138 
0139     // poppler dependent stuff
0140     std::unique_ptr<Poppler::Document> pdfdoc;
0141 
0142     void xrefReconstructionHandler();
0143 
0144     // misc variables for document info and synopsis caching
0145     bool docSynopsisDirty;
0146     bool xrefReconstructed;
0147     Okular::DocumentSynopsis docSyn;
0148     mutable bool docEmbeddedFilesDirty;
0149     mutable QList<Okular::EmbeddedFile *> docEmbeddedFiles;
0150     int nextFontPage;
0151     PopplerAnnotationProxy *annotProxy;
0152     mutable Okular::CertificateStore *certStore;
0153     // the hash below only contains annotations that were present on the file at open time
0154     // this is enough for what we use it for
0155     QHash<Okular::Annotation *, Poppler::Annotation *> annotationsOnOpenHash;
0156 
0157     QBitArray rectsGenerated;
0158 
0159     QPointer<PDFOptionsPage> pdfOptionsPage;
0160 };
0161 
0162 #endif
0163 
0164 /* kate: replace-tabs on; indent-width 4; */