mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
DocDiff application: create document report, overlay
This commit is contained in:
@@ -195,7 +195,7 @@ void PDFDrawSpaceController::recalculate()
|
||||
QSizeF pageSize = PDFPage::getRotatedBox(catalog->getPage(leftIndex)->getRotatedMediaBoxMM(), m_pageRotation).size();
|
||||
PDFReal xPos = -pageSize.width() - m_horizontalSpacingMM * 0.5;
|
||||
QRectF rect(xPos, yPos, pageSize.width(), pageSize.height());
|
||||
m_layoutItems.emplace_back(blockIndex, leftIndex, rect);
|
||||
m_layoutItems.emplace_back(blockIndex, leftIndex, -1, rect);
|
||||
yPosAdvance = qMax(yPosAdvance, pageSize.height());
|
||||
boundingRect = boundingRect.united(rect);
|
||||
}
|
||||
@@ -205,7 +205,7 @@ void PDFDrawSpaceController::recalculate()
|
||||
QSizeF pageSize = PDFPage::getRotatedBox(catalog->getPage(rightIndex)->getRotatedMediaBoxMM(), m_pageRotation).size();
|
||||
PDFReal xPos = m_horizontalSpacingMM * 0.5;
|
||||
QRectF rect(xPos, yPos, pageSize.width(), pageSize.height());
|
||||
m_layoutItems.emplace_back(blockIndex, rightIndex, rect);
|
||||
m_layoutItems.emplace_back(blockIndex, rightIndex, -1, rect);
|
||||
yPosAdvance = qMax(yPosAdvance, pageSize.height());
|
||||
boundingRect = boundingRect.united(rect);
|
||||
}
|
||||
@@ -267,7 +267,7 @@ void PDFDrawSpaceController::recalculate()
|
||||
{
|
||||
QSizeF pageSize = PDFPage::getRotatedBox(catalog->getPage(i)->getRotatedMediaBoxMM(), m_pageRotation).size();
|
||||
QRectF rect(-pageSize.width() * 0.5, -pageSize.height() * 0.5, pageSize.width(), pageSize.height());
|
||||
m_layoutItems.emplace_back(i, i, rect);
|
||||
m_layoutItems.emplace_back(i, i, -1, rect);
|
||||
m_blockItems.emplace_back(rect);
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ void PDFDrawSpaceController::recalculate()
|
||||
// Top of current page is at yPos.
|
||||
QSizeF pageSize = PDFPage::getRotatedBox(catalog->getPage(i)->getRotatedMediaBoxMM(), m_pageRotation).size();
|
||||
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||
m_layoutItems.emplace_back(0, i, rect);
|
||||
m_layoutItems.emplace_back(0, i, -1, rect);
|
||||
yPos += pageSize.height() + m_verticalSpacingMM;
|
||||
boundingRectangle = boundingRectangle.united(rect);
|
||||
}
|
||||
@@ -382,10 +382,10 @@ void PDFDrawSpaceController::recalculate()
|
||||
// We do not support page rotation for custom layout
|
||||
Q_ASSERT(m_pageRotation == PageRotation::None);
|
||||
|
||||
// Assure, that layout items are sorted by block
|
||||
// Assure, that layout items are sorted by block and page group
|
||||
auto comparator = [](const LayoutItem& l, const LayoutItem& r)
|
||||
{
|
||||
return l.blockIndex < r.blockIndex;
|
||||
return std::tie(l.blockIndex, l.groupIndex) < std::tie(r.blockIndex, r.groupIndex);
|
||||
};
|
||||
std::stable_sort(m_layoutItems.begin(), m_layoutItems.end(), comparator);
|
||||
|
||||
@@ -566,7 +566,7 @@ void PDFDrawWidgetProxy::update()
|
||||
m_layout.items.reserve(items.size());
|
||||
for (const PDFDrawSpaceController::LayoutItem& item : items)
|
||||
{
|
||||
m_layout.items.emplace_back(item.pageIndex, fromDeviceSpace(item.pageRectMM).toRect());
|
||||
m_layout.items.emplace_back(item.pageIndex, item.groupIndex, fromDeviceSpace(item.pageRectMM).toRect());
|
||||
}
|
||||
|
||||
m_layout.blockRect = fromDeviceSpace(rectangle).toRect();
|
||||
@@ -762,8 +762,13 @@ void PDFDrawWidgetProxy::drawPages(QPainter* painter, QRect rect, PDFRenderer::F
|
||||
QRect placedRect = item.pageRect.translated(m_horizontalOffset - m_layout.blockRect.left(), m_verticalOffset - m_layout.blockRect.top());
|
||||
if (placedRect.intersects(rect))
|
||||
{
|
||||
GroupInfo groupInfo = getGroupInfo(item.groupIndex);
|
||||
|
||||
// Clear the page space by paper color
|
||||
painter->fillRect(placedRect, paperColor);
|
||||
if (groupInfo.drawPaper)
|
||||
{
|
||||
painter->fillRect(placedRect, paperColor);
|
||||
}
|
||||
|
||||
const PDFPrecompiledPage* compiledPage = m_compiler->getCompiledPage(item.pageIndex, true);
|
||||
if (compiledPage && compiledPage->isValid())
|
||||
@@ -773,7 +778,7 @@ void PDFDrawWidgetProxy::drawPages(QPainter* painter, QRect rect, PDFRenderer::F
|
||||
|
||||
const PDFPage* page = m_controller->getDocument()->getCatalog()->getPage(item.pageIndex);
|
||||
QMatrix matrix = createPagePointToDevicePointMatrix(page, placedRect) * baseMatrix;
|
||||
compiledPage->draw(painter, page->getCropBox(), matrix, features);
|
||||
compiledPage->draw(painter, page->getCropBox(), matrix, features, groupInfo.transparency);
|
||||
PDFTextLayoutGetter layoutGetter = m_textLayoutCompiler->getTextLayoutLazy(item.pageIndex);
|
||||
|
||||
// Draw text blocks/text lines, if it is enabled
|
||||
@@ -1001,6 +1006,22 @@ PDFWidgetSnapshot PDFDrawWidgetProxy::getSnapshot() const
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::setGroupTransparency(PDFInteger groupIndex, bool drawPaper, PDFReal transparency)
|
||||
{
|
||||
GroupInfo groupInfo;
|
||||
groupInfo.drawPaper = drawPaper;
|
||||
groupInfo.transparency = transparency;
|
||||
|
||||
if (groupInfo == GroupInfo())
|
||||
{
|
||||
m_groupInfos.erase(groupIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_groupInfos[groupIndex] = std::move(groupInfo);
|
||||
}
|
||||
}
|
||||
|
||||
QRect PDFDrawWidgetProxy::getPagesIntersectingRectBoundingBox(QRect rect) const
|
||||
{
|
||||
QRect resultRect;
|
||||
@@ -1385,6 +1406,17 @@ void PDFDrawWidgetProxy::updateVerticalScrollbarFromOffset()
|
||||
}
|
||||
}
|
||||
|
||||
PDFDrawWidgetProxy::GroupInfo PDFDrawWidgetProxy::getGroupInfo(int groupIndex) const
|
||||
{
|
||||
auto it = m_groupInfos.find(groupIndex);
|
||||
if (it != m_groupInfos.cend())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return GroupInfo();
|
||||
}
|
||||
|
||||
PDFWidgetAnnotationManager* PDFDrawWidgetProxy::getAnnotationManager() const
|
||||
{
|
||||
return m_widget->getAnnotationManager();
|
||||
|
@@ -77,9 +77,9 @@ public:
|
||||
/// page and page rectangle, in which the page is contained.
|
||||
struct LayoutItem
|
||||
{
|
||||
constexpr inline explicit LayoutItem() : blockIndex(-1), pageIndex(-1) { }
|
||||
constexpr inline explicit LayoutItem(PDFInteger blockIndex, PDFInteger pageIndex, const QRectF& pageRectMM) :
|
||||
blockIndex(blockIndex), pageIndex(pageIndex), pageRectMM(pageRectMM) { }
|
||||
constexpr inline explicit LayoutItem() : blockIndex(-1), pageIndex(-1), groupIndex(-1) { }
|
||||
constexpr inline explicit LayoutItem(PDFInteger blockIndex, PDFInteger pageIndex, PDFInteger groupIndex, const QRectF& pageRectMM) :
|
||||
blockIndex(blockIndex), pageIndex(pageIndex), groupIndex(groupIndex), pageRectMM(pageRectMM) { }
|
||||
|
||||
bool operator ==(const LayoutItem&) const = default;
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
|
||||
PDFInteger blockIndex;
|
||||
PDFInteger pageIndex;
|
||||
PDFInteger groupIndex; ///< Page group index
|
||||
QRectF pageRectMM;
|
||||
};
|
||||
|
||||
@@ -371,6 +372,13 @@ public:
|
||||
|
||||
/// Returns snapshot of current view area
|
||||
PDFWidgetSnapshot getSnapshot() const;
|
||||
|
||||
/// Sets page group transparency settings. All pages with a given group index
|
||||
/// will be displayed with this transparency settings.
|
||||
/// \param groupIndex Group index
|
||||
/// \param drawPaper Draw background paper
|
||||
/// \param transparency Page graphics transparency
|
||||
void setGroupTransparency(PDFInteger groupIndex, bool drawPaper = true, PDFReal transparency = 1.0);
|
||||
|
||||
PDFWidgetAnnotationManager* getAnnotationManager() const;
|
||||
|
||||
@@ -385,12 +393,13 @@ signals:
|
||||
private:
|
||||
struct LayoutItem
|
||||
{
|
||||
constexpr inline explicit LayoutItem() : pageIndex(-1) { }
|
||||
constexpr inline explicit LayoutItem(PDFInteger pageIndex, const QRect& pageRect) :
|
||||
pageIndex(pageIndex), pageRect(pageRect) { }
|
||||
constexpr inline explicit LayoutItem() : pageIndex(-1), groupIndex(-1) { }
|
||||
constexpr inline explicit LayoutItem(PDFInteger pageIndex, PDFInteger groupIndex, const QRect& pageRect) :
|
||||
pageIndex(pageIndex), groupIndex(groupIndex), pageRect(pageRect) { }
|
||||
|
||||
|
||||
PDFInteger pageIndex;
|
||||
PDFInteger groupIndex; ///< Used to create group of pages (for transparency and overlay)
|
||||
QRect pageRect;
|
||||
};
|
||||
|
||||
@@ -406,6 +415,14 @@ private:
|
||||
QRect blockRect;
|
||||
};
|
||||
|
||||
struct GroupInfo
|
||||
{
|
||||
bool operator==(const GroupInfo&) const = default;
|
||||
|
||||
bool drawPaper = true;
|
||||
PDFReal transparency = 1.0;
|
||||
};
|
||||
|
||||
static constexpr size_t INVALID_BLOCK_INDEX = std::numeric_limits<size_t>::max();
|
||||
|
||||
// Minimal/maximal zoom is from 8% to 6400 %, according to the PDF 1.7 Reference,
|
||||
@@ -430,6 +447,8 @@ private:
|
||||
void updateHorizontalScrollbarFromOffset();
|
||||
void updateVerticalScrollbarFromOffset();
|
||||
|
||||
GroupInfo getGroupInfo(int groupIndex) const;
|
||||
|
||||
template<typename T>
|
||||
struct Range
|
||||
{
|
||||
@@ -518,6 +537,11 @@ private:
|
||||
|
||||
/// Surface format for OpenGL
|
||||
QSurfaceFormat m_surfaceFormat;
|
||||
|
||||
/// Page group info for rendering. Group of pages
|
||||
/// can be rendered with transparency or without paper
|
||||
/// as overlay.
|
||||
std::map<PDFInteger, GroupInfo> m_groupInfos;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
@@ -501,13 +501,18 @@ void PDFPrecompiledPageGenerator::setCompositionMode(QPainter::CompositionMode m
|
||||
m_precompiledPage->addSetCompositionMode(mode);
|
||||
}
|
||||
|
||||
void PDFPrecompiledPage::draw(QPainter* painter, const QRectF& cropBox, const QMatrix& pagePointToDevicePointMatrix, PDFRenderer::Features features) const
|
||||
void PDFPrecompiledPage::draw(QPainter* painter,
|
||||
const QRectF& cropBox,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
PDFRenderer::Features features,
|
||||
PDFReal opacity) const
|
||||
{
|
||||
Q_ASSERT(painter);
|
||||
Q_ASSERT(pagePointToDevicePointMatrix.isInvertible());
|
||||
|
||||
painter->save();
|
||||
painter->setWorldMatrix(QMatrix());
|
||||
painter->setOpacity(opacity);
|
||||
|
||||
if (features.testFlag(PDFRenderer::ClipToCropBox))
|
||||
{
|
||||
|
@@ -187,7 +187,12 @@ public:
|
||||
/// \param cropBox Page's crop box
|
||||
/// \param pagePointToDevicePointMatrix Page point to device point transformation matrix
|
||||
/// \param features Renderer features
|
||||
void draw(QPainter* painter, const QRectF& cropBox, const QMatrix& pagePointToDevicePointMatrix, PDFRenderer::Features features) const;
|
||||
/// \param opacity Opacity of page graphics
|
||||
void draw(QPainter* painter,
|
||||
const QRectF& cropBox,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
PDFRenderer::Features features,
|
||||
PDFReal opacity) const;
|
||||
|
||||
/// Redact path - remove all content intersecting given path,
|
||||
/// and fill redact path with given color.
|
||||
|
@@ -106,7 +106,7 @@ PDFDocument PDFRedact::perform(Options options)
|
||||
|
||||
QPainter* painter = contentStreamBuilder.begin(newPageReference);
|
||||
compiledPage.redact(redactPath, matrix, m_redactFillColor);
|
||||
compiledPage.draw(painter, QRectF(), matrix, PDFRenderer::None);
|
||||
compiledPage.draw(painter, QRectF(), matrix, PDFRenderer::None, 1.0);
|
||||
contentStreamBuilder.end(painter);
|
||||
}
|
||||
|
||||
|
@@ -244,7 +244,7 @@ QImage PDFRasterizer::render(PDFInteger pageIndex,
|
||||
QOpenGLPaintDevice device(size);
|
||||
QPainter painter(&device);
|
||||
painter.fillRect(QRect(QPoint(0, 0), size), compiledPage->getPaperColor());
|
||||
compiledPage->draw(&painter, page->getCropBox(), matrix, features);
|
||||
compiledPage->draw(&painter, page->getCropBox(), matrix, features, 1.0);
|
||||
|
||||
if (annotationManager)
|
||||
{
|
||||
@@ -276,7 +276,7 @@ QImage PDFRasterizer::render(PDFInteger pageIndex,
|
||||
image.fill(Qt::white);
|
||||
|
||||
QPainter painter(&image);
|
||||
compiledPage->draw(&painter, page->getCropBox(), matrix, features);
|
||||
compiledPage->draw(&painter, page->getCropBox(), matrix, features, 1.0);
|
||||
|
||||
if (annotationManager)
|
||||
{
|
||||
|
Reference in New Issue
Block a user