mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-11 09:10:36 +01:00
Fixing bugs - annotation rendering
This commit is contained in:
parent
0b2d94d115
commit
e124ae9135
@ -21,6 +21,7 @@
|
|||||||
#include "pdfpainter.h"
|
#include "pdfpainter.h"
|
||||||
#include "pdfdrawspacecontroller.h"
|
#include "pdfdrawspacecontroller.h"
|
||||||
#include "pdfcms.h"
|
#include "pdfcms.h"
|
||||||
|
#include "pdfwidgetutils.h"
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
@ -766,7 +767,7 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||||||
const PDFPage* page = m_document->getCatalog()->getPage(pageIndex);
|
const PDFPage* page = m_document->getCatalog()->getPage(pageIndex);
|
||||||
Q_ASSERT(page);
|
Q_ASSERT(page);
|
||||||
|
|
||||||
const PDFRenderer::Features features = m_proxy->getFeatures();
|
PDFRenderer::Features features = m_proxy->getFeatures();
|
||||||
PDFFontCache* fontCache = m_proxy->getFontCache();
|
PDFFontCache* fontCache = m_proxy->getFontCache();
|
||||||
const PDFCMSPointer cms = m_proxy->getCMSManager()->getCurrentCMS();
|
const PDFCMSPointer cms = m_proxy->getCMSManager()->getCurrentCMS();
|
||||||
const PDFOptionalContentActivity* optionalActivity = m_proxy->getOptionalContentActivity();
|
const PDFOptionalContentActivity* optionalActivity = m_proxy->getOptionalContentActivity();
|
||||||
@ -775,6 +776,14 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||||||
|
|
||||||
for (PageAnnotation& annotation : annotations.annotations)
|
for (PageAnnotation& annotation : annotations.annotations)
|
||||||
{
|
{
|
||||||
|
const PDFAnnotation::Flags annotationFlags = annotation.annotation->getFlags();
|
||||||
|
if (annotationFlags.testFlag(PDFAnnotation::Hidden) || // Annotation is completely hidden
|
||||||
|
(m_target == Target::Print && !annotationFlags.testFlag(PDFAnnotation::Print)) || // Target is print and annotation is marked as not printed
|
||||||
|
(m_target == Target::View && annotationFlags.testFlag(PDFAnnotation::NoView))) // Target is view, and annotation is disabled for screen
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PDFObject appearanceStreamObject = m_document->getObject(getAppearanceStream(annotation));
|
PDFObject appearanceStreamObject = m_document->getObject(getAppearanceStream(annotation));
|
||||||
if (!appearanceStreamObject.isStream())
|
if (!appearanceStreamObject.isStream())
|
||||||
{
|
{
|
||||||
@ -801,7 +810,7 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||||||
|
|
||||||
// "Unrotate" user coordinate space, if NoRotate flag is set
|
// "Unrotate" user coordinate space, if NoRotate flag is set
|
||||||
QMatrix userSpaceToDeviceSpace = pagePointToDevicePointMatrix;
|
QMatrix userSpaceToDeviceSpace = pagePointToDevicePointMatrix;
|
||||||
if (annotation.annotation->getFlags().testFlag(PDFAnnotation::NoRotate))
|
if (annotationFlags.testFlag(PDFAnnotation::NoRotate))
|
||||||
{
|
{
|
||||||
PDFReal rotationAngle = 0.0;
|
PDFReal rotationAngle = 0.0;
|
||||||
switch (page->getPageRotation())
|
switch (page->getPageRotation())
|
||||||
@ -837,6 +846,23 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||||||
userSpaceToDeviceSpace = finalMatrix * userSpaceToDeviceSpace;
|
userSpaceToDeviceSpace = finalMatrix * userSpaceToDeviceSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (annotationFlags.testFlag(PDFAnnotation::NoZoom))
|
||||||
|
{
|
||||||
|
// Jakub Melka: we must adjust annotation rectangle to disable zoom. We calculate
|
||||||
|
// inverse zoom as square root of absolute value of determinant of scale matrix.
|
||||||
|
// Determinant corresponds approximately to zoom squared, and if we will have
|
||||||
|
// unrotated matrix, and both axes are scaled by same value, then determinant will
|
||||||
|
// be exactly zoom squared. Also, we will adjust to target device logical DPI,
|
||||||
|
// if we, for example are using 4K, or 8K monitors.
|
||||||
|
qreal zoom = 1.0 / qSqrt(qAbs(pagePointToDevicePointMatrix.determinant()));
|
||||||
|
zoom = PDFWidgetUtils::scaleDPI_x(painter->device(), zoom);
|
||||||
|
|
||||||
|
QRectF unzoomedRect(annotationRectangle.bottomLeft(), annotationRectangle.size() * zoom);
|
||||||
|
unzoomedRect.translate(0, -unzoomedRect.height());
|
||||||
|
annotationRectangle = unzoomedRect;
|
||||||
|
features.setFlag(PDFRenderer::ClipToCropBox, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Jakub Melka: perform algorithm 8.1, defined in PDF 1.7 reference,
|
// Jakub Melka: perform algorithm 8.1, defined in PDF 1.7 reference,
|
||||||
// chapter 8.4.4 Appearance streams.
|
// chapter 8.4.4 Appearance streams.
|
||||||
|
|
||||||
@ -844,11 +870,12 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
|||||||
QRectF transformedAppearanceBox = formMatrix.mapRect(formBoundingBox);
|
QRectF transformedAppearanceBox = formMatrix.mapRect(formBoundingBox);
|
||||||
|
|
||||||
// Step 2) - calculate matrix A, which maps from form space to annotation space
|
// Step 2) - calculate matrix A, which maps from form space to annotation space
|
||||||
// Matrix A transforms from form space to transformed appearance box space
|
// Matrix A transforms from transformed appearance box space to the
|
||||||
const PDFReal scaleX = transformedAppearanceBox.width() / formBoundingBox.width();
|
// annotation rectangle.
|
||||||
const PDFReal scaleY = transformedAppearanceBox.height() / formBoundingBox.height();
|
const PDFReal scaleX = annotationRectangle.width() / transformedAppearanceBox.width();
|
||||||
const PDFReal translateX = annotationRectangle.left() - formBoundingBox.left() * scaleX;
|
const PDFReal scaleY = annotationRectangle.height() / transformedAppearanceBox.height();
|
||||||
const PDFReal translateY = annotationRectangle.bottom() - formBoundingBox.bottom() * scaleY;
|
const PDFReal translateX = annotationRectangle.left() - transformedAppearanceBox.left() * scaleX;
|
||||||
|
const PDFReal translateY = annotationRectangle.bottom() - transformedAppearanceBox.bottom() * scaleY;
|
||||||
QMatrix A(scaleX, 0.0, 0.0, scaleY, translateX, translateY);
|
QMatrix A(scaleX, 0.0, 0.0, scaleY, translateX, translateY);
|
||||||
|
|
||||||
// Step 3) - compute final matrix AA
|
// Step 3) - compute final matrix AA
|
||||||
@ -919,4 +946,14 @@ PDFAnnotationManager::PageAnnotations& PDFAnnotationManager::getPageAnnotations(
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFAnnotationManager::Target PDFAnnotationManager::getTarget() const
|
||||||
|
{
|
||||||
|
return m_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFAnnotationManager::setTarget(Target target)
|
||||||
|
{
|
||||||
|
m_target = target;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -1036,6 +1036,13 @@ private:
|
|||||||
using BaseClass = QObject;
|
using BaseClass = QObject;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum class Target
|
||||||
|
{
|
||||||
|
View,
|
||||||
|
Print
|
||||||
|
};
|
||||||
|
|
||||||
explicit PDFAnnotationManager(PDFDrawWidgetProxy* proxy, QObject* parent);
|
explicit PDFAnnotationManager(PDFDrawWidgetProxy* proxy, QObject* parent);
|
||||||
virtual ~PDFAnnotationManager() override;
|
virtual ~PDFAnnotationManager() override;
|
||||||
|
|
||||||
@ -1047,6 +1054,9 @@ public:
|
|||||||
|
|
||||||
void setDocument(const PDFDocument* document);
|
void setDocument(const PDFDocument* document);
|
||||||
|
|
||||||
|
Target getTarget() const;
|
||||||
|
void setTarget(Target target);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PageAnnotation
|
struct PageAnnotation
|
||||||
{
|
{
|
||||||
@ -1074,6 +1084,7 @@ private:
|
|||||||
const PDFDocument* m_document;
|
const PDFDocument* m_document;
|
||||||
PDFDrawWidgetProxy* m_proxy;
|
PDFDrawWidgetProxy* m_proxy;
|
||||||
mutable std::map<PDFInteger, PageAnnotations> m_pageAnnotations;
|
mutable std::map<PDFInteger, PageAnnotations> m_pageAnnotations;
|
||||||
|
Target m_target = Target::View;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -50,6 +50,13 @@ int PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, int unscaledSize)
|
|||||||
return (logicalDPI_x / defaultDPI_x) * unscaledSize;
|
return (logicalDPI_x / defaultDPI_x) * unscaledSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFReal PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize)
|
||||||
|
{
|
||||||
|
const double logicalDPI_x = device->logicalDpiX();
|
||||||
|
const double defaultDPI_x = qt_default_dpi_x();
|
||||||
|
return (logicalDPI_x / defaultDPI_x) * unscaledSize;
|
||||||
|
}
|
||||||
|
|
||||||
void PDFWidgetUtils::scaleWidget(QWidget* widget, QSize unscaledSize)
|
void PDFWidgetUtils::scaleWidget(QWidget* widget, QSize unscaledSize)
|
||||||
{
|
{
|
||||||
const double logicalDPI_x = widget->logicalDpiX();
|
const double logicalDPI_x = widget->logicalDpiX();
|
||||||
|
@ -37,6 +37,10 @@ public:
|
|||||||
/// \param device Paint device to obtain logical DPI for scaling
|
/// \param device Paint device to obtain logical DPI for scaling
|
||||||
static int scaleDPI_x(QPaintDevice* device, int unscaledSize);
|
static int scaleDPI_x(QPaintDevice* device, int unscaledSize);
|
||||||
|
|
||||||
|
/// Scale horizontal DPI value
|
||||||
|
/// \param device Paint device to obtain logical DPI for scaling
|
||||||
|
static PDFReal scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize);
|
||||||
|
|
||||||
/// Scales widget based on DPI
|
/// Scales widget based on DPI
|
||||||
/// \param widget Widget to be scaled
|
/// \param widget Widget to be scaled
|
||||||
/// \param unscaledSize Unscaled size of the widget
|
/// \param unscaledSize Unscaled size of the widget
|
||||||
|
Loading…
x
Reference in New Issue
Block a user