Magnifier tool

This commit is contained in:
Jakub Melka
2020-02-22 18:27:33 +01:00
parent 5823df0443
commit e9bad256dc
13 changed files with 385 additions and 6 deletions

View File

@@ -647,15 +647,35 @@ QMatrix PDFDrawWidgetProxy::createPagePointToDevicePointMatrix(const PDFPage* pa
void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect)
{
painter->fillRect(rect, Qt::lightGray);
drawPages(painter, rect);
// Use current paper color (it can be a bit different from white)
for (IDocumentDrawInterface* drawInterface : m_drawInterfaces)
{
painter->save();
drawInterface->drawPostRendering(painter, rect);
painter->restore();
}
}
QColor PDFDrawWidgetProxy::getPaperColor()
{
QColor paperColor = getCMSManager()->getCurrentCMS()->getPaperColor();
if (m_features.testFlag(PDFRenderer::InvertColors))
{
paperColor = invertColor(paperColor);
}
return paperColor;
}
void PDFDrawWidgetProxy::drawPages(QPainter* painter, QRect rect)
{
painter->fillRect(rect, Qt::lightGray);
QMatrix baseMatrix = painter->worldMatrix();
// Use current paper color (it can be a bit different from white)
QColor paperColor = getPaperColor();
// Iterate trough pages and display them on the painter device
for (const LayoutItem& item : m_layout.items)
{
@@ -675,7 +695,7 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect)
timer.start();
const PDFPage* page = m_controller->getDocument()->getCatalog()->getPage(item.pageIndex);
QMatrix matrix = createPagePointToDevicePointMatrix(page, placedRect);
QMatrix matrix = createPagePointToDevicePointMatrix(page, placedRect) * baseMatrix;
compiledPage->draw(painter, page->getCropBox(), matrix, m_features);
PDFTextLayoutGetter layoutGetter = m_textLayoutCompiler->getTextLayoutLazy(item.pageIndex);
@@ -1314,4 +1334,10 @@ void IDocumentDrawInterface::drawPage(QPainter* painter,
Q_UNUSED(pagePointToDevicePointMatrix);
}
void IDocumentDrawInterface::drawPostRendering(QPainter* painter, QRect rect) const
{
Q_UNUSED(painter);
Q_UNUSED(rect);
}
} // namespace pdf

View File

@@ -58,6 +58,11 @@ public:
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix) const;
/// Performs drawing of additional graphics after all pages are drawn onto the painter.
/// \param painter Painter
/// \param rect Draw rectangle (usually viewport rectangle of the pdf widget)
virtual void drawPostRendering(QPainter* painter, QRect rect) const;
};
/// This class controls draw space - page layout. Pages are divided into blocks
@@ -210,10 +215,19 @@ public:
/// Draws the actually visible pages on the painter using the rectangle.
/// Rectangle is space in the widget, which is used for painting the PDF.
/// This function is using drawPages function to draw all pages. After that,
/// custom drawing is performed.
/// \sa drawPages
/// \param painter Painter to paint the PDF pages
/// \param rect Rectangle in which the content is painted
void draw(QPainter* painter, QRect rect);
/// Draws the actually visible pages on the painter using the rectangle.
/// Rectangle is space in the widget, which is used for painting the PDF.
/// \param painter Painter to paint the PDF pages
/// \param rect Rectangle in which the content is painted
void drawPages(QPainter* painter, QRect rect);
/// Draws thumbnail image of the given size (so larger of the page size
/// width or height equals to pixel size and the latter size is rescaled
/// using the aspect ratio)
@@ -334,6 +348,9 @@ public:
void registerDrawInterface(IDocumentDrawInterface* drawInterface) { m_drawInterfaces.insert(drawInterface); }
void unregisterDrawInterface(IDocumentDrawInterface* drawInterface) { m_drawInterfaces.erase(drawInterface); }
/// Returns current paper color
QColor getPaperColor();
signals:
void drawSpaceChanged();
void pageLayoutChanged();

View File

@@ -664,6 +664,7 @@ PDFToolManager::PDFToolManager(PDFDrawWidgetProxy* proxy, Actions actions, QObje
{
m_predefinedTools[FindTextTool] = new PDFFindTextTool(proxy, actions.findPrevAction, actions.findNextAction, this, parentDialog);
m_predefinedTools[SelectTextTool] = new PDFSelectTextTool(proxy, actions.selectTextToolAction, actions.copyTextAction, actions.selectAllAction, actions.deselectAction, this);
m_predefinedTools[MagnifierTool] = new PDFMagnifierTool(proxy, actions.magnifierAction, this);
for (PDFWidgetTool* tool : m_predefinedTools)
{
@@ -719,6 +720,11 @@ PDFFindTextTool* PDFToolManager::getFindTextTool() const
return qobject_cast<PDFFindTextTool*>(m_predefinedTools[FindTextTool]);
}
PDFMagnifierTool* PDFToolManager::getMagnifierTool() const
{
return qobject_cast<PDFMagnifierTool*>(m_predefinedTools[MagnifierTool]);
}
void PDFToolManager::keyPressEvent(QWidget* widget, QKeyEvent* event)
{
event->ignore();
@@ -802,5 +808,99 @@ void PDFToolManager::onToolActionTriggered(bool checked)
}
}
PDFMagnifierTool::PDFMagnifierTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) :
BaseClass(proxy, action, parent),
m_magnifierSize(200),
m_magnifierZoom(2.0)
{
setCursor(Qt::BlankCursor);
}
void PDFMagnifierTool::mousePressEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->accept();
}
void PDFMagnifierTool::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->accept();
}
void PDFMagnifierTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
event->accept();
QPoint mousePos = event->pos();
if (m_mousePos != mousePos)
{
m_mousePos = mousePos;
getProxy()->repaintNeeded();
}
}
void PDFMagnifierTool::drawPostRendering(QPainter* painter, QRect rect) const
{
if (!m_mousePos.isNull())
{
QPainterPath path;
path.addEllipse(m_mousePos, m_magnifierSize, m_magnifierSize);
painter->save();
// Clip the painter path for magnifier
painter->setClipPath(path, Qt::IntersectClip);
painter->fillRect(rect, getProxy()->getPaperColor());
painter->scale(m_magnifierZoom, m_magnifierZoom);
// Jakub Melka: this must be explained. We want to display the origin (mouse position)
// at the same position to remain under scaling. If scale == 1, then we translate
// by -m_mousePos + m_mousePos = (0, 0). Otherwise we are m_mousePos / scale away
// from the original position. Example:
// m_mousePos = (100, 100), scale = 2
// we are translating by -(100, 100) + (50, 50) = -(50, 50),
// because origin at (100, 100) is now at position (50, 50) after scale. So, if it has to remain
// the same, we must translate by -(50, 50).
painter->translate(m_mousePos * (1.0 / m_magnifierZoom - 1.0));
getProxy()->drawPages(painter, rect);
painter->restore();
painter->setPen(Qt::black);
painter->setBrush(Qt::NoBrush);
painter->drawPath(path);
}
}
void PDFMagnifierTool::setActiveImpl(bool active)
{
BaseClass::setActiveImpl(active);
if (!active)
{
m_mousePos = QPoint();
}
}
PDFReal PDFMagnifierTool::getMagnifierZoom() const
{
return m_magnifierZoom;
}
void PDFMagnifierTool::setMagnifierZoom(const PDFReal& magnifierZoom)
{
m_magnifierZoom = magnifierZoom;
}
int PDFMagnifierTool::getMagnifierSize() const
{
return m_magnifierSize;
}
void PDFMagnifierTool::setMagnifierSize(int magnifierSize)
{
m_magnifierSize = magnifierSize;
}
} // namespace pdf

View File

@@ -236,6 +236,41 @@ private:
bool m_isCursorOverText;
};
/// Tool to magnify specific area in the drawing widget
class PDFFORQTLIBSHARED_EXPORT PDFMagnifierTool : public PDFWidgetTool
{
Q_OBJECT
private:
using BaseClass = PDFWidgetTool;
public:
/// Constructs new magnifier tool
/// \param proxy Draw widget proxy
/// \param action Tool activation action
/// \param parent Parent object
explicit PDFMagnifierTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent);
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
virtual void drawPostRendering(QPainter* painter, QRect rect) const override;
int getMagnifierSize() const;
void setMagnifierSize(int magnifierSize);
PDFReal getMagnifierZoom() const;
void setMagnifierZoom(const PDFReal& magnifierZoom);
protected:
virtual void setActiveImpl(bool active) override;
private:
QPoint m_mousePos;
int m_magnifierSize;
PDFReal m_magnifierZoom;
};
/// Manager used for managing tools, their activity, availability
/// and other settings. It also defines a predefined set of tools,
/// available for various purposes (text searching, magnifier tool etc.)
@@ -255,6 +290,7 @@ public:
QAction* selectAllAction = nullptr;
QAction* deselectAction = nullptr;
QAction* copyTextAction = nullptr;
QAction* magnifierAction = nullptr;
};
/// Construct new text search tool
@@ -272,6 +308,7 @@ public:
{
FindTextTool,
SelectTextTool,
MagnifierTool,
ToolEnd
};
@@ -285,6 +322,9 @@ public:
/// Returns find text tool
PDFFindTextTool* getFindTextTool() const;
/// Returns magnifier tool
PDFMagnifierTool* getMagnifierTool() const;
/// Handles key press event from widget, over which tool operates
/// \param widget Widget, over which tool operates
/// \param event Event