mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2024-12-29 09:40:26 +01:00
323 lines
12 KiB
C++
323 lines
12 KiB
C++
// Copyright (C) 2018-2021 Jakub Melka
|
|
//
|
|
// This file is part of PDF4QT.
|
|
//
|
|
// PDF4QT 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
|
|
// with the written consent of the copyright owner, any later version.
|
|
//
|
|
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#ifndef PDFPAGE_H
|
|
#define PDFPAGE_H
|
|
|
|
#include "pdfobject.h"
|
|
|
|
#include <QRectF>
|
|
|
|
#include <set>
|
|
#include <optional>
|
|
|
|
namespace pdf
|
|
{
|
|
class PDFDocument;
|
|
class PDFObjectStorage;
|
|
|
|
/// This enum represents number of degree, which should be page rotated CLOCKWISE,
|
|
/// when being displayed or printed.
|
|
enum class PageRotation
|
|
{
|
|
None,
|
|
Rotate90,
|
|
Rotate180,
|
|
Rotate270
|
|
};
|
|
|
|
enum class PageTabOrder
|
|
{
|
|
Invalid,
|
|
Row,
|
|
Column,
|
|
Structure,
|
|
Array,
|
|
Widget
|
|
};
|
|
|
|
constexpr PageRotation getPageRotationRotatedRight(PageRotation rotation)
|
|
{
|
|
switch (rotation)
|
|
{
|
|
case PageRotation::None:
|
|
return PageRotation::Rotate90;
|
|
case PageRotation::Rotate90:
|
|
return PageRotation::Rotate180;
|
|
case PageRotation::Rotate180:
|
|
return PageRotation::Rotate270;
|
|
case PageRotation::Rotate270:
|
|
return PageRotation::None;
|
|
}
|
|
|
|
return PageRotation::None;
|
|
}
|
|
|
|
constexpr PageRotation getPageRotationRotatedLeft(PageRotation rotation)
|
|
{
|
|
switch (rotation)
|
|
{
|
|
case PageRotation::None:
|
|
return PageRotation::Rotate270;
|
|
case PageRotation::Rotate90:
|
|
return PageRotation::None;
|
|
case PageRotation::Rotate180:
|
|
return PageRotation::Rotate90;
|
|
case PageRotation::Rotate270:
|
|
return PageRotation::Rotate180;
|
|
}
|
|
|
|
return PageRotation::None;
|
|
}
|
|
|
|
constexpr PageRotation getPageRotationCombined(PageRotation r1, PageRotation r2)
|
|
{
|
|
while (r1 != PageRotation::None)
|
|
{
|
|
r2 = getPageRotationRotatedRight(r2);
|
|
r1 = getPageRotationRotatedLeft(r1);
|
|
}
|
|
|
|
return r2;
|
|
}
|
|
|
|
constexpr PageRotation getPageRotationInversed(PageRotation rotation)
|
|
{
|
|
switch (rotation)
|
|
{
|
|
case PageRotation::None:
|
|
return PageRotation::None;
|
|
case PageRotation::Rotate90:
|
|
return PageRotation::Rotate270;
|
|
case PageRotation::Rotate180:
|
|
return PageRotation::Rotate180;
|
|
case PageRotation::Rotate270:
|
|
return PageRotation::Rotate90;
|
|
}
|
|
|
|
return PageRotation::None;
|
|
}
|
|
|
|
/// This class represents attributes, which are inheritable. Also allows merging from
|
|
/// parents.
|
|
class PDFPageInheritableAttributes
|
|
{
|
|
public:
|
|
explicit inline PDFPageInheritableAttributes() = default;
|
|
|
|
/// Parses inheritable attributes from the page tree node
|
|
/// \param templateAttributes Template attributes
|
|
/// \param dictionary Dictionary, from which the data will be read
|
|
/// \param storage Storage owning this data
|
|
static PDFPageInheritableAttributes parse(const PDFPageInheritableAttributes& templateAttributes, const PDFObject& dictionary, const PDFObjectStorage* storage);
|
|
|
|
const QRectF& getMediaBox() const { return m_mediaBox; }
|
|
const QRectF& getCropBox() const { return m_cropBox; }
|
|
PageRotation getPageRotation() const;
|
|
const PDFObject& getResources() const { return m_resources; }
|
|
|
|
private:
|
|
QRectF m_mediaBox;
|
|
QRectF m_cropBox;
|
|
std::optional<PageRotation> m_pageRotation;
|
|
PDFObject m_resources;
|
|
};
|
|
|
|
/// Object representing page in PDF document. Contains different page properties, such as
|
|
/// media box, crop box, rotation, etc. and also page content, resources.
|
|
class PDF4QTLIBSHARED_EXPORT PDFPage
|
|
{
|
|
public:
|
|
explicit PDFPage() = default;
|
|
|
|
/// Parses the page tree. If error occurs, then exception is thrown.
|
|
/// \param storage Storage owning this tree
|
|
/// \param root Root object of page tree
|
|
static std::vector<PDFPage> parse(const PDFObjectStorage* storage, const PDFObject& root);
|
|
|
|
inline const QRectF& getMediaBox() const { return m_mediaBox; }
|
|
inline const QRectF& getCropBox() const { return m_cropBox; }
|
|
inline const QRectF& getBleedBox() const { return m_bleedBox; }
|
|
inline const QRectF& getTrimBox() const { return m_trimBox; }
|
|
inline const QRectF& getArtBox() const { return m_artBox; }
|
|
inline PageRotation getPageRotation() const { return m_pageRotation; }
|
|
|
|
inline const PDFObject& getResources() const { return m_resources; }
|
|
inline const PDFObject& getContents() const { return m_contents; }
|
|
|
|
QRectF getRectMM(const QRectF& rect) const;
|
|
|
|
inline QRectF getMediaBoxMM() const { return getRectMM(m_mediaBox); }
|
|
inline QRectF getCropBoxMM() const { return getRectMM(m_cropBox); }
|
|
inline QRectF getBleedBoxMM() const { return getRectMM(m_bleedBox); }
|
|
inline QRectF getTrimBoxMM() const { return getRectMM(m_trimBox); }
|
|
inline QRectF getArtBoxMM() const { return getRectMM(m_artBox); }
|
|
|
|
inline PDFObjectReference getPageReference() const { return m_pageReference; }
|
|
inline PDFObjectReference getThumbnailReference() const { return m_thumbnailReference; }
|
|
inline PDFObjectReference getDocumentPart() const { return m_documentPart; }
|
|
|
|
QRectF getRotatedMediaBox() const;
|
|
QRectF getRotatedMediaBoxMM() const;
|
|
QRectF getRotatedCropBox() const;
|
|
|
|
inline const std::vector<PDFObjectReference>& getAnnotations() const { return m_annots; }
|
|
inline const std::vector<PDFObjectReference>& getBeads() const { return m_beads; }
|
|
inline const QDateTime& getLastModifiedDateTime() const { return m_lastModified; }
|
|
|
|
/// Returns box color info dictionary, if it is present. This dictionary
|
|
/// describes appearance of page boundaries. Empty object can be returned,
|
|
/// if dictionary doesn't exist.
|
|
/// \param storage Storage
|
|
PDFObject getBoxColorInfo(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page transparency group (attributes for the
|
|
/// transparent imaging model). Empty object can be returned,
|
|
/// if dictionary doesn't exist.
|
|
/// \param storage Storage
|
|
PDFObject getTransparencyGroup(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page thumbnail. Empty object can be returned,
|
|
/// if thumbnail doesn't exist.
|
|
/// \param storage Storage
|
|
PDFObject getThumbnail(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page transition. Page transition object defines,
|
|
/// what should be done during presentations, how pages are switched etc.
|
|
/// Empty object can be returned, if thumbnail doesn't exist.
|
|
/// \param storage Storage
|
|
PDFObject getTransition(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page additional actions dictionary. If no additional
|
|
/// actions are defined, then empty object is returned.
|
|
/// \param storage Storage
|
|
PDFObject getAdditionalActions(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page metadata stream. If no metadata stream is defined,
|
|
/// then empty object is returned.
|
|
/// \param storage Storage
|
|
PDFObject getMetadata(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page piece dictionary associated with the page.
|
|
/// Empty object can be returned, if no piece dictionary is found.
|
|
/// \param storage Storage
|
|
PDFObject getPieceDictionary(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns color separation info. This information is required
|
|
/// to generate color separations for the page.
|
|
/// \param storage Storage
|
|
PDFObject getColorSeparationInfo(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns first navigation node on the page, or null object,
|
|
/// if no navigation nodes are present.
|
|
/// \param storage Storage
|
|
PDFObject getFirstSubpageNavigationNode(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns array of viewport dictionaries, that shall specify
|
|
/// rectangular regions on the page.
|
|
/// \param storage Storage
|
|
PDFObject getViewports(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns array of associated files.
|
|
/// \param storage Storage
|
|
PDFObject getAssociatedFiles(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns array of output intents. Output intents define color
|
|
/// characteristics of output devices on which this page
|
|
/// will be rendered.
|
|
/// \param storage Storage
|
|
PDFObject getOutputIntents(const PDFObjectStorage* storage) const;
|
|
|
|
/// Returns page transition time. During presentations, this specifies a time window,
|
|
/// in which is page displayed, until it is advanced to the next page. Time
|
|
/// is specified in seconds.
|
|
inline PDFInteger getDuration() const { return m_duration; }
|
|
|
|
/// Returns integer key of structure parent of the page, in the structure tree.
|
|
/// If no structure tree exists, or page doesn't define it, then zero is returned.
|
|
inline PDFInteger getStructureParentKey() const { return m_structParent; }
|
|
|
|
/// Returns web capture content set id.
|
|
inline const QByteArray& getWebCaptureContentSetId() const { return m_webCaptureContentSetId; }
|
|
|
|
/// Returns preferred zoom. If zero is returned, no preferred zoom is returned.
|
|
inline PDFReal getPreferredZoom() const { return m_preferredZoom; }
|
|
|
|
/// Returns page tab order (if it is defined). Page tab order defines
|
|
/// sequence of tab stops for annotations. If no tab order is defined,
|
|
/// then Invalid is returned.
|
|
inline PageTabOrder getTabOrder() const { return m_pageTabOrder; }
|
|
|
|
/// Returns name of template, from which this page was generated
|
|
inline const QByteArray& getTemplateName() const { return m_templateName; }
|
|
|
|
/// Returns page user space unit. User space units are multiplies
|
|
/// of 1 / 72 inch. Default value is 1.0.
|
|
inline PDFReal getUserUnit() const { return m_userUnit; }
|
|
|
|
static QSizeF getRotatedSize(const QSizeF& size, PageRotation rotation);
|
|
static QRectF getRotatedBox(const QRectF& rect, PageRotation rotation);
|
|
|
|
private:
|
|
/// Parses the page tree (implementation). If error occurs, then exception is thrown.
|
|
/// \param pages Page array. Pages are inserted into this array
|
|
/// \param visitedReferences Visited references (to check cycles in page tree and avoid hangup)
|
|
/// \param templateAttributes Template attributes (inheritable attributes defined in parent)
|
|
/// \param root Root object of page tree
|
|
/// \param storage Storage owning this tree
|
|
static void parseImpl(std::vector<PDFPage>& pages,
|
|
std::set<PDFObjectReference>& visitedReferences,
|
|
const PDFPageInheritableAttributes& templateAttributes,
|
|
const PDFObject& root,
|
|
const PDFObjectStorage* storage);
|
|
|
|
/// Returns object from page dictionary. This function requires,
|
|
/// that storage of object is present, for object fetching. Objects
|
|
/// are not stored in this class, because it will have too large
|
|
/// memory requirements.
|
|
/// \param storage Storage
|
|
/// \param key Page dictionary key
|
|
PDFObject getObjectFromPageDictionary(const PDFObjectStorage* storage, const char* key) const;
|
|
|
|
PDFObject m_pageObject;
|
|
QRectF m_mediaBox;
|
|
QRectF m_cropBox;
|
|
QRectF m_bleedBox;
|
|
QRectF m_trimBox;
|
|
QRectF m_artBox;
|
|
PageRotation m_pageRotation = PageRotation::None;
|
|
PDFObject m_resources;
|
|
PDFObject m_contents;
|
|
PDFObjectReference m_pageReference;
|
|
PDFObjectReference m_thumbnailReference;
|
|
PDFObjectReference m_documentPart;
|
|
std::vector<PDFObjectReference> m_annots;
|
|
std::vector<PDFObjectReference> m_beads;
|
|
QDateTime m_lastModified;
|
|
PDFInteger m_duration = 0;
|
|
PDFInteger m_structParent = 0;
|
|
PDFReal m_preferredZoom = 0.0;
|
|
PDFReal m_userUnit = 1.0;
|
|
PageTabOrder m_pageTabOrder = PageTabOrder::Invalid;
|
|
QByteArray m_webCaptureContentSetId;
|
|
QByteArray m_templateName;
|
|
};
|
|
|
|
} // namespace pdf
|
|
|
|
#endif // PDFPAGE_H
|