DocDiff application: draw differences onto pages

This commit is contained in:
Jakub Melka 2021-10-14 19:12:56 +02:00
parent bafcc36d3f
commit e838f5130a
7 changed files with 537 additions and 306 deletions

View File

@ -46,7 +46,8 @@ SOURCES += \
differencesdockwidget.cpp \
main.cpp \
mainwindow.cpp \
settingsdockwidget.cpp
settingsdockwidget.cpp \
utils.cpp
FORMS += \
aboutdialog.ui \
@ -59,7 +60,8 @@ HEADERS += \
differencesdockwidget.h \
mainwindow.h \
settings.h \
settingsdockwidget.h
settingsdockwidget.h \
utils.h
RESOURCES += \
resources.qrc

View File

@ -52,7 +52,8 @@ MainWindow::MainWindow(QWidget* parent) :
m_diff(nullptr),
m_isChangingProgressStep(false),
m_dontDisplayErrorMessage(false),
m_diffNavigator(nullptr)
m_diffNavigator(nullptr),
m_drawInterface(&m_settings, &m_documentMapper, &m_filteredDiffResult)
{
ui->setupUi(this);
@ -73,6 +74,7 @@ MainWindow::MainWindow(QWidget* parent) :
m_pdfWidget = new pdf::PDFWidget(m_cmsManager, pdf::RendererEngine::Software, 1, ui->documentFrame);
m_pdfWidget->getDrawWidgetProxy()->setProgress(m_progress);
ui->documentFrame->layout()->addWidget(m_pdfWidget);
m_pdfWidget->getDrawWidgetProxy()->registerDrawInterface(&m_drawInterface);
ui->menuView->addSeparator();
ui->menuView->addAction(m_settingsDockWidget->toggleViewAction());
@ -752,255 +754,4 @@ void MainWindow::onProgressFinished()
m_progressTaskbarIndicator->hide();
}
void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
bool filterDifferences,
const pdf::PDFDiffResult& diff,
const pdf::PDFDocument* leftDocument,
const pdf::PDFDocument* rightDocument,
const pdf::PDFDocument* currentDocument)
{
m_layout.clear();
m_leftPageIndices.clear();
m_rightPageIndices.clear();
m_allLeft = false;
m_allRight = false;
if (!leftDocument || !rightDocument || !currentDocument)
{
return;
}
// Jakub Melka
pdf::PDFDiffResult::PageSequence pageSequence = diff.getPageSequence();
const bool isEmpty = pageSequence.empty();
if (filterDifferences)
{
pdf::PDFDiffResult::PageSequence filteredPageSequence;
std::vector<pdf::PDFInteger> leftPageIndices = diff.getChangedLeftPageIndices();
std::vector<pdf::PDFInteger> rightPageIndices = diff.getChangedRightPageIndices();
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
const bool isLeftModified = std::binary_search(leftPageIndices.cbegin(), leftPageIndices.cend(), item.leftPage);
const bool isRightModified = std::binary_search(rightPageIndices.cbegin(), rightPageIndices.cend(), item.rightPage);
if (isLeftModified || isRightModified)
{
filteredPageSequence.push_back(item);
}
}
pageSequence = std::move(filteredPageSequence);
}
switch (mode)
{
case ComparedDocumentMapper::Mode::Left:
{
Q_ASSERT(leftDocument == currentDocument);
m_allLeft = true;
double yPos = 0.0;
const pdf::PDFCatalog* catalog = leftDocument->getCatalog();
if (isEmpty)
{
// Just copy all pages
const size_t pageCount = catalog->getPageCount();
for (size_t i = 0; i < pageCount; ++i)
{
QSizeF pageSize = catalog->getPage(i)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, i, rect);
yPos += pageSize.height() + 5;
}
}
else
{
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
if (item.leftPage == -1)
{
continue;
}
QSizeF pageSize = catalog->getPage(item.leftPage)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, item.leftPage, rect);
yPos += pageSize.height() + 5;
}
}
break;
}
case ComparedDocumentMapper::Mode::Right:
{
Q_ASSERT(rightDocument == currentDocument);
m_allRight = true;
double yPos = 0.0;
const pdf::PDFCatalog* catalog = rightDocument->getCatalog();
if (isEmpty)
{
// Just copy all pages
const size_t pageCount = catalog->getPageCount();
for (size_t i = 0; i < pageCount; ++i)
{
QSizeF pageSize = catalog->getPage(i)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, i, rect);
yPos += pageSize.height() + 5;
}
}
else
{
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
if (item.rightPage == -1)
{
continue;
}
QSizeF pageSize = catalog->getPage(item.rightPage)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, item.rightPage, rect);
yPos += pageSize.height() + 5;
}
}
break;
}
case ComparedDocumentMapper::Mode::Combined:
case ComparedDocumentMapper::Mode::Overlay:
{
double yPos = 0.0;
const pdf::PDFCatalog* catalog = currentDocument->getCatalog();
pdf::PDFInteger offset = leftDocument->getCatalog()->getPageCount();
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
double yAdvance = 0.0;
if (item.leftPage != -1)
{
QSizeF pageSize = catalog->getPage(item.leftPage)->getRotatedMediaBoxMM().size();
QRectF rect;
if (mode == ComparedDocumentMapper::Mode::Combined)
{
rect = QRectF(-pageSize.width() - 5, yPos, pageSize.width(), pageSize.height());
}
else
{
rect = QRectF(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
}
m_layout.emplace_back(0, item.leftPage, rect);
yAdvance = pageSize.height() + 5;
m_leftPageIndices[item.leftPage] = item.leftPage;
}
if (item.rightPage != -1)
{
pdf::PDFInteger rightPageIndex = item.rightPage + offset;
QSizeF pageSize = catalog->getPage(rightPageIndex)->getRotatedMediaBoxMM().size();
QRectF rect;
if (mode == ComparedDocumentMapper::Mode::Combined)
{
rect = QRectF(5, yPos, pageSize.width(), pageSize.height());
}
else
{
rect = QRectF(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
}
m_layout.emplace_back(0, rightPageIndex, rect);
yAdvance = qMax(yAdvance, pageSize.height() + 5);
m_rightPageIndices[rightPageIndex] = item.rightPage;
}
yPos += yAdvance;
}
break;
}
default:
Q_ASSERT(false);
break;
}
}
pdf::PDFInteger ComparedDocumentMapper::getLeftPageIndex(pdf::PDFInteger pageIndex) const
{
if (m_allLeft)
{
return pageIndex;
}
auto it = m_leftPageIndices.find(pageIndex);
if (it != m_leftPageIndices.cend())
{
return it->second;
}
return -1;
}
pdf::PDFInteger ComparedDocumentMapper::getRightPageIndex(pdf::PDFInteger pageIndex) const
{
if (m_allRight)
{
return pageIndex;
}
auto it = m_rightPageIndices.find(pageIndex);
if (it != m_rightPageIndices.cend())
{
return it->second;
}
return -1;
}
pdf::PDFInteger ComparedDocumentMapper::getPageIndexFromLeftPageIndex(pdf::PDFInteger leftPageIndex) const
{
if (m_allLeft)
{
return leftPageIndex;
}
for (const auto& indexItem : m_leftPageIndices)
{
if (indexItem.second == leftPageIndex)
{
return indexItem.first;
}
}
return -1;
}
pdf::PDFInteger ComparedDocumentMapper::getPageIndexFromRightPageIndex(pdf::PDFInteger rightPageIndex) const
{
if (m_allRight)
{
return rightPageIndex;
}
for (const auto& indexItem : m_rightPageIndices)
{
if (indexItem.second == rightPageIndex)
{
return indexItem.first;
}
}
return -1;
}
} // namespace pdfdocdiff

View File

@ -18,14 +18,12 @@
#ifndef PDFDOCDIFF_MAINWINDOW_H
#define PDFDOCDIFF_MAINWINDOW_H
#include "settings.h"
#include "utils.h"
#include "pdfdocument.h"
#include "pdfdiff.h"
#include "pdfdrawwidget.h"
#include "pdfcms.h"
#include "pdfoptionalcontent.h"
#include "pdfdrawspacecontroller.h"
#include <QMainWindow>
#include <QSignalMapper>
@ -43,55 +41,6 @@ namespace pdfdocdiff
class SettingsDockWidget;
class DifferencesDockWidget;
class ComparedDocumentMapper
{
public:
enum class Mode
{
Left,
Right,
Combined,
Overlay
};
void update(Mode mode,
bool filterDifferences,
const pdf::PDFDiffResult& diff,
const pdf::PDFDocument* leftDocument,
const pdf::PDFDocument* rightDocument,
const pdf::PDFDocument* currentDocument);
const pdf::PDFDrawSpaceController::LayoutItems& getLayout() const { return m_layout; }
void setPageSequence(const pdf::PDFDiffResult::PageSequence& sequence) { m_pageSequence = sequence; }
/// Returns left page index (that means page index in left document),
/// if it doesn't exist, -1 is returned.
/// \param pageIndex Actual page index
pdf::PDFInteger getLeftPageIndex(pdf::PDFInteger pageIndex) const;
/// Returns right page index (that means page index in right document),
/// if it doesn't exist, -1 is returned.
/// \param pageIndex Actual page index
pdf::PDFInteger getRightPageIndex(pdf::PDFInteger pageIndex) const;
/// Returns actual page index from left page index, or -1.
/// \param leftPageIndex Left page index
pdf::PDFInteger getPageIndexFromLeftPageIndex(pdf::PDFInteger leftPageIndex) const;
/// Returns actual page index from right page index, or -1.
/// \param rightPageIndex Right page index
pdf::PDFInteger getPageIndexFromRightPageIndex(pdf::PDFInteger rightPageIndex) const;
private:
pdf::PDFDrawSpaceController::LayoutItems m_layout;
bool m_allLeft = false;
bool m_allRight = false;
std::map<pdf::PDFInteger, pdf::PDFInteger> m_leftPageIndices;
std::map<pdf::PDFInteger, pdf::PDFInteger> m_rightPageIndices;
pdf::PDFDiffResult::PageSequence m_pageSequence;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
@ -190,6 +139,7 @@ private:
pdf::PDFDiffResult m_filteredDiffResult; ///< Difference result with filters applied
pdf::PDFDiffResultNavigator m_diffNavigator; ///< Difference navigator
ComparedDocumentMapper m_documentMapper;
DifferencesDrawInterface m_drawInterface;
};
} // namespace pdfdocdiff

378
Pdf4QtDocDiff/utils.cpp Normal file
View File

@ -0,0 +1,378 @@
// 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 "utils.h"
#include <QPainter>
namespace pdfdocdiff
{
void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
bool filterDifferences,
const pdf::PDFDiffResult& diff,
const pdf::PDFDocument* leftDocument,
const pdf::PDFDocument* rightDocument,
const pdf::PDFDocument* currentDocument)
{
m_layout.clear();
m_leftPageIndices.clear();
m_rightPageIndices.clear();
m_allLeft = false;
m_allRight = false;
if (!leftDocument || !rightDocument || !currentDocument)
{
return;
}
// Jakub Melka
pdf::PDFDiffResult::PageSequence pageSequence = diff.getPageSequence();
const bool isEmpty = pageSequence.empty();
if (filterDifferences)
{
pdf::PDFDiffResult::PageSequence filteredPageSequence;
std::vector<pdf::PDFInteger> leftPageIndices = diff.getChangedLeftPageIndices();
std::vector<pdf::PDFInteger> rightPageIndices = diff.getChangedRightPageIndices();
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
const bool isLeftModified = std::binary_search(leftPageIndices.cbegin(), leftPageIndices.cend(), item.leftPage);
const bool isRightModified = std::binary_search(rightPageIndices.cbegin(), rightPageIndices.cend(), item.rightPage);
if (isLeftModified || isRightModified)
{
filteredPageSequence.push_back(item);
}
}
pageSequence = std::move(filteredPageSequence);
}
switch (mode)
{
case ComparedDocumentMapper::Mode::Left:
{
Q_ASSERT(leftDocument == currentDocument);
m_allLeft = true;
double yPos = 0.0;
const pdf::PDFCatalog* catalog = leftDocument->getCatalog();
if (isEmpty)
{
// Just copy all pages
const size_t pageCount = catalog->getPageCount();
for (size_t i = 0; i < pageCount; ++i)
{
QSizeF pageSize = catalog->getPage(i)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, i, rect);
yPos += pageSize.height() + 5;
}
}
else
{
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
if (item.leftPage == -1)
{
continue;
}
QSizeF pageSize = catalog->getPage(item.leftPage)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, item.leftPage, rect);
yPos += pageSize.height() + 5;
}
}
break;
}
case ComparedDocumentMapper::Mode::Right:
{
Q_ASSERT(rightDocument == currentDocument);
m_allRight = true;
double yPos = 0.0;
const pdf::PDFCatalog* catalog = rightDocument->getCatalog();
if (isEmpty)
{
// Just copy all pages
const size_t pageCount = catalog->getPageCount();
for (size_t i = 0; i < pageCount; ++i)
{
QSizeF pageSize = catalog->getPage(i)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, i, rect);
yPos += pageSize.height() + 5;
}
}
else
{
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
if (item.rightPage == -1)
{
continue;
}
QSizeF pageSize = catalog->getPage(item.rightPage)->getRotatedMediaBoxMM().size();
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
m_layout.emplace_back(0, item.rightPage, rect);
yPos += pageSize.height() + 5;
}
}
break;
}
case ComparedDocumentMapper::Mode::Combined:
case ComparedDocumentMapper::Mode::Overlay:
{
double yPos = 0.0;
const pdf::PDFCatalog* catalog = currentDocument->getCatalog();
pdf::PDFInteger offset = leftDocument->getCatalog()->getPageCount();
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
{
double yAdvance = 0.0;
if (item.leftPage != -1)
{
QSizeF pageSize = catalog->getPage(item.leftPage)->getRotatedMediaBoxMM().size();
QRectF rect;
if (mode == ComparedDocumentMapper::Mode::Combined)
{
rect = QRectF(-pageSize.width() - 5, yPos, pageSize.width(), pageSize.height());
}
else
{
rect = QRectF(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
}
m_layout.emplace_back(0, item.leftPage, rect);
yAdvance = pageSize.height() + 5;
m_leftPageIndices[item.leftPage] = item.leftPage;
}
if (item.rightPage != -1)
{
pdf::PDFInteger rightPageIndex = item.rightPage + offset;
QSizeF pageSize = catalog->getPage(rightPageIndex)->getRotatedMediaBoxMM().size();
QRectF rect;
if (mode == ComparedDocumentMapper::Mode::Combined)
{
rect = QRectF(5, yPos, pageSize.width(), pageSize.height());
}
else
{
rect = QRectF(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
}
m_layout.emplace_back(0, rightPageIndex, rect);
yAdvance = qMax(yAdvance, pageSize.height() + 5);
m_rightPageIndices[rightPageIndex] = item.rightPage;
}
yPos += yAdvance;
}
break;
}
default:
Q_ASSERT(false);
break;
}
}
pdf::PDFInteger ComparedDocumentMapper::getLeftPageIndex(pdf::PDFInteger pageIndex) const
{
if (m_allLeft)
{
return pageIndex;
}
auto it = m_leftPageIndices.find(pageIndex);
if (it != m_leftPageIndices.cend())
{
return it->second;
}
return -1;
}
pdf::PDFInteger ComparedDocumentMapper::getRightPageIndex(pdf::PDFInteger pageIndex) const
{
if (m_allRight)
{
return pageIndex;
}
auto it = m_rightPageIndices.find(pageIndex);
if (it != m_rightPageIndices.cend())
{
return it->second;
}
return -1;
}
pdf::PDFInteger ComparedDocumentMapper::getPageIndexFromLeftPageIndex(pdf::PDFInteger leftPageIndex) const
{
if (m_allLeft)
{
return leftPageIndex;
}
for (const auto& indexItem : m_leftPageIndices)
{
if (indexItem.second == leftPageIndex)
{
return indexItem.first;
}
}
return -1;
}
pdf::PDFInteger ComparedDocumentMapper::getPageIndexFromRightPageIndex(pdf::PDFInteger rightPageIndex) const
{
if (m_allRight)
{
return rightPageIndex;
}
for (const auto& indexItem : m_rightPageIndices)
{
if (indexItem.second == rightPageIndex)
{
return indexItem.first;
}
}
return -1;
}
DifferencesDrawInterface::DifferencesDrawInterface(const Settings* settings,
const ComparedDocumentMapper* mapper,
const pdf::PDFDiffResult* diffResult) :
m_settings(settings),
m_mapper(mapper),
m_diffResult(diffResult)
{
}
void DifferencesDrawInterface::drawPage(QPainter* painter,
pdf::PDFInteger pageIndex,
const pdf::PDFPrecompiledPage* compiledPage,
pdf::PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<pdf::PDFRenderError>& errors) const
{
Q_UNUSED(compiledPage);
Q_UNUSED(layoutGetter);
Q_UNUSED(errors);
const size_t differencesCount = m_diffResult->getDifferencesCount();
const pdf::PDFInteger leftPageIndex = m_mapper->getLeftPageIndex(pageIndex);
const pdf::PDFInteger rightPageIndex = m_mapper->getRightPageIndex(pageIndex);
if (leftPageIndex != -1)
{
for (size_t i = 0; i < differencesCount; ++i)
{
auto leftRectangles = m_diffResult->getLeftRectangles(i);
for (auto it = leftRectangles.first; it != leftRectangles.second; ++it)
{
const auto& item = *it;
if (item.first == leftPageIndex)
{
drawRectangle(painter, pagePointToDevicePointMatrix, item.second, i);
}
}
}
}
if (rightPageIndex != -1)
{
for (size_t i = 0; i < differencesCount; ++i)
{
auto rightRectangles = m_diffResult->getRightRectangles(i);
for (auto it = rightRectangles.first; it != rightRectangles.second; ++it)
{
const auto& item = *it;
if (item.first == rightPageIndex)
{
drawRectangle(painter, pagePointToDevicePointMatrix, item.second, i);
}
}
}
}
}
QColor DifferencesDrawInterface::getColorForIndex(size_t index) const
{
QColor color;
const size_t resultIndex = index;
if (m_diffResult->isReplaceDifference(resultIndex))
{
color = m_settings->colorReplaced;
}
else if (m_diffResult->isRemoveDifference(resultIndex))
{
color = m_settings->colorRemoved;
}
else if (m_diffResult->isAddDifference(resultIndex))
{
color = m_settings->colorAdded;
}
else if (m_diffResult->isPageMoveDifference(resultIndex))
{
color = m_settings->colorPageMove;
}
return color;
}
void DifferencesDrawInterface::drawPostRendering(QPainter* painter, QRect rect) const
{
Q_UNUSED(painter);
Q_UNUSED(rect);
}
void DifferencesDrawInterface::drawRectangle(QPainter* painter,
const QMatrix& pagePointToDevicePointMatrix,
const QRectF& rect,
size_t resultIndex) const
{
QColor color = getColorForIndex(resultIndex);
color.setAlphaF(0.3);
QRectF resultRect = pagePointToDevicePointMatrix.mapRect(rect);
painter->fillRect(resultRect, color);
}
} // namespace pdfdocdiff

107
Pdf4QtDocDiff/utils.h Normal file
View File

@ -0,0 +1,107 @@
// 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 UTILS_H
#define UTILS_H
#include "settings.h"
#include "pdfdiff.h"
#include "pdfdrawspacecontroller.h"
#include "pdfdocumentdrawinterface.h"
namespace pdfdocdiff
{
class ComparedDocumentMapper
{
public:
enum class Mode
{
Left,
Right,
Combined,
Overlay
};
void update(Mode mode,
bool filterDifferences,
const pdf::PDFDiffResult& diff,
const pdf::PDFDocument* leftDocument,
const pdf::PDFDocument* rightDocument,
const pdf::PDFDocument* currentDocument);
const pdf::PDFDrawSpaceController::LayoutItems& getLayout() const { return m_layout; }
void setPageSequence(const pdf::PDFDiffResult::PageSequence& sequence) { m_pageSequence = sequence; }
/// Returns left page index (that means page index in left document),
/// if it doesn't exist, -1 is returned.
/// \param pageIndex Actual page index
pdf::PDFInteger getLeftPageIndex(pdf::PDFInteger pageIndex) const;
/// Returns right page index (that means page index in right document),
/// if it doesn't exist, -1 is returned.
/// \param pageIndex Actual page index
pdf::PDFInteger getRightPageIndex(pdf::PDFInteger pageIndex) const;
/// Returns actual page index from left page index, or -1.
/// \param leftPageIndex Left page index
pdf::PDFInteger getPageIndexFromLeftPageIndex(pdf::PDFInteger leftPageIndex) const;
/// Returns actual page index from right page index, or -1.
/// \param rightPageIndex Right page index
pdf::PDFInteger getPageIndexFromRightPageIndex(pdf::PDFInteger rightPageIndex) const;
private:
pdf::PDFDrawSpaceController::LayoutItems m_layout;
bool m_allLeft = false;
bool m_allRight = false;
std::map<pdf::PDFInteger, pdf::PDFInteger> m_leftPageIndices;
std::map<pdf::PDFInteger, pdf::PDFInteger> m_rightPageIndices;
pdf::PDFDiffResult::PageSequence m_pageSequence;
};
class DifferencesDrawInterface : public pdf::IDocumentDrawInterface
{
public:
explicit DifferencesDrawInterface(const Settings* settings,
const ComparedDocumentMapper* mapper,
const pdf::PDFDiffResult* diffResult);
virtual void drawPage(QPainter* painter, pdf::PDFInteger pageIndex,
const pdf::PDFPrecompiledPage* compiledPage,
pdf::PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<pdf::PDFRenderError>& errors) const override;
virtual void drawPostRendering(QPainter* painter, QRect rect) const override;
private:
void drawRectangle(QPainter* painter,
const QMatrix& pagePointToDevicePointMatrix,
const QRectF& rect,
size_t resultIndex) const;
QColor getColorForIndex(size_t index) const;
const Settings* m_settings;
const ComparedDocumentMapper* m_mapper;
const pdf::PDFDiffResult* m_diffResult;
};
} // namespace pdfdocdiff
#endif // UTILS_H

View File

@ -1180,6 +1180,42 @@ PDFInteger PDFDiffResult::getRightPage(size_t index) const
return m_differences[index].pageIndex2;
}
std::pair<PDFDiffResult::RectInfosIt, PDFDiffResult::RectInfosIt> PDFDiffResult::getLeftRectangles(size_t index) const
{
if (index >= m_differences.size())
{
return std::make_pair(m_rects.cend(), m_rects.cend());
}
const Difference& difference = m_differences[index];
if (difference.leftRectCount > 0)
{
auto it = std::next(m_rects.cbegin(), difference.leftRectIndex);
auto itEnd = std::next(it, difference.leftRectCount);
return std::make_pair(it, itEnd);
}
return std::make_pair(m_rects.cend(), m_rects.cend());
}
std::pair<PDFDiffResult::RectInfosIt, PDFDiffResult::RectInfosIt> PDFDiffResult::getRightRectangles(size_t index) const
{
if (index >= m_differences.size())
{
return std::make_pair(m_rects.cend(), m_rects.cend());
}
const Difference& difference = m_differences[index];
if (difference.rightRectCount > 0)
{
auto it = std::next(m_rects.cbegin(), difference.rightRectIndex);
auto itEnd = std::next(it, difference.rightRectCount);
return std::make_pair(it, itEnd);
}
return std::make_pair(m_rects.cend(), m_rects.cend());
}
bool PDFDiffResult::isPageMoveDifference(size_t index) const
{
return getTypeFlags(index) & FLAGS_TYPE_PAGE_MOVE;

View File

@ -68,6 +68,7 @@ public:
using PageSequence = std::vector<PageSequenceItem>;
using RectInfos = std::vector<std::pair<PDFInteger, QRectF>>;
using RectInfosIt = typename RectInfos::const_iterator;
void setResult(PDFOperationResult result) { m_result = std::move(result); }
const PDFOperationResult& getResult() const { return m_result; }
@ -95,6 +96,12 @@ public:
/// \param index Index
PDFInteger getRightPage(size_t index) const;
/// Returns iterator range for rectangles of "left" pages of an item
std::pair<RectInfosIt, RectInfosIt> getLeftRectangles(size_t index) const;
/// Returns iterator range for rectangles of "right" pages of an item
std::pair<RectInfosIt, RectInfosIt> getRightRectangles(size_t index) const;
bool isPageMoveDifference(size_t index) const;
bool isAddDifference(size_t index) const;
bool isRemoveDifference(size_t index) const;