mirror of https://github.com/JakubMelka/PDF4QT.git
DocPage Organizer: Assemble documents
This commit is contained in:
parent
b644ea48e3
commit
b38bbf8468
|
@ -42,6 +42,7 @@ INSTALLS += application
|
|||
|
||||
SOURCES += \
|
||||
aboutdialog.cpp \
|
||||
assembleoutputsettingsdialog.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
pageitemdelegate.cpp \
|
||||
|
@ -49,10 +50,12 @@ SOURCES += \
|
|||
|
||||
FORMS += \
|
||||
aboutdialog.ui \
|
||||
assembleoutputsettingsdialog.ui \
|
||||
mainwindow.ui
|
||||
|
||||
HEADERS += \
|
||||
aboutdialog.h \
|
||||
assembleoutputsettingsdialog.h \
|
||||
mainwindow.h \
|
||||
pageitemdelegate.h \
|
||||
pageitemmodel.h
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
// 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 PDFABOUTDIALOG_H
|
||||
#define PDFABOUTDIALOG_H
|
||||
#ifndef PDFDOCPAGEORGANIZER_PDFABOUTDIALOG_H
|
||||
#define PDFDOCPAGEORGANIZER_PDFABOUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
|
@ -42,4 +42,4 @@ private:
|
|||
|
||||
} // namespace pdfdocpage
|
||||
|
||||
#endif // PDFABOUTDIALOG_H
|
||||
#endif // PDFDOCPAGEORGANIZER_PDFABOUTDIALOG_H
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (C) 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/>.
|
||||
|
||||
#include "assembleoutputsettingsdialog.h"
|
||||
#include "ui_assembleoutputsettingsdialog.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
namespace pdfdocpage
|
||||
{
|
||||
|
||||
AssembleOutputSettingsDialog::AssembleOutputSettingsDialog(QString directory, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AssembleOutputSettingsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->directoryEdit->setText(directory);
|
||||
|
||||
pdf::PDFWidgetUtils::scaleWidget(this, QSize(450, 150));
|
||||
}
|
||||
|
||||
AssembleOutputSettingsDialog::~AssembleOutputSettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString AssembleOutputSettingsDialog::getDirectory() const
|
||||
{
|
||||
return ui->directoryEdit->text();
|
||||
}
|
||||
|
||||
QString AssembleOutputSettingsDialog::getFileName() const
|
||||
{
|
||||
return ui->fileTemplateEdit->text();
|
||||
}
|
||||
|
||||
bool AssembleOutputSettingsDialog::isOverwriteFiles() const
|
||||
{
|
||||
return ui->overwriteFilesCheckBox->isChecked();
|
||||
}
|
||||
|
||||
void AssembleOutputSettingsDialog::on_selectDirectoryButton_clicked()
|
||||
{
|
||||
QString directory = QFileDialog::getExistingDirectory(this, tr("Select output directory"), ui->directoryEdit->text());
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
ui->directoryEdit->setText(directory);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdfdocpage
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 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 PDFDOCPAGEORGANIZER_ASSEMBLEOUTPUTSETTINGSDIALOG_H
|
||||
#define PDFDOCPAGEORGANIZER_ASSEMBLEOUTPUTSETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AssembleOutputSettingsDialog;
|
||||
}
|
||||
|
||||
namespace pdfdocpage
|
||||
{
|
||||
|
||||
class AssembleOutputSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AssembleOutputSettingsDialog(QString directory, QWidget* parent);
|
||||
virtual ~AssembleOutputSettingsDialog() override;
|
||||
|
||||
QString getDirectory() const;
|
||||
QString getFileName() const;
|
||||
bool isOverwriteFiles() const;
|
||||
|
||||
private slots:
|
||||
void on_selectDirectoryButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::AssembleOutputSettingsDialog* ui;
|
||||
};
|
||||
|
||||
} // namespace pdfdocpage
|
||||
|
||||
#endif // PDFDOCPAGEORGANIZER_ASSEMBLEOUTPUTSETTINGSDIALOG_H
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AssembleOutputSettingsDialog</class>
|
||||
<widget class="QDialog" name="AssembleOutputSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>614</width>
|
||||
<height>213</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Assemble Documents</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="assembleDocumentsGroupBox">
|
||||
<property name="title">
|
||||
<string>Assemble Documents</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="assembleDocumentsGroupBoxLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="fileTemplateLabel">
|
||||
<property name="text">
|
||||
<string>File template</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="selectDirectoryButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QLabel" name="infoLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>In a template file name, you can use symbols '#' for output document number (means output document index, not input document) or '@' for page number of input document (if document contains more pages, it is a page number of a original document), or '%' for index of input document. Use more '#' or '@' or '%' for setting minimal number of digits (if number has less digits, the they are padded with zero).</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="fileTemplateEdit">
|
||||
<property name="text">
|
||||
<string>doc-#.pdf</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="directoryLabel">
|
||||
<property name="text">
|
||||
<string>Generate into directory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="directoryEdit"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="overwriteFilesCheckBox">
|
||||
<property name="text">
|
||||
<string>Overwrite existing files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AssembleOutputSettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AssembleOutputSettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -19,6 +19,7 @@
|
|||
#include "ui_mainwindow.h"
|
||||
|
||||
#include "aboutdialog.h"
|
||||
#include "assembleoutputsettingsdialog.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfdocumentreader.h"
|
||||
|
@ -489,9 +490,102 @@ void MainWindow::performOperation(Operation operation)
|
|||
break;
|
||||
}
|
||||
|
||||
case Operation::ReplaceSelection:
|
||||
Q_ASSERT(false);
|
||||
case Operation::Unite:
|
||||
case Operation::Separate:
|
||||
case Operation::SeparateGrouped:
|
||||
{
|
||||
PageItemModel::AssembleMode assembleMode = PageItemModel::AssembleMode::Unite;
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case Operation::Unite:
|
||||
assembleMode = PageItemModel::AssembleMode::Unite;
|
||||
break;
|
||||
|
||||
case Operation::Separate:
|
||||
assembleMode = PageItemModel::AssembleMode::Separate;
|
||||
break;
|
||||
|
||||
case Operation::SeparateGrouped:
|
||||
assembleMode = PageItemModel::AssembleMode::SeparateGrouped;
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
std::vector<std::vector<pdf::PDFDocumentManipulator::AssembledPage>> assembledDocuments = m_model->getAssembledPages(assembleMode);
|
||||
|
||||
// Check we have something to process
|
||||
if (assembledDocuments.empty())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("No documents to assemble."));
|
||||
break;
|
||||
}
|
||||
|
||||
AssembleOutputSettingsDialog dialog(m_settings.directory, this);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
pdf::PDFDocumentManipulator manipulator;
|
||||
|
||||
// Add documents and images
|
||||
for (const auto& documentItem : m_model->getDocuments())
|
||||
{
|
||||
manipulator.addDocument(documentItem.first, &documentItem.second.document);
|
||||
}
|
||||
for (const auto& imageItem : m_model->getImages())
|
||||
{
|
||||
manipulator.addImage(imageItem.first, imageItem.second.image);
|
||||
}
|
||||
|
||||
// Jakub Melka: create assembled documents
|
||||
pdf::PDFOperationResult result(true);
|
||||
std::vector<std::pair<QString, pdf::PDFDocument>> assembledDocumentStorage;
|
||||
|
||||
int sourceDocumentIndex = 1;
|
||||
int assembledDocumentIndex = 1;
|
||||
int sourcePageIndex = 1;
|
||||
int documentCount = int(m_model->getDocuments().size());
|
||||
|
||||
QString directory = dialog.getDirectory();
|
||||
QString fileNameTemplate = dialog.getFileName();
|
||||
const bool isOverwriteEnabled = dialog.isOverwriteFiles();
|
||||
|
||||
for (const std::vector<pdf::PDFDocumentManipulator::AssembledPage>& assembledPages : assembledDocuments)
|
||||
{
|
||||
pdf::PDFOperationResult currentResult = manipulator.assemble(assembledPages);
|
||||
if (!currentResult && result)
|
||||
{
|
||||
result = currentResult;
|
||||
break;
|
||||
}
|
||||
|
||||
pdf::PDFDocumentManipulator::AssembledPage samplePage = assembledPages.front();
|
||||
sourceDocumentIndex = samplePage.documentIndex == -1 ? documentCount + samplePage.imageIndex : samplePage.documentIndex;
|
||||
sourcePageIndex = qMax(samplePage.pageIndex + 1, 1);
|
||||
|
||||
QString fileName = fileNameTemplate;
|
||||
|
||||
if (!fileName.endsWith(".pdf"))
|
||||
{
|
||||
fileName += ".pdf";
|
||||
}
|
||||
|
||||
assembledDocumentStorage.emplace_back(std::make_pair(std::move(fileName), manipulator.takeAssembledDocument()));
|
||||
++assembledDocumentIndex;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), result.getErrorMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Operation::InsertImage:
|
||||
{
|
||||
|
@ -512,10 +606,9 @@ void MainWindow::performOperation(Operation operation)
|
|||
}
|
||||
|
||||
case Operation::InsertPDF:
|
||||
|
||||
case Operation::Unite:
|
||||
case Operation::Separate:
|
||||
case Operation::SeparateGrouped:
|
||||
case Operation::ReplaceSelection:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
|
|
|
@ -848,6 +848,97 @@ Qt::ItemFlags PageItemModel::flags(const QModelIndex& index) const
|
|||
return flags;
|
||||
}
|
||||
|
||||
std::vector<std::vector<pdf::PDFDocumentManipulator::AssembledPage>> PageItemModel::getAssembledPages(AssembleMode mode) const
|
||||
{
|
||||
std::vector<std::vector<pdf::PDFDocumentManipulator::AssembledPage>> result;
|
||||
|
||||
auto createAssembledPage = [this](const PageGroupItem::GroupItem& item)
|
||||
{
|
||||
pdf::PDFDocumentManipulator::AssembledPage assembledPage;
|
||||
|
||||
assembledPage.documentIndex = item.documentIndex;
|
||||
assembledPage.imageIndex = item.imageIndex;
|
||||
assembledPage.pageIndex = item.pageIndex;
|
||||
|
||||
if (assembledPage.pageIndex > 0)
|
||||
{
|
||||
--assembledPage.pageIndex;
|
||||
}
|
||||
|
||||
pdf::PageRotation originalPageRotation = pdf::PageRotation::None;
|
||||
if (item.pageType == PT_DocumentPage)
|
||||
{
|
||||
auto it = m_documents.find(item.documentIndex);
|
||||
if (it != m_documents.cend())
|
||||
{
|
||||
const pdf::PDFPage* page = it->second.document.getCatalog()->getPage(item.pageIndex - 1);
|
||||
originalPageRotation = page->getPageRotation();
|
||||
}
|
||||
}
|
||||
|
||||
assembledPage.pageRotation = pdf::getPageRotationCombined(originalPageRotation, item.pageAdditionalRotation);
|
||||
assembledPage.pageSize = pdf::PDFPage::getRotatedSize(item.rotatedPageDimensionsMM, pdf::getPageRotationInversed(item.pageAdditionalRotation));
|
||||
|
||||
return assembledPage;
|
||||
};
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case AssembleMode::Unite:
|
||||
{
|
||||
std::vector<pdf::PDFDocumentManipulator::AssembledPage> unitedDocument;
|
||||
|
||||
for (const auto& pageGroupItem : m_pageGroupItems)
|
||||
{
|
||||
for (const auto& groupItem : pageGroupItem.groups)
|
||||
{
|
||||
unitedDocument.emplace_back(createAssembledPage(groupItem));
|
||||
}
|
||||
}
|
||||
|
||||
result.emplace_back(std::move(unitedDocument));
|
||||
break;
|
||||
}
|
||||
|
||||
case AssembleMode::Separate:
|
||||
{
|
||||
for (const auto& pageGroupItem : m_pageGroupItems)
|
||||
{
|
||||
for (const auto& groupItem : pageGroupItem.groups)
|
||||
{
|
||||
result.emplace_back().emplace_back(createAssembledPage(groupItem));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AssembleMode::SeparateGrouped:
|
||||
{
|
||||
for (const auto& pageGroupItem : m_pageGroupItems)
|
||||
{
|
||||
std::vector<pdf::PDFDocumentManipulator::AssembledPage> groupDocument;
|
||||
for (const auto& groupItem : pageGroupItem.groups)
|
||||
{
|
||||
groupDocument.emplace_back(createAssembledPage(groupItem));
|
||||
}
|
||||
result.emplace_back(std::move(groupDocument));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove empty documents
|
||||
result.erase(std::remove_if(result.begin(), result.end(), [](const auto& pages) { return pages.empty(); }), result.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PageItemModel::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfutils.h"
|
||||
#include "pdfdocumentmanipulator.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QAbstractItemModel>
|
||||
|
@ -100,6 +101,15 @@ public:
|
|||
virtual Qt::DropActions supportedDragActions() const override;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
enum class AssembleMode
|
||||
{
|
||||
Unite,
|
||||
Separate,
|
||||
SeparateGrouped
|
||||
};
|
||||
|
||||
std::vector<std::vector<pdf::PDFDocumentManipulator::AssembledPage>> getAssembledPages(AssembleMode mode) const;
|
||||
|
||||
/// Clear all data and undo/redo
|
||||
void clear();
|
||||
|
||||
|
@ -153,6 +163,9 @@ public:
|
|||
|
||||
static QString getMimeDataType() { return QLatin1String("application/pagemodel.PDF4QtDocPageOrganizer"); }
|
||||
|
||||
const std::map<int, DocumentItem>& getDocuments() const { return m_documents; }
|
||||
const std::map<int, ImageItem>& getImages() const { return m_images; }
|
||||
|
||||
private:
|
||||
void createDocumentGroup(int index);
|
||||
QString getGroupNameFromDocument(int index) const;
|
||||
|
|
|
@ -29,6 +29,10 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages)
|
|||
return tr("Empty page list.");
|
||||
}
|
||||
|
||||
m_flags = None;
|
||||
m_mergedObjects = { };
|
||||
m_assembledDocument = PDFDocument();
|
||||
|
||||
try
|
||||
{
|
||||
classify(pages);
|
||||
|
|
|
@ -207,6 +207,23 @@ PDFObject PDFPage::getOutputIntents(const PDFObjectStorage* storage) const
|
|||
return getObjectFromPageDictionary(storage, "OutputIntents");
|
||||
}
|
||||
|
||||
QSizeF PDFPage::getRotatedSize(const QSizeF& size, PageRotation rotation)
|
||||
{
|
||||
switch (rotation)
|
||||
{
|
||||
case PageRotation::None:
|
||||
case PageRotation::Rotate180:
|
||||
// Preserve rotation
|
||||
break;
|
||||
|
||||
case PageRotation::Rotate90:
|
||||
case PageRotation::Rotate270:
|
||||
return size.transposed();
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
QRectF PDFPage::getRotatedBox(const QRectF& rect, PageRotation rotation)
|
||||
{
|
||||
switch (rotation)
|
||||
|
|
|
@ -84,6 +84,34 @@ constexpr PageRotation getPageRotationRotatedLeft(PageRotation rotation)
|
|||
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
|
||||
|
@ -241,6 +269,7 @@ public:
|
|||
/// 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:
|
||||
|
|
Loading…
Reference in New Issue