2006-09-11 10:44:17 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 2006 Brad Hards <bradh@frogmouth.net>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
This program 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 General Public License for more details.
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2006-10-21 22:10:09 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
2006-09-11 10:44:17 +00:00
|
|
|
02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _OKULAR_GENERATOR_XPS_H_
|
|
|
|
#define _OKULAR_GENERATOR_XPS_H_
|
|
|
|
|
2011-06-01 08:49:49 +00:00
|
|
|
#include <core/generator.h>
|
|
|
|
#include <core/textpage.h>
|
2007-01-03 14:30:48 +00:00
|
|
|
|
2008-06-27 17:18:41 +00:00
|
|
|
#include <QColor>
|
2006-12-28 16:45:50 +00:00
|
|
|
#include <QDomDocument>
|
2007-04-19 18:30:20 +00:00
|
|
|
#include <QFontDatabase>
|
|
|
|
#include <QImage>
|
2006-09-21 11:41:46 +00:00
|
|
|
#include <QLoggingCategory>
|
2007-02-10 17:31:25 +00:00
|
|
|
#include <QStack>
|
2008-09-04 17:30:56 +00:00
|
|
|
#include <QVariant>
|
2018-08-31 09:23:45 +00:00
|
|
|
#include <QXmlDefaultHandler>
|
|
|
|
#include <QXmlStreamReader>
|
2006-09-11 10:44:17 +00:00
|
|
|
|
|
|
|
#include <kzip.h>
|
|
|
|
|
2007-02-08 15:07:54 +00:00
|
|
|
typedef enum { abtCommand, abtNumber, abtComma, abtEOF } AbbPathTokenType;
|
|
|
|
|
2007-02-10 17:31:25 +00:00
|
|
|
class AbbPathToken
|
|
|
|
{
|
|
|
|
public:
|
2007-02-08 15:07:54 +00:00
|
|
|
QString data;
|
|
|
|
int curPos;
|
|
|
|
|
|
|
|
AbbPathTokenType type;
|
2007-02-08 16:41:53 +00:00
|
|
|
char command;
|
|
|
|
double number;
|
2007-02-10 17:31:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
Holds information about xml element during SAX parsing of page
|
|
|
|
*/
|
|
|
|
class XpsRenderNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
QString name;
|
|
|
|
QVector<XpsRenderNode> children;
|
|
|
|
QXmlAttributes attributes;
|
2008-09-04 17:30:56 +00:00
|
|
|
QVariant data;
|
2007-02-08 15:07:54 +00:00
|
|
|
|
2020-01-02 23:16:36 +00:00
|
|
|
const XpsRenderNode *findChild(const QString &name) const;
|
|
|
|
QVariant getRequiredChildData(const QString &name) const;
|
|
|
|
QVariant getChildData(const QString &name) const;
|
2007-02-10 17:31:25 +00:00
|
|
|
};
|
|
|
|
|
2008-06-27 17:18:41 +00:00
|
|
|
struct XpsGradient {
|
|
|
|
XpsGradient(double o, const QColor &c)
|
|
|
|
: offset(o)
|
|
|
|
, color(c)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
double offset;
|
|
|
|
QColor color;
|
|
|
|
};
|
|
|
|
|
2007-02-10 17:31:25 +00:00
|
|
|
/**
|
|
|
|
Types of data in XpsRenderNode::data. Name of each type consist of Xps and
|
|
|
|
name of xml element which data it holds
|
|
|
|
*/
|
2012-09-08 15:06:02 +00:00
|
|
|
typedef QTransform XpsMatrixTransform;
|
|
|
|
typedef QTransform XpsRenderTransform;
|
2007-02-10 17:31:25 +00:00
|
|
|
typedef QBrush XpsFill;
|
2008-06-29 02:15:17 +00:00
|
|
|
struct XpsPathFigure {
|
|
|
|
XpsPathFigure(const QPainterPath &_path, bool filled)
|
|
|
|
: path(_path)
|
|
|
|
, isFilled(filled)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QPainterPath path;
|
|
|
|
bool isFilled;
|
|
|
|
};
|
|
|
|
struct XpsPathGeometry {
|
|
|
|
XpsPathGeometry()
|
|
|
|
: fillRule(Qt::OddEvenFill)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
~XpsPathGeometry()
|
|
|
|
{
|
|
|
|
qDeleteAll(paths);
|
|
|
|
}
|
|
|
|
|
2019-01-09 23:28:49 +00:00
|
|
|
XpsPathGeometry(const XpsPathGeometry &) = delete;
|
|
|
|
XpsPathGeometry &operator=(const XpsPathGeometry &) = delete;
|
|
|
|
|
2008-06-29 02:15:17 +00:00
|
|
|
QList<XpsPathFigure *> paths;
|
|
|
|
Qt::FillRule fillRule;
|
|
|
|
XpsMatrixTransform transform;
|
|
|
|
};
|
2007-02-08 15:07:54 +00:00
|
|
|
|
2006-09-21 11:41:46 +00:00
|
|
|
class XpsPage;
|
2007-02-13 13:26:37 +00:00
|
|
|
class XpsFile;
|
2006-09-21 11:41:46 +00:00
|
|
|
|
|
|
|
class XpsHandler : public QXmlDefaultHandler
|
|
|
|
{
|
|
|
|
public:
|
2018-09-01 08:25:57 +00:00
|
|
|
explicit XpsHandler(XpsPage *page);
|
2019-12-18 11:51:13 +00:00
|
|
|
~XpsHandler() override;
|
2006-09-21 11:41:46 +00:00
|
|
|
|
|
|
|
bool startElement(const QString &nameSpace, const QString &localName, const QString &qname, const QXmlAttributes &atts) override;
|
|
|
|
bool endElement(const QString &nameSpace, const QString &localName, const QString &qname) override;
|
2017-03-02 19:39:24 +00:00
|
|
|
bool startDocument() override;
|
2006-09-21 11:41:46 +00:00
|
|
|
|
2007-02-13 11:13:35 +00:00
|
|
|
protected:
|
|
|
|
XpsPage *m_page;
|
|
|
|
|
2007-02-10 17:31:25 +00:00
|
|
|
void processStartElement(XpsRenderNode &node);
|
|
|
|
void processEndElement(XpsRenderNode &node);
|
|
|
|
|
2018-11-14 19:12:15 +00:00
|
|
|
// Methods for processing of different xml elements
|
2007-02-10 17:31:25 +00:00
|
|
|
void processGlyph(XpsRenderNode &node);
|
|
|
|
void processPath(XpsRenderNode &node);
|
2008-06-29 02:15:17 +00:00
|
|
|
void processPathData(XpsRenderNode &node);
|
2007-02-10 17:31:25 +00:00
|
|
|
void processFill(XpsRenderNode &node);
|
2008-06-28 10:58:57 +00:00
|
|
|
void processStroke(XpsRenderNode &node);
|
2007-02-10 17:31:25 +00:00
|
|
|
void processImageBrush(XpsRenderNode &node);
|
2008-06-29 02:15:17 +00:00
|
|
|
void processPathGeometry(XpsRenderNode &node);
|
|
|
|
void processPathFigure(XpsRenderNode &node);
|
2007-02-10 17:31:25 +00:00
|
|
|
|
2006-09-21 11:41:46 +00:00
|
|
|
QPainter *m_painter;
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2006-09-21 11:41:46 +00:00
|
|
|
QImage m_image;
|
2007-02-10 17:31:25 +00:00
|
|
|
|
|
|
|
QStack<XpsRenderNode> m_nodes;
|
2007-02-08 15:07:54 +00:00
|
|
|
|
|
|
|
friend class XpsPage;
|
2006-09-21 11:41:46 +00:00
|
|
|
};
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
class XpsPage
|
|
|
|
{
|
|
|
|
public:
|
2007-02-13 13:26:37 +00:00
|
|
|
XpsPage(XpsFile *file, const QString &fileName);
|
2006-09-11 10:44:17 +00:00
|
|
|
~XpsPage();
|
|
|
|
|
2019-01-09 23:28:49 +00:00
|
|
|
XpsPage(const XpsPage &) = delete;
|
|
|
|
XpsPage &operator=(const XpsPage &) = delete;
|
|
|
|
|
2008-06-27 00:59:36 +00:00
|
|
|
QSizeF size() const;
|
2006-09-26 11:53:27 +00:00
|
|
|
bool renderToImage(QImage *p);
|
2008-08-03 10:19:05 +00:00
|
|
|
bool renderToPainter(QPainter *painter);
|
2007-02-13 11:13:35 +00:00
|
|
|
Okular::TextPage *textPage();
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2007-02-12 13:31:16 +00:00
|
|
|
QImage loadImageFromFile(const QString &filename);
|
2018-04-08 10:50:46 +00:00
|
|
|
QString fileName() const
|
|
|
|
{
|
|
|
|
return m_fileName;
|
|
|
|
}
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
private:
|
2007-02-13 13:26:37 +00:00
|
|
|
XpsFile *m_file;
|
2006-09-21 11:41:46 +00:00
|
|
|
const QString m_fileName;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
2008-06-27 00:59:36 +00:00
|
|
|
QSizeF m_pageSize;
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
QString m_thumbnailFileName;
|
|
|
|
bool m_thumbnailMightBeAvailable;
|
|
|
|
QImage m_thumbnail;
|
|
|
|
bool m_thumbnailIsLoaded;
|
|
|
|
|
2006-09-26 11:53:27 +00:00
|
|
|
QImage *m_pageImage;
|
2006-09-21 11:41:46 +00:00
|
|
|
bool m_pageIsRendered;
|
2007-02-06 07:07:23 +00:00
|
|
|
|
2006-09-23 00:42:42 +00:00
|
|
|
friend class XpsHandler;
|
2007-02-13 11:13:35 +00:00
|
|
|
friend class XpsTextExtractionHandler;
|
2006-09-11 10:44:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
Represents one of the (perhaps the only) documents in an XpsFile
|
|
|
|
*/
|
|
|
|
class XpsDocument
|
|
|
|
{
|
|
|
|
public:
|
2007-02-13 13:26:37 +00:00
|
|
|
XpsDocument(XpsFile *file, const QString &fileName);
|
2006-09-11 10:44:17 +00:00
|
|
|
~XpsDocument();
|
|
|
|
|
2019-01-09 23:28:49 +00:00
|
|
|
XpsDocument(const XpsDocument &) = delete;
|
|
|
|
XpsDocument &operator=(const XpsDocument &) = delete;
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
/**
|
|
|
|
the total number of pages in this document
|
|
|
|
*/
|
|
|
|
int numPages() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
obtain a certain page from this document
|
|
|
|
|
|
|
|
\param pageNum the number of the page to return
|
|
|
|
|
2007-02-17 10:45:07 +00:00
|
|
|
\note page numbers are zero based - they run from 0 to
|
2006-09-11 10:44:17 +00:00
|
|
|
numPages() - 1
|
|
|
|
*/
|
|
|
|
XpsPage *page(int pageNum) const;
|
|
|
|
|
2007-02-19 10:43:40 +00:00
|
|
|
/**
|
|
|
|
whether this document has a Document Structure
|
|
|
|
*/
|
|
|
|
bool hasDocumentStructure();
|
|
|
|
|
|
|
|
/**
|
|
|
|
the document structure for this document, if available
|
|
|
|
*/
|
|
|
|
const Okular::DocumentSynopsis *documentStructure();
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
private:
|
2007-02-19 10:43:40 +00:00
|
|
|
void parseDocumentStructure(const QString &documentStructureFileName);
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
QList<XpsPage *> m_pages;
|
2007-02-13 13:26:37 +00:00
|
|
|
XpsFile *m_file;
|
2007-02-19 10:43:40 +00:00
|
|
|
bool m_haveDocumentStructure;
|
|
|
|
Okular::DocumentSynopsis *m_docStructure;
|
|
|
|
QMap<QString, int> m_docStructurePageMap;
|
2006-09-11 10:44:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
Represents the contents of a Microsoft XML Paper Specification
|
|
|
|
format document.
|
|
|
|
*/
|
|
|
|
class XpsFile
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
XpsFile();
|
|
|
|
~XpsFile();
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2019-01-09 23:28:49 +00:00
|
|
|
XpsFile(const XpsFile &) = delete;
|
|
|
|
XpsFile &operator=(const XpsFile &) = delete;
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
bool loadDocument(const QString &fileName);
|
|
|
|
bool closeDocument();
|
|
|
|
|
2014-05-11 09:17:49 +00:00
|
|
|
Okular::DocumentInfo generateDocumentInfo() const;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
|
|
|
QImage thumbnail();
|
|
|
|
|
|
|
|
/**
|
|
|
|
the total number of XpsDocuments with this file
|
|
|
|
*/
|
|
|
|
int numDocuments() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
the total number of pages in all the XpsDocuments within this
|
|
|
|
file
|
|
|
|
*/
|
|
|
|
int numPages() const;
|
|
|
|
|
2006-09-21 11:41:46 +00:00
|
|
|
/**
|
|
|
|
a page from the file
|
|
|
|
|
|
|
|
\param pageNum the page number of the page to return
|
|
|
|
|
2007-02-17 10:45:07 +00:00
|
|
|
\note page numbers are zero based - they run from 0 to
|
2006-09-21 11:41:46 +00:00
|
|
|
numPages() - 1
|
|
|
|
*/
|
|
|
|
XpsPage *page(int pageNum) const;
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
/**
|
|
|
|
obtain a certain document from this file
|
|
|
|
|
|
|
|
\param documentNum the number of the document to return
|
|
|
|
|
2007-02-17 10:45:07 +00:00
|
|
|
\note document numbers are zero based - they run from 0 to
|
2006-09-11 10:44:17 +00:00
|
|
|
numDocuments() - 1
|
|
|
|
*/
|
|
|
|
XpsDocument *document(int documentNum) const;
|
2007-02-13 13:26:37 +00:00
|
|
|
|
|
|
|
QFont getFontByName(const QString &absoluteFileName, float size);
|
|
|
|
|
|
|
|
KZip *xpsArchive();
|
2007-02-17 10:45:07 +00:00
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
private:
|
2019-12-20 15:40:59 +00:00
|
|
|
int loadFontByName(const QString &absoluteFileName);
|
2007-02-13 13:26:37 +00:00
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
QList<XpsDocument *> m_documents;
|
2006-09-21 11:41:46 +00:00
|
|
|
QList<XpsPage *> m_pages;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
|
|
|
QString m_thumbnailFileName;
|
|
|
|
bool m_thumbnailMightBeAvailable;
|
|
|
|
QImage m_thumbnail;
|
|
|
|
bool m_thumbnailIsLoaded;
|
|
|
|
|
|
|
|
QString m_corePropertiesFileName;
|
|
|
|
|
2007-02-17 10:45:07 +00:00
|
|
|
QString m_signatureOrigin;
|
2007-02-17 09:56:08 +00:00
|
|
|
|
2007-02-13 13:26:37 +00:00
|
|
|
KZip *m_xpsArchive;
|
2007-02-06 07:07:23 +00:00
|
|
|
|
2007-02-13 13:26:37 +00:00
|
|
|
QMap<QString, int> m_fontCache;
|
|
|
|
QFontDatabase m_fontDatabase;
|
2006-09-11 10:44:17 +00:00
|
|
|
};
|
|
|
|
|
2006-09-21 08:45:36 +00:00
|
|
|
class XpsGenerator : public Okular::Generator
|
2006-09-11 10:44:17 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
2015-04-22 12:34:32 +00:00
|
|
|
Q_INTERFACES(Okular::Generator)
|
2006-09-11 10:44:17 +00:00
|
|
|
public:
|
2007-12-02 20:57:24 +00:00
|
|
|
XpsGenerator(QObject *parent, const QVariantList &args);
|
2019-12-18 11:51:13 +00:00
|
|
|
~XpsGenerator() override;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
2017-03-02 19:39:24 +00:00
|
|
|
bool loadDocument(const QString &fileName, QVector<Okular::Page *> &pagesVector) override;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
2017-03-02 19:39:24 +00:00
|
|
|
Okular::DocumentInfo generateDocumentInfo(const QSet<Okular::DocumentInfo::Key> &keys) const override;
|
|
|
|
const Okular::DocumentSynopsis *generateDocumentSynopsis() override;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
2017-03-02 19:39:24 +00:00
|
|
|
Okular::ExportFormat::List exportFormats() const override;
|
|
|
|
bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override;
|
2007-10-08 16:46:51 +00:00
|
|
|
|
2017-03-02 19:39:24 +00:00
|
|
|
bool print(QPrinter &printer) override;
|
2008-08-03 10:19:05 +00:00
|
|
|
|
2007-01-24 15:06:45 +00:00
|
|
|
protected:
|
2017-03-02 19:39:24 +00:00
|
|
|
bool doCloseDocument() override;
|
2019-12-20 15:40:59 +00:00
|
|
|
QImage image(Okular::PixmapRequest *request) override;
|
2018-02-01 18:42:37 +00:00
|
|
|
Okular::TextPage *textPage(Okular::TextRequest *request) override;
|
2006-09-11 10:44:17 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
XpsFile *m_xpsFile;
|
|
|
|
};
|
|
|
|
|
2014-09-11 19:12:27 +00:00
|
|
|
Q_DECLARE_LOGGING_CATEGORY(OkularXpsDebug)
|
|
|
|
|
2006-09-11 10:44:17 +00:00
|
|
|
#endif
|