Extract image tool

This commit is contained in:
Jakub Melka
2020-02-29 14:26:36 +01:00
parent 9de47cc183
commit 475103f5d5
9 changed files with 587 additions and 60 deletions

View File

@ -438,7 +438,7 @@ void PDFPrecompiledPageGenerator::performImagePainting(const QImage& image)
matrix.map(QPointF(1.0, 1.0)), matrix.map(QPointF(1.0, 1.0)),
matrix.map(QPointF(0.0, 1.0)), matrix.map(QPointF(0.0, 1.0)),
matrix.map(QPointF(0.5, 0.5)), matrix.map(QPointF(0.5, 0.5)),
}); }, image);
if (isTransparencyGroupActive()) if (isTransparencyGroupActive())
{ {

View File

@ -47,7 +47,7 @@ void PDFSnapInfo::addPageMediaBox(const QRectF& mediaBox)
addLine(tl, bl); addLine(tl, bl);
} }
void PDFSnapInfo::addImage(const std::array<QPointF, 5>& points) void PDFSnapInfo::addImage(const std::array<QPointF, 5>& points, const QImage& image)
{ {
m_snapPoints.insert(m_snapPoints.cend(), { m_snapPoints.insert(m_snapPoints.cend(), {
SnapPoint(SnapType::ImageCorner, points[0]), SnapPoint(SnapType::ImageCorner, points[0]),
@ -61,6 +61,15 @@ void PDFSnapInfo::addImage(const std::array<QPointF, 5>& points)
{ {
addLine(points[i], points[(i + 1) % 4]); addLine(points[i], points[(i + 1) % 4]);
} }
SnapImage snapImage;
snapImage.imagePath.moveTo(points[0]);
snapImage.imagePath.lineTo(points[1]);
snapImage.imagePath.lineTo(points[2]);
snapImage.imagePath.lineTo(points[3]);
snapImage.imagePath.lineTo(points[0]);
snapImage.image = image;
m_snapImages.emplace_back(qMove(snapImage));
} }
void PDFSnapInfo::addLine(const QPointF& start, const QPointF& end) void PDFSnapInfo::addLine(const QPointF& start, const QPointF& end)
@ -140,6 +149,7 @@ bool PDFSnapper::isSnappingAllowed(PDFInteger pageIndex) const
void PDFSnapper::updateSnappedPoint(const QPointF& mousePoint) void PDFSnapper::updateSnappedPoint(const QPointF& mousePoint)
{ {
m_snappedPoint = std::nullopt; m_snappedPoint = std::nullopt;
m_snappedImage = std::nullopt;
m_mousePoint = mousePoint; m_mousePoint = mousePoint;
// Iterate trough all points, check, if some satisfies condition // Iterate trough all points, check, if some satisfies condition
@ -151,7 +161,17 @@ void PDFSnapper::updateSnappedPoint(const QPointF& mousePoint)
if (distanceSquared < toleranceSquared && isSnappingAllowed(snapPoint.pageIndex)) if (distanceSquared < toleranceSquared && isSnappingAllowed(snapPoint.pageIndex))
{ {
m_snappedPoint = snapPoint; m_snappedPoint = snapPoint;
return; break;
}
}
// Iterate trough all images, check, if some is under mouse cursor
for (const ViewportSnapImage& snapImage : m_snapImages)
{
if (snapImage.viewportPath.contains(mousePoint))
{
m_snappedImage = snapImage;
break;
} }
} }
} }
@ -220,6 +240,32 @@ void PDFSnapper::buildSnapPoints(const PDFWidgetSnapshot& snapshot)
updateSnappedPoint(m_mousePoint); updateSnappedPoint(m_mousePoint);
} }
void PDFSnapper::buildSnapImages(const PDFWidgetSnapshot& snapshot)
{
// First, clear all snap images
m_snapImages.clear();
// Second, create snapping points from snapshot
for (const PDFWidgetSnapshot::SnapshotItem& item : snapshot.items)
{
if (!item.compiledPage)
{
continue;
}
const PDFSnapInfo* info = item.compiledPage->getSnapInfo();
for (const PDFSnapInfo::SnapImage& snapImage : info->getSnapImages())
{
ViewportSnapImage viewportSnapImage;
viewportSnapImage.image = snapImage.image;
viewportSnapImage.imagePath = snapImage.imagePath;
viewportSnapImage.pageIndex = item.pageIndex;
viewportSnapImage.viewportPath = item.pageToDeviceMatrix.map(snapImage.imagePath);
m_snapImages.emplace_back(qMove(viewportSnapImage));
}
}
}
int PDFSnapper::getSnapPointTolerance() const int PDFSnapper::getSnapPointTolerance() const
{ {
return m_snapPointTolerance; return m_snapPointTolerance;
@ -240,6 +286,16 @@ QPointF PDFSnapper::getSnappedPoint() const
return m_mousePoint; return m_mousePoint;
} }
const PDFSnapper::ViewportSnapImage* PDFSnapper::getSnappedImage() const
{
if (m_snappedImage.has_value())
{
return &*m_snappedImage;
}
return nullptr;
}
void PDFSnapper::setReferencePoint(PDFInteger pageIndex, QPointF pagePoint) void PDFSnapper::setReferencePoint(PDFInteger pageIndex, QPointF pagePoint)
{ {
m_currentPage = pageIndex; m_currentPage = pageIndex;
@ -252,4 +308,15 @@ void PDFSnapper::clearReferencePoint()
m_referencePoint = std::nullopt; m_referencePoint = std::nullopt;
} }
void PDFSnapper::clear()
{
clearReferencePoint();
m_snapPoints.clear();
m_snapImages.clear();
m_snappedPoint = std::nullopt;
m_snappedImage = std::nullopt;
m_mousePoint = QPointF();
}
} // namespace pdf } // namespace pdf

View File

@ -20,6 +20,9 @@
#include "pdfglobal.h" #include "pdfglobal.h"
#include <QImage>
#include <QPainterPath>
#include <array> #include <array>
#include <optional> #include <optional>
@ -63,6 +66,12 @@ public:
QPointF point; QPointF point;
}; };
struct SnapImage
{
QPainterPath imagePath;
QImage image;
};
/// Adds page media box. Media box must be in page coordinates. /// Adds page media box. Media box must be in page coordinates.
/// \param mediaBox Media box /// \param mediaBox Media box
void addPageMediaBox(const QRectF& mediaBox); void addPageMediaBox(const QRectF& mediaBox);
@ -71,7 +80,8 @@ public:
/// points are defined - four corners and center. /// points are defined - four corners and center.
/// \param points Four corner points in clockwise order, fifth point is center, /// \param points Four corner points in clockwise order, fifth point is center,
/// all in page coordinates. /// all in page coordinates.
void addImage(const std::array<QPointF, 5>& points); /// \param image Image
void addImage(const std::array<QPointF, 5>& points, const QImage& image);
/// Adds line and line center points /// Adds line and line center points
/// \param start Start point of line, in page coordinates /// \param start Start point of line, in page coordinates
@ -84,9 +94,14 @@ public:
/// Returns lines /// Returns lines
const std::vector<QLineF>& getLines() const { return m_snapLines; } const std::vector<QLineF>& getLines() const { return m_snapLines; }
/// Returns snap images (together with painter path in page coordinates,
/// in which image is painted).
const std::vector<SnapImage>& getSnapImages() const { return m_snapImages; }
private: private:
std::vector<SnapPoint> m_snapPoints; std::vector<SnapPoint> m_snapPoints;
std::vector<QLineF> m_snapLines; std::vector<QLineF> m_snapLines;
std::vector<SnapImage> m_snapImages;
}; };
/// Snap engine, which handles snapping of points on the page. /// Snap engine, which handles snapping of points on the page.
@ -95,6 +110,18 @@ class PDFSnapper
public: public:
PDFSnapper(); PDFSnapper();
struct ViewportSnapPoint : public PDFSnapInfo::SnapPoint
{
QPointF viewportPoint;
PDFInteger pageIndex;
};
struct ViewportSnapImage : public PDFSnapInfo::SnapImage
{
PDFInteger pageIndex;
QPainterPath viewportPath;
};
/// Sets snap point pixel size /// Sets snap point pixel size
/// \param snapPointPixelSize Snap point diameter in pixels /// \param snapPointPixelSize Snap point diameter in pixels
void setSnapPointPixelSize(int snapPointPixelSize) { m_snapPointPixelSize = snapPointPixelSize; } void setSnapPointPixelSize(int snapPointPixelSize) { m_snapPointPixelSize = snapPointPixelSize; }
@ -111,7 +138,7 @@ public:
/// \param pageIndex Page index to be tested for allowing snapping /// \param pageIndex Page index to be tested for allowing snapping
bool isSnappingAllowed(PDFInteger pageIndex) const; bool isSnappingAllowed(PDFInteger pageIndex) const;
/// Updates snapped point using given information. If current page is set, it means, we are /// Updates snapped point/image using given information. If current page is set, it means, we are
/// using snapping info from current page, and if we are hovering at different page, /// using snapping info from current page, and if we are hovering at different page,
/// then nothing happens. Otherwise, other page snap info is used to update snapped point. /// then nothing happens. Otherwise, other page snap info is used to update snapped point.
/// If mouse point distance from some snap point is lesser than tolerance, then new snap is set. /// If mouse point distance from some snap point is lesser than tolerance, then new snap is set.
@ -126,6 +153,10 @@ public:
/// \param snapshot Widget snapshot /// \param snapshot Widget snapshot
void buildSnapPoints(const PDFWidgetSnapshot& snapshot); void buildSnapPoints(const PDFWidgetSnapshot& snapshot);
/// Builds snap images from the widget snapshot.
/// \param snapshot Widget snapshot
void buildSnapImages(const PDFWidgetSnapshot& snapshot);
/// Returns current snap point tolerance (while aiming with the mouse cursor, /// Returns current snap point tolerance (while aiming with the mouse cursor,
/// when mouse cursor is at most tolerance distance from some snap point, /// when mouse cursor is at most tolerance distance from some snap point,
/// it is snapped. /// it is snapped.
@ -138,6 +169,10 @@ public:
/// mouse cursor position is returned. /// mouse cursor position is returned.
QPointF getSnappedPoint() const; QPointF getSnappedPoint() const;
/// Returns snapped image. If no image is present at mouse cursor, then
/// nullptr is returned.
const ViewportSnapImage* getSnappedImage() const;
/// Sets current page index and reference point /// Sets current page index and reference point
/// \param pageIndex Page index /// \param pageIndex Page index
/// \param pagePoint Page point /// \param pagePoint Page point
@ -146,14 +181,10 @@ public:
/// Resets reference point (and current page) /// Resets reference point (and current page)
void clearReferencePoint(); void clearReferencePoint();
/// Clears all snapped data, including snap points, images and referenced data.
void clear();
private: private:
struct ViewportSnapPoint : public PDFSnapInfo::SnapPoint
{
QPointF viewportPoint;
PDFInteger pageIndex;
};
struct SnappedPoint struct SnappedPoint
{ {
PDFInteger pageIndex = -1; PDFInteger pageIndex = -1;
@ -161,7 +192,9 @@ private:
}; };
std::vector<ViewportSnapPoint> m_snapPoints; std::vector<ViewportSnapPoint> m_snapPoints;
std::vector<ViewportSnapImage> m_snapImages;
std::optional<ViewportSnapPoint> m_snappedPoint; std::optional<ViewportSnapPoint> m_snappedPoint;
std::optional<ViewportSnapImage> m_snappedImage;
QPointF m_mousePoint; QPointF m_mousePoint;
std::optional<QPointF> m_referencePoint; std::optional<QPointF> m_referencePoint;
PDFInteger m_currentPage = -1; PDFInteger m_currentPage = -1;

View File

@ -709,6 +709,7 @@ PDFToolManager::PDFToolManager(PDFDrawWidgetProxy* proxy, Actions actions, QObje
m_predefinedTools[SelectTextTool] = new PDFSelectTextTool(proxy, actions.selectTextToolAction, actions.copyTextAction, actions.selectAllAction, actions.deselectAction, this); m_predefinedTools[SelectTextTool] = new PDFSelectTextTool(proxy, actions.selectTextToolAction, actions.copyTextAction, actions.selectAllAction, actions.deselectAction, this);
m_predefinedTools[MagnifierTool] = new PDFMagnifierTool(proxy, actions.magnifierAction, this); m_predefinedTools[MagnifierTool] = new PDFMagnifierTool(proxy, actions.magnifierAction, this);
m_predefinedTools[ScreenshotTool] = new PDFScreenshotTool(proxy, actions.screenshotToolAction, this); m_predefinedTools[ScreenshotTool] = new PDFScreenshotTool(proxy, actions.screenshotToolAction, this);
m_predefinedTools[ExtractImageTool] = new PDFExtractImageTool(proxy, actions.extractImageAction, this);
for (PDFWidgetTool* tool : m_predefinedTools) for (PDFWidgetTool* tool : m_predefinedTools)
{ {
@ -952,12 +953,12 @@ PDFPickTool::PDFPickTool(PDFDrawWidgetProxy* proxy, PDFPickTool::Mode mode, QObj
m_mode(mode), m_mode(mode),
m_pageIndex(-1) m_pageIndex(-1)
{ {
setCursor(Qt::BlankCursor); setCursor((m_mode == Mode::Images) ? Qt::CrossCursor : Qt::BlankCursor);
m_snapper.setSnapPointPixelSize(PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 10)); m_snapper.setSnapPointPixelSize(PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 10));
m_snapper.setSnapPointTolerance(m_snapper.getSnapPointPixelSize()); m_snapper.setSnapPointTolerance(m_snapper.getSnapPointPixelSize());
connect(proxy, &PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFPickTool::buildSnapPoints); connect(proxy, &PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFPickTool::buildSnapData);
connect(proxy, &PDFDrawWidgetProxy::pageImageChanged, this, &PDFPickTool::buildSnapPoints); connect(proxy, &PDFDrawWidgetProxy::pageImageChanged, this, &PDFPickTool::buildSnapData);
} }
void PDFPickTool::drawPage(QPainter* painter, void PDFPickTool::drawPage(QPainter* painter,
@ -988,26 +989,37 @@ void PDFPickTool::drawPage(QPainter* painter,
painter->fillRect(selectionRectangle, selectionColor); painter->fillRect(selectionRectangle, selectionColor);
} }
} }
if (m_mode == Mode::Images && m_snapper.getSnappedImage())
{
const PDFSnapper::ViewportSnapImage* snappedImage = m_snapper.getSnappedImage();
QColor selectionColor(Qt::blue);
selectionColor.setAlphaF(0.25);
painter->fillPath(snappedImage->viewportPath, selectionColor);
}
} }
void PDFPickTool::drawPostRendering(QPainter* painter, QRect rect) const void PDFPickTool::drawPostRendering(QPainter* painter, QRect rect) const
{ {
m_snapper.drawSnapPoints(painter); if (m_mode != Mode::Images)
{
m_snapper.drawSnapPoints(painter);
QPoint snappedPoint = m_snapper.getSnappedPoint().toPoint(); QPoint snappedPoint = m_snapper.getSnappedPoint().toPoint();
QPoint hleft = snappedPoint; QPoint hleft = snappedPoint;
QPoint hright = snappedPoint; QPoint hright = snappedPoint;
QPoint vtop = snappedPoint; QPoint vtop = snappedPoint;
QPoint vbottom = snappedPoint; QPoint vbottom = snappedPoint;
hleft.setX(0); hleft.setX(0);
hright.setX(rect.width()); hright.setX(rect.width());
vtop.setY(0); vtop.setY(0);
vbottom.setY(rect.height()); vbottom.setY(rect.height());
painter->setPen(Qt::black); painter->setPen(Qt::black);
painter->drawLine(hleft, hright); painter->drawLine(hleft, hright);
painter->drawLine(vtop, vbottom); painter->drawLine(vtop, vbottom);
}
} }
void PDFPickTool::mousePressEvent(QWidget* widget, QMouseEvent* event) void PDFPickTool::mousePressEvent(QWidget* widget, QMouseEvent* event)
@ -1017,41 +1029,52 @@ void PDFPickTool::mousePressEvent(QWidget* widget, QMouseEvent* event)
if (event->button() == Qt::LeftButton) if (event->button() == Qt::LeftButton)
{ {
// Try to perform pick if (m_mode != Mode::Images)
QPointF pagePoint;
PDFInteger pageIndex = getProxy()->getPageUnderPoint(m_snapper.getSnappedPoint().toPoint(), &pagePoint);
if (pageIndex != -1 && // We have picked some point on page
(m_pageIndex == -1 || m_pageIndex == pageIndex)) // We are under current page
{ {
m_pageIndex = pageIndex; // Try to perform pick point
m_pickedPoints.push_back(pagePoint); QPointF pagePoint;
m_snapper.setReferencePoint(pageIndex, pagePoint); PDFInteger pageIndex = getProxy()->getPageUnderPoint(m_snapper.getSnappedPoint().toPoint(), &pagePoint);
if (pageIndex != -1 && // We have picked some point on page
// Emit signal about picked point (m_pageIndex == -1 || m_pageIndex == pageIndex)) // We are under current page
emit pointPicked(pageIndex, pagePoint);
if (m_mode == Mode::Rectangles && m_pickedPoints.size() == 2)
{ {
QPointF first = m_pickedPoints.front(); m_pageIndex = pageIndex;
QPointF second = m_pickedPoints.back(); m_pickedPoints.push_back(pagePoint);
m_snapper.setReferencePoint(pageIndex, pagePoint);
const qreal xMin = qMin(first.x(), second.x()); // Emit signal about picked point
const qreal xMax = qMax(first.x(), second.x()); emit pointPicked(pageIndex, pagePoint);
const qreal yMin = qMin(first.y(), second.y());
const qreal yMax = qMax(first.y(), second.y());
QRectF pageRectangle(xMin, yMin, xMax - xMin, yMax - yMin); if (m_mode == Mode::Rectangles && m_pickedPoints.size() == 2)
emit rectanglePicked(pageIndex, pageRectangle); {
QPointF first = m_pickedPoints.front();
QPointF second = m_pickedPoints.back();
// We must reset tool, to pick next rectangle const qreal xMin = qMin(first.x(), second.x());
resetTool(); const qreal xMax = qMax(first.x(), second.x());
const qreal yMin = qMin(first.y(), second.y());
const qreal yMax = qMax(first.y(), second.y());
QRectF pageRectangle(xMin, yMin, xMax - xMin, yMax - yMin);
emit rectanglePicked(pageIndex, pageRectangle);
// We must reset tool, to pick next rectangle
resetTool();
}
buildSnapData();
getProxy()->repaintNeeded();
}
}
else
{
// Try to perform pick image
if (const PDFSnapper::ViewportSnapImage* snappedImage = m_snapper.getSnappedImage())
{
emit imagePicked(snappedImage->image);
} }
buildSnapPoints();
getProxy()->repaintNeeded();
} }
} }
else if (event->button() == Qt::RightButton) else if (event->button() == Qt::RightButton && m_mode != Mode::Images)
{ {
// Reset tool to enable new picking (right button means reset the tool) // Reset tool to enable new picking (right button means reset the tool)
resetTool(); resetTool();
@ -1083,13 +1106,14 @@ void PDFPickTool::setActiveImpl(bool active)
if (active) if (active)
{ {
buildSnapPoints(); buildSnapData();
} }
else else
{ {
// Reset tool to reinitialize it for future use. If tool // Reset tool to reinitialize it for future use. If tool
// is activated, then it should be in initial state. // is activated, then it should be in initial state.
resetTool(); resetTool();
m_snapper.clear();
} }
} }
@ -1099,18 +1123,27 @@ void PDFPickTool::resetTool()
m_pageIndex = -1; m_pageIndex = -1;
m_snapper.clearReferencePoint(); m_snapper.clearReferencePoint();
buildSnapPoints(); buildSnapData();
getProxy()->repaintNeeded(); getProxy()->repaintNeeded();
} }
void PDFPickTool::buildSnapPoints() void PDFPickTool::buildSnapData()
{ {
if (!isActive()) if (!isActive())
{ {
return; return;
} }
m_snapper.buildSnapPoints(getProxy()->getSnapshot()); if (m_mode == Mode::Images)
{
// Snap images
m_snapper.buildSnapImages(getProxy()->getSnapshot());
}
else
{
// Snap points
m_snapper.buildSnapPoints(getProxy()->getSnapshot());
}
} }
PDFScreenshotTool::PDFScreenshotTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) : PDFScreenshotTool::PDFScreenshotTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) :
@ -1143,4 +1176,33 @@ void PDFScreenshotTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRecta
} }
} }
PDFExtractImageTool::PDFExtractImageTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) :
BaseClass(proxy, action, parent),
m_pickTool(nullptr)
{
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Images, this);
addTool(m_pickTool);
connect(m_pickTool, &PDFPickTool::imagePicked, this, &PDFExtractImageTool::onImagePicked);
}
void PDFExtractImageTool::updateActions()
{
// Jakub Melka: We do not call base class implementation here, because
// we must verify we have right to extract content (this tool extracts content)
if (QAction* action = getAction())
{
action->setChecked(isActive());
action->setEnabled(getDocument() && getDocument()->getStorage().getSecurityHandler()->isAllowed(PDFSecurityHandler::Permission::CopyContent));
}
}
void PDFExtractImageTool::onImagePicked(const QImage& image)
{
if (!image.isNull())
{
QApplication::clipboard()->setImage(image, QClipboard::Clipboard);
}
}
} // namespace pdf } // namespace pdf

View File

@ -308,13 +308,14 @@ public:
signals: signals:
void pointPicked(PDFInteger pageIndex, QPointF pagePoint); void pointPicked(PDFInteger pageIndex, QPointF pagePoint);
void rectanglePicked(PDFInteger pageIndex, QRectF pageRectangle); void rectanglePicked(PDFInteger pageIndex, QRectF pageRectangle);
void imagePicked(const QImage& image);
protected: protected:
virtual void setActiveImpl(bool active) override; virtual void setActiveImpl(bool active) override;
private: private:
void resetTool(); void resetTool();
void buildSnapPoints(); void buildSnapData();
Mode m_mode; Mode m_mode;
PDFSnapper m_snapper; PDFSnapper m_snapper;
@ -345,6 +346,31 @@ private:
PDFPickTool* m_pickTool; PDFPickTool* m_pickTool;
}; };
/// Tool that extracts image from page and copies it to the clipboard,
/// using image original size (not zoomed size from widget area)
class PDFFORQTLIBSHARED_EXPORT PDFExtractImageTool : public PDFWidgetTool
{
Q_OBJECT
private:
using BaseClass = PDFWidgetTool;
public:
/// Constructs new extract image tool
/// \param proxy Draw widget proxy
/// \param action Tool activation action
/// \param parent Parent object
explicit PDFExtractImageTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent);
protected:
virtual void updateActions() override;
private:
void onImagePicked(const QImage& image);
PDFPickTool* m_pickTool;
};
/// Manager used for managing tools, their activity, availability /// Manager used for managing tools, their activity, availability
/// and other settings. It also defines a predefined set of tools, /// and other settings. It also defines a predefined set of tools,
/// available for various purposes (text searching, magnifier tool etc.) /// available for various purposes (text searching, magnifier tool etc.)
@ -366,6 +392,7 @@ public:
QAction* copyTextAction = nullptr; QAction* copyTextAction = nullptr;
QAction* magnifierAction = nullptr; QAction* magnifierAction = nullptr;
QAction* screenshotToolAction = nullptr; QAction* screenshotToolAction = nullptr;
QAction* extractImageAction = nullptr;
}; };
/// Construct new text search tool /// Construct new text search tool
@ -385,6 +412,7 @@ public:
SelectTextTool, SelectTextTool,
MagnifierTool, MagnifierTool,
ScreenshotTool, ScreenshotTool,
ExtractImageTool,
ToolEnd ToolEnd
}; };

View File

@ -42,5 +42,6 @@
<file>resources/stop.svg</file> <file>resources/stop.svg</file>
<file>resources/magnifier.svg</file> <file>resources/magnifier.svg</file>
<file>resources/screenshot-tool.svg</file> <file>resources/screenshot-tool.svg</file>
<file>resources/extract-image.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -191,6 +191,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
ui->mainToolBar->addAction(ui->actionSelectText); ui->mainToolBar->addAction(ui->actionSelectText);
ui->mainToolBar->addAction(ui->actionMagnifier); ui->mainToolBar->addAction(ui->actionMagnifier);
ui->mainToolBar->addAction(ui->actionScreenshot); ui->mainToolBar->addAction(ui->actionScreenshot);
ui->mainToolBar->addAction(ui->actionExtractImage);
connect(ui->actionZoom_In, &QAction::triggered, this, [this] { m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomIn); }); connect(ui->actionZoom_In, &QAction::triggered, this, [this] { m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomIn); });
connect(ui->actionZoom_Out, &QAction::triggered, this, [this] { m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomOut); }); connect(ui->actionZoom_Out, &QAction::triggered, this, [this] { m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomOut); });
@ -255,6 +256,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
actions.copyTextAction = ui->actionCopyText; actions.copyTextAction = ui->actionCopyText;
actions.magnifierAction = ui->actionMagnifier; actions.magnifierAction = ui->actionMagnifier;
actions.screenshotToolAction = ui->actionScreenshot; actions.screenshotToolAction = ui->actionScreenshot;
actions.extractImageAction = ui->actionExtractImage;
m_toolManager = new pdf::PDFToolManager(m_pdfWidget->getDrawWidgetProxy(), actions, this, this); m_toolManager = new pdf::PDFToolManager(m_pdfWidget->getDrawWidgetProxy(), actions, this, this);
m_pdfWidget->setToolManager(m_toolManager); m_pdfWidget->setToolManager(m_toolManager);
updateMagnifierToolSettings(); updateMagnifierToolSettings();

View File

@ -88,6 +88,7 @@
</property> </property>
<addaction name="actionMagnifier"/> <addaction name="actionMagnifier"/>
<addaction name="actionScreenshot"/> <addaction name="actionScreenshot"/>
<addaction name="actionExtractImage"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionRendering_Errors"/> <addaction name="actionRendering_Errors"/>
<addaction name="separator"/> <addaction name="separator"/>
@ -486,6 +487,18 @@
<string>Screenshot</string> <string>Screenshot</string>
</property> </property>
</action> </action>
<action name="actionExtractImage">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdfforqtviewer.qrc">
<normaloff>:/resources/extract-image.svg</normaloff>:/resources/extract-image.svg</iconset>
</property>
<property name="text">
<string>Extract Image</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>

View File

@ -0,0 +1,321 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30mm"
height="30mm"
viewBox="0 0 30 30"
version="1.1"
id="svg5291"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="extract-image.svg">
<defs
id="defs5285">
<inkscape:path-effect
effect="bspline"
id="path-effect975"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<inkscape:path-effect
effect="bspline"
id="path-effect967"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<inkscape:path-effect
effect="bspline"
id="path-effect963"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<inkscape:path-effect
effect="bspline"
id="path-effect959"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<inkscape:path-effect
effect="bspline"
id="path-effect891"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<inkscape:path-effect
effect="bspline"
id="path-effect843"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 15 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="30 : 15 : 1"
inkscape:persp3d-origin="15 : 10 : 1"
id="perspective5921" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="15.999999"
inkscape:cx="107.4567"
inkscape:cy="-24.152196"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2035"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1" />
<metadata
id="metadata5288">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Melka</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-267)">
<flowRoot
xml:space="preserve"
id="flowRoot5913"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
id="flowRegion5915"><rect
id="rect5917"
width="129.22377"
height="91.747108"
x="-13.788582"
y="-33.515606" /></flowRegion><flowPara
id="flowPara5919" /></flowRoot> <rect
style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect839"
width="21.44504"
height="17.937128"
x="1.964431"
y="269.59152" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.5231773,284.72995 -0.099219,-5.32474"
id="path845"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 8.7643231,284.79609 8.6320314,279.47135"
id="path847"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.310938,284.59766 -0.297656,-5.2586"
id="path849"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.4239583,279.40521 -0.8598956,1.32291"
id="path851"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.2916669,281.42266 -0.7276042,1.12447"
id="path853"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.3578127,283.27474 -1.0914062,1.25677"
id="path855"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.4239583,279.40521 1.3229169,1.2237"
id="path857"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.2916669,281.42266 1.2567708,1.15755"
id="path859"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 5.3578127,283.27474 1.190625,0.89297"
id="path861"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.6320314,279.47135 -0.9591146,1.38907"
id="path863"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.6320314,279.47135 0.8598961,1.15756"
id="path865"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.6320314,281.4888 -0.8929687,0.89297"
id="path867"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.6320314,281.4888 0.8598961,0.79375"
id="path869"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.4335939,283.14245 -0.6945312,0.99218"
id="path871"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.4335939,283.14245 1.289844,1.25677"
id="path873"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.013282,279.33906 -0.727605,1.45521"
id="path875"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.013282,279.33906 1.058333,1.35599"
id="path877"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.211719,281.22422 -0.777213,1.35599"
id="path879"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.211719,281.22422 1.223698,1.38906"
id="path881"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.261329,283.2582 -0.859896,1.37253"
id="path883"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.261329,283.2582 1.637109,1.10795"
id="path885"
inkscape:connector-curvature="0" />
<ellipse
style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path887"
cx="18.462955"
cy="274.27063"
rx="2.9352217"
ry="2.8194661" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 3.7183874,284.62876 c 0.022905,0.0382 0.046302,0.0772 0.079041,0.0971 0.03274,0.0199 0.071717,0.0199 0.1143279,0.024 0.042611,0.004 0.089399,0.0119 0.1474068,0.0315 0.058007,0.0196 0.1281781,0.0507 0.2068384,0.0661 0.07866,0.0153 0.1644089,0.0153 0.2380693,0.0233 0.07366,0.008 0.1360229,0.0236 0.2142472,0.0352 0.078224,0.0116 0.171785,0.0194 0.34697,0.0507 0.1751849,0.0313 0.4324366,0.0859 0.6860219,0.12081 0.2535852,0.0349 0.5030367,0.0505 0.7758104,0.074 0.2727737,0.0234 0.5690007,0.0546 0.7874224,0.0701 0.2184216,0.0155 0.358738,0.0155 0.5146453,0.0155 0.1559074,0 0.3274052,0 0.8185131,0 0.4911078,0 1.3018252,0 1.8043855,0.0158 0.50256,0.0158 0.697449,0.0469 0.826312,0.0623 0.128862,0.0154 0.191224,0.0154 0.257482,0.0154 0.06626,0 0.136421,0 0.237761,0 0.101339,0 0.23386,0 0.323508,0 0.08965,0 0.136418,0 0.183191,0 0.04677,0 0.09354,0 0.13275,-0.004 0.03921,-0.004 0.07039,-0.0121 0.101338,-0.0156 0.03095,-0.004 0.06213,-0.004 0.09741,-0.008 0.03528,-0.004 0.07425,-0.012 0.116931,-0.0156 0.04268,-0.004 0.08945,-0.004 0.128679,-0.0122 0.03923,-0.009 0.07041,-0.0242 0.132518,-0.0312 0.06211,-0.007 0.155649,-0.007 0.222132,-0.0196 0.06648,-0.0126 0.105462,-0.036 0.155909,-0.0468 0.05045,-0.0108 0.112809,-0.0108 0.171538,-0.0231 0.05873,-0.0124 0.1133,-0.0358 0.15201,-0.0468 0.03871,-0.011 0.0621,-0.011 0.08574,-0.0154 0.02364,-0.004 0.04703,-0.0122 0.07795,-0.0156 0.03092,-0.003 0.0699,-0.003 0.109004,-0.0201 0.0391,-0.0167 0.0781,-0.0479 0.101348,-0.0623 0.02325,-0.0144 0.03105,-0.0144 0.04664,-0.0144 0.01559,0 0.03898,0 0.08186,0 0.04288,0 0.105236,0 0.226064,0 0.120829,0 0.300122,0 0.41705,0 0.116929,0 0.1715,0 0.214376,0 0.04288,0 0.07406,0 0.09744,0 0.02338,0 0.03897,0 0.05482,-0.005 0.01585,-0.005 0.03144,-0.0125 0.07015,-0.0156 0.03872,-0.003 0.101082,-0.003 0.186831,-0.003 0.08575,0 0.194884,0 0.417052,0 0.222168,0 0.557368,0 0.791229,0 0.233861,0 0.366382,0 0.45603,0 0.08965,0 0.136417,0 0.163701,0 0.02728,0 0.03508,0 0.04288,0 0.0078,0 0.0156,0 0.02338,-0.005 0.0078,-0.005 0.01558,-0.013 0.02729,-0.0156 0.01171,-0.003 0.0273,-0.003 0.05068,-0.0195 0.02338,-0.0169 0.05458,-0.0481 0.08205,-0.0712 0.02747,-0.0231 0.05086,-0.0387 0.07431,-0.0499 0.02345,-0.0112 0.04684,-0.019 0.06137,-0.0356 0.01453,-0.0166 0.02233,-0.04 0.03872,-0.0502 0.01639,-0.0101 0.03978,-0.0101 0.05536,-0.0153 0.01558,-0.005 0.02338,-0.013 0.03534,-0.0203 0.01196,-0.007 0.02755,-0.0151 0.05484,-0.0266 0.02729,-0.0115 0.06627,-0.0271 0.10134,-0.0429 0.03507,-0.0157 0.06625,-0.0313 0.08548,-0.0384 0.01923,-0.007 0.02703,-0.007 0.03482,-0.0122 0.0078,-0.005 0.01558,-0.013 0.02729,-0.0156 0.01171,-0.003 0.0273,-0.003 0.05068,-0.003 0.02338,0 0.05457,0 0.09354,0 0.03898,0 0.08575,0 0.116928,0 0.03118,0 0.04677,0 0.06975,0.004 0.02298,0.004 0.05418,0.0119 0.08965,0.0156 0.03547,0.004 0.07445,0.004 0.104601,0.0117 0.03015,0.008 0.05354,0.0236 0.07016,0.0312 0.01662,0.008 0.02442,0.008 0.0435,0.0117 0.01908,0.004 0.05029,0.0119 0.09356,0.0156 0.04327,0.004 0.09784,0.004 0.147707,0.0156 0.04987,0.012 0.09664,0.0354 0.13642,0.0468 0.03978,0.0114 0.07096,0.0114 0.106038,0.0114 0.03507,0 0.07406,0 0.179292,0 0.105238,0 0.276735,0 0.389766,0 0.113031,0 0.167602,0 0.206578,0 0.03898,0 0.06237,0 0.07796,0 0.01559,0 0.02339,0 0.04247,0.004 0.01908,0.004 0.05029,0.0119 0.08106,0.0237 0.03077,0.0117 0.06195,0.0273 0.09783,0.0349 0.03588,0.008 0.07486,0.008 0.09688,0.0114 0.02202,0.004 0.02987,0.0117 0.05365,0.0276 0.02378,0.0158 0.06275,0.0392 0.113976,0.0588 0.05122,0.0195 0.113583,0.0351 0.151644,0.0505 0.03806,0.0154 0.0536,0.0309 0.08893,0.0584 0.03533,0.0275 0.08991,0.0665 0.120809,0.0896 0.03089,0.0232 0.03874,0.031 0.06314,0.039 0.0244,0.008 0.0634,0.0158 0.09333,0.0386 0.02993,0.0228 0.05333,0.0618 0.07437,0.0817 0.02105,0.0199 0.03664,0.0199 0.05557,0.024 0.01893,0.004 0.04235,0.012 0.09201,0.0776 0.04966,0.0656 0.127614,0.19036 0.178267,0.27217 0.05065,0.0818 0.07405,0.1208 0.08598,0.15493 0.01193,0.0341 0.01193,0.0653 0.02391,0.0902 0.01199,0.0249 0.03537,0.0405 0.04677,0.0546 0.0114,0.014 0.0114,0.0297 0.02386,0.043 0.01246,0.0133 0.03588,0.0211 0.0577,0.0284"
id="path889"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect891"
inkscape:original-d="m 3.7183874,284.62876 c 0.026032,0.0363 0.049418,0.0753 0.070158,0.11693 0.041623,-0.003 0.0806,-0.003 0.1169305,0 0.049418,0.005 0.09619,0.0129 0.1403164,0.0234 0.072804,0.0285 0.1429624,0.0597 0.2104748,0.0935 0.088395,-0.003 0.1741437,-0.003 0.2572469,0 0.065009,0.0129 0.1273715,0.0285 0.1870888,0.0468 0.09619,0.005 0.1897342,0.013 0.2806329,0.0234 0.2598928,0.0519 0.5171398,0.10649 0.7717406,0.1637 0.2520977,0.0129 0.5015492,0.0285 0.7483549,0.0468 0.2988697,0.0285 0.5950932,0.0597 0.8886711,0.0935 0.1429624,-0.003 0.2832788,-0.003 0.4209495,0 0.174144,-0.003 0.3456418,-0.003 0.5144939,0 0.8133636,-0.003 1.624081,-0.003 2.4321533,0 0.19753,0.0285 0.392414,0.0597 0.584652,0.0935 0.06501,-0.003 0.127372,-0.003 0.187089,0 0.0728,-0.003 0.142962,-0.003 0.210474,0 0.135167,-0.003 0.267688,-0.003 0.397564,0 0.04942,-0.003 0.09619,-0.003 0.140316,0 0.04942,-0.003 0.09619,-0.003 0.140317,0 0.03383,-0.0104 0.06501,-0.0182 0.09354,-0.0234 0.03383,-0.003 0.06501,-0.003 0.09354,0 0.04162,-0.0104 0.0806,-0.0182 0.116931,-0.0234 0.04942,-0.003 0.09619,-0.003 0.140316,0 0.03383,-0.0182 0.06501,-0.0338 0.09354,-0.0468 0.09619,-0.003 0.189734,-0.003 0.280633,0 0.04162,-0.026 0.0806,-0.0494 0.11693,-0.0702 0.06501,-0.003 0.127372,-0.003 0.187089,0 0.05721,-0.026 0.111781,-0.0494 0.163702,-0.0702 0.02603,-0.003 0.04942,-0.003 0.07016,0 0.02603,-0.0104 0.04942,-0.0182 0.07016,-0.0234 0.04162,-0.003 0.0806,-0.003 0.11693,0 0.04162,-0.0338 0.0806,-0.065 0.116931,-0.0935 0.01044,-0.003 0.01824,-0.003 0.02339,0 0.02603,-0.003 0.04942,-0.003 0.07016,0 0.06501,-0.003 0.127371,-0.003 0.187088,0 0.18194,-0.003 0.361233,-0.003 0.53788,0 0.05721,-0.003 0.111781,-0.003 0.163703,0 0.03383,-0.003 0.06501,-0.003 0.09354,0 0.01824,-0.003 0.03383,-0.003 0.04677,0 0.01824,-0.0104 0.03383,-0.0182 0.04677,-0.0234 0.06501,-0.003 0.127372,-0.003 0.187089,0 0.111781,-0.003 0.220916,-0.003 0.327405,0 0.337847,-0.003 0.673047,-0.003 1.005602,0 0.135167,-0.003 0.267688,-0.003 0.397563,0 0.04942,-0.003 0.09619,-0.003 0.140317,0 0.01044,-0.003 0.01824,-0.003 0.02339,0 0.01044,-0.003 0.01824,-0.003 0.02339,0 0.01044,-0.0104 0.01824,-0.0182 0.02339,-0.0234 0.01824,-0.003 0.03383,-0.003 0.04677,0 0.03383,-0.0338 0.06501,-0.065 0.09354,-0.0935 0.02603,-0.0182 0.04942,-0.0338 0.07016,-0.0468 0.02603,-0.0104 0.04942,-0.0182 0.07016,-0.0234 0.01044,-0.026 0.01824,-0.0494 0.02339,-0.0702 0.02603,-0.003 0.04942,-0.003 0.07016,0 0.01044,-0.0104 0.01824,-0.0182 0.02339,-0.0234 0.01824,-0.0104 0.03383,-0.0182 0.04677,-0.0234 0.04162,-0.0182 0.0806,-0.0338 0.11693,-0.0468 0.03383,-0.0182 0.06501,-0.0338 0.09355,-0.0468 0.01044,-0.003 0.01824,-0.003 0.02339,0 0.01044,-0.0104 0.01824,-0.0182 0.02339,-0.0234 0.01824,-0.003 0.03383,-0.003 0.04677,0 0.03383,-0.003 0.06501,-0.003 0.09354,0 0.04942,-0.003 0.09619,-0.003 0.140317,0 0.01824,-0.003 0.03383,-0.003 0.04677,0 0.03383,0.005 0.06501,0.0129 0.09354,0.0234 0.04162,-0.003 0.0806,-0.003 0.116931,0 0.02603,0.0129 0.04942,0.0285 0.07016,0.0468 0.01044,-0.003 0.01824,-0.003 0.02339,0 0.03383,0.005 0.06501,0.0129 0.09355,0.0234 0.05721,-0.003 0.111781,-0.003 0.163702,0 0.04942,0.0207 0.09619,0.0441 0.140317,0.0702 0.03383,-0.003 0.06501,-0.003 0.09354,0 0.04162,-0.003 0.0806,-0.003 0.116931,0 0.174144,-0.003 0.345641,-0.003 0.514493,0 0.05721,-0.003 0.111781,-0.003 0.163703,0 0.02603,-0.003 0.04942,-0.003 0.07016,0 0.01044,-0.003 0.01824,-0.003 0.02339,0 0.03383,0.005 0.06501,0.0129 0.09354,0.0234 0.03383,0.0129 0.06501,0.0285 0.09354,0.0468 0.04162,-0.003 0.0806,-0.003 0.11693,0 0.01044,0.005 0.01824,0.0129 0.02339,0.0234 0.04162,0.0207 0.0806,0.0441 0.11693,0.0702 0.06501,0.0129 0.127372,0.0285 0.187089,0.0468 0.01824,0.013 0.03383,0.0285 0.04677,0.0468 0.05721,0.0363 0.111781,0.0753 0.163703,0.11693 0.01044,0.005 0.01824,0.0129 0.02339,0.0234 0.04162,0.005 0.0806,0.0129 0.116931,0.0234 0.02603,0.0363 0.04942,0.0753 0.07016,0.11693 0.01824,-0.003 0.03383,-0.003 0.04677,0 0.02603,0.005 0.04942,0.0129 0.07016,0.0234 0.0806,0.12208 0.158553,0.2468 0.233861,0.37417 0.02603,0.0363 0.04942,0.0753 0.07016,0.11693 0.0026,0.0285 0.0026,0.0597 0,0.0935 0.02603,0.0129 0.04942,0.0285 0.07016,0.0468 0.0026,0.0129 0.0026,0.0285 0,0.0468 0.02603,0.005 0.04942,0.0129 0.07016,0.0234" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 3.320824,285.08479 c 0.026032,0 0.049418,0 0.071383,0.0135 0.021965,0.0135 0.045367,0.0408 0.075293,0.0626 0.029926,0.0218 0.065005,0.0374 0.099659,0.0587 0.034655,0.0213 0.06975,0.0486 0.1167167,0.0798 0.046967,0.0313 0.1054411,0.0663 0.1579747,0.0994 0.052534,0.0331 0.099321,0.0643 0.1503107,0.0916 0.05099,0.0274 0.1055574,0.0507 0.1659126,0.078 0.060355,0.0273 0.1266289,0.0585 0.1927927,0.0916 0.066164,0.0331 0.1324323,0.0682 0.2088421,0.0974 0.07641,0.0292 0.1621589,0.0526 0.2478304,0.078 0.085672,0.0254 0.1714203,0.0527 0.2981264,0.0917 0.1267061,0.039 0.2943147,0.0897 0.4271924,0.11873 0.1328777,0.0291 0.2303278,0.0369 0.3195583,0.0546 0.08923,0.0177 0.171092,0.045 0.255282,0.0624 0.08419,0.0174 0.1699477,0.0252 0.2498226,0.033 0.079875,0.008 0.1539411,0.0156 0.2119728,0.0275 0.058032,0.0118 0.1009067,0.0274 0.1443693,0.035 0.043463,0.008 0.086338,0.008 0.1487004,0.008 0.062363,0 0.1442141,0 0.1948844,0 0.05067,0 0.070157,0 0.080463,0.002 0.010305,0.002 0.014254,0.006 0.019512,0.008 0.00526,0.002 0.00916,0.002 0.016953,0.002 0.00779,0 0.019489,0 0.035345,-0.005 0.015857,-0.005 0.035345,-0.0123 0.056516,-0.0156 0.021171,-0.003 0.044557,-0.003 0.068159,-0.005 0.023602,-0.002 0.046907,-0.006 0.06622,-0.008 0.019314,-0.002 0.034903,-0.002 0.066084,-0.002 0.031182,0 0.077954,0 0.1851398,0 0.1071863,0 0.2747866,0 0.397679,-0.004 0.1228925,-0.004 0.2008463,-0.0118 0.2552981,-0.0156 0.054452,-0.004 0.085634,-0.004 0.1304572,-0.004 0.044823,0 0.1032886,0 0.1792933,0 0.076005,0 0.1695492,0 0.2358099,0 0.066261,0 0.1052367,0 0.140117,0.002 0.03488,0.002 0.066075,0.006 0.099398,0.008 0.033323,0.002 0.068402,0.002 0.1226414,0.01 0.054239,0.008 0.1282949,0.0236 0.1966402,0.0352 0.068345,0.0116 0.1307201,0.0194 0.193077,0.0272 0.062357,0.008 0.1247318,0.0156 0.1890498,0.0234 0.064318,0.008 0.1305895,0.0156 0.1946801,0.0274 0.064091,0.0118 0.1264546,0.0274 0.1892136,0.035 0.06276,0.008 0.125121,0.008 0.189254,0.0116 0.06413,0.004 0.130401,0.0118 0.183194,0.0156 0.05279,0.004 0.09177,0.004 0.128802,0.004 0.03703,0 0.0721,0 0.120824,0 0.04872,0 0.111085,0 0.157859,0 0.04677,0 0.07795,0 0.110363,0.008 0.03241,0.008 0.06749,0.0237 0.09939,0.0312 0.0319,0.008 0.05918,0.008 0.08382,0.008"
id="path957"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect959"
inkscape:original-d="m 3.320824,285.08479 c 0.026032,-0.003 0.049418,-0.003 0.070158,0 0.026032,0.0246 0.049418,0.0519 0.070158,0.0818 0.037725,0.0129 0.072804,0.0285 0.1052375,0.0468 0.037725,0.0246 0.072804,0.0519 0.1052372,0.0818 0.061111,0.0324 0.1195763,0.0675 0.1753957,0.10524 0.049418,0.0285 0.09619,0.0597 0.1403165,0.0935 0.057213,0.0207 0.1117809,0.0441 0.1637025,0.0702 0.068906,0.0285 0.1351671,0.0597 0.1987817,0.0935 0.068907,0.0324 0.1351671,0.0675 0.1987817,0.10524 0.088395,0.0207 0.174144,0.0441 0.257247,0.0702 0.088395,0.0246 0.1741437,0.0519 0.2572469,0.0819 0.1702462,0.048 0.3378465,0.0987 0.502801,0.15201 0.1000876,0.005 0.1975297,0.0129 0.2923259,0.0234 0.084497,0.0246 0.1663486,0.0519 0.245554,0.0818 0.088395,0.005 0.1741437,0.0129 0.257247,0.0234 0.076702,0.005 0.1507577,0.0129 0.2221677,0.0234 0.04552,0.0129 0.088395,0.0285 0.1286234,0.0468 0.04552,-0.003 0.088395,-0.003 0.1286235,0 0.084497,-0.003 0.1663483,-0.003 0.245554,0 0.022135,-0.003 0.041622,-0.003 0.058465,0 0.00654,10e-4 0.01044,0.005 0.011692,0.0117 0.00654,-0.003 0.010441,-0.003 0.011692,0 0.014338,-0.003 0.026032,-0.003 0.035079,0 0.022135,-0.0104 0.041623,-0.0182 0.058465,-0.0234 0.026032,-0.003 0.049418,-0.003 0.070158,0 0.026032,-0.007 0.049418,-0.0104 0.070158,-0.0117 0.018238,-0.003 0.033827,-0.003 0.046772,0 0.049418,-0.003 0.09619,-0.003 0.1403165,0 0.1702461,-0.003 0.3378464,-0.003 0.5028009,0 0.080599,-0.0104 0.1585529,-0.0182 0.2338607,-0.0234 0.033827,-0.003 0.065009,-0.003 0.093545,0 0.061111,-0.003 0.1195761,-0.003 0.1753955,0 0.09619,-0.003 0.1897345,-0.003 0.2806329,0 0.041623,-0.003 0.080599,-0.003 0.1169305,0 0.033827,0.001 0.065009,0.005 0.093545,0.0117 0.037725,-0.003 0.072804,-0.003 0.1052372,0 0.076702,0.0129 0.1507578,0.0285 0.222168,0.0468 0.065009,0.005 0.1273715,0.0129 0.1870885,0.0234 0.065009,0.005 0.1273717,0.0129 0.1870887,0.0234 0.068907,0.005 0.1351669,0.0129 0.1987817,0.0234 0.065008,0.0129 0.1273717,0.0285 0.1870887,0.0468 0.06501,-0.003 0.127372,-0.003 0.187089,0 0.06891,0.005 0.135167,0.0129 0.198782,0.0234 0.04162,-0.003 0.0806,-0.003 0.11693,0 0.03773,-0.003 0.0728,-0.003 0.105238,0 0.06501,-0.003 0.127371,-0.003 0.187088,0 0.03383,-0.003 0.06501,-0.003 0.09354,0 0.03773,0.0129 0.07281,0.0285 0.105238,0.0468 0.02993,-0.003 0.05721,-0.003 0.08185,0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 19.609232,285.59928 c 0.05089,0.0431 0.101573,0.0859 0.132392,0.11663 0.03082,0.0307 0.04251,0.0502 0.08177,0.0916 0.03926,0.0414 0.105527,0.10374 0.183291,0.19316 0.07776,0.0894 0.167412,0.20634 0.261105,0.31372 0.09369,0.10738 0.191133,0.20483 0.259227,0.2768 0.06809,0.072 0.107088,0.11875 0.148059,0.16559 0.04097,0.0468 0.08386,0.0936 0.109031,0.12259 0.02518,0.029 0.03297,0.0407 0.05136,0.053 0.01839,0.0123 0.04566,0.024 0.06055,0.0314 0.01489,0.007 0.01886,0.0114 0.02272,0.0153 0.0039,0.004 0.0078,0.008 0.0118,0.0118"
id="path961"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect963"
inkscape:original-d="m 19.609232,285.59928 c 0.05332,0.0402 0.103985,0.0831 0.152009,0.12863 0.01434,0.0168 0.02603,0.0363 0.03508,0.0585 0.06891,0.0597 0.135166,0.12208 0.198781,0.18709 0.09229,0.11429 0.181939,0.23122 0.26894,0.35079 0.100088,0.0948 0.19753,0.19224 0.292326,0.29233 0.04162,0.0441 0.0806,0.0909 0.116931,0.14031 0.04552,0.0441 0.08839,0.0909 0.128623,0.14032 0.01044,0.009 0.01824,0.0207 0.02339,0.0351 0.02993,0.009 0.05721,0.0207 0.08185,0.0351 0.0065,0.001 0.01044,0.005 0.01169,0.0117 0.0065,10e-4 0.01044,0.005 0.01169,0.0117" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 18.007285,285.66944 c 0.05439,0.0622 0.108971,0.12454 0.145896,0.16919 0.03693,0.0446 0.05643,0.0719 0.09159,0.11495 0.03516,0.043 0.08584,0.10148 0.130816,0.14841 0.04497,0.0469 0.08396,0.082 0.120846,0.1189 0.03688,0.0369 0.07197,0.0759 0.111076,0.11498 0.03911,0.0391 0.08199,0.0781 0.116858,0.11488 0.03486,0.0368 0.06216,0.0719 0.08032,0.0918 0.01816,0.0199 0.02599,0.0238 0.03915,0.0353 0.01316,0.0115 0.0326,0.0309 0.04423,0.0426 0.01163,0.0116 0.0156,0.0156 0.01946,0.0195 0.0039,0.004 0.0078,0.008 0.01307,0.01 0.0052,0.002 0.0092,0.002 0.01043,0.002"
id="path965"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect967"
inkscape:original-d="m 18.007285,285.66944 c 0.05721,0.0597 0.111781,0.12208 0.163703,0.18709 0.02213,0.0246 0.04162,0.0519 0.05846,0.0818 0.05332,0.0558 0.103985,0.11429 0.152009,0.1754 0.04162,0.0324 0.0806,0.0675 0.116931,0.10523 0.03772,0.0363 0.0728,0.0753 0.105237,0.11694 0.04552,0.0363 0.0884,0.0753 0.128624,0.11693 0.02993,0.0324 0.05721,0.0675 0.08185,0.10523 0.01044,10e-4 0.01823,0.005 0.02339,0.0117 0.02213,0.0169 0.04162,0.0363 0.05847,0.0585 0.0065,10e-4 0.01044,0.005 0.01169,0.0117 0.0065,0.001 0.01044,0.005 0.01169,0.0117 0.0065,-0.003 0.01044,-0.003 0.01169,0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 3.7183874,284.62876 c -0.04622,0.0476 -0.095074,0.0979 -0.1247472,0.1263 -0.029673,0.0284 -0.040496,0.0338 -0.06012,0.0499 -0.019624,0.016 -0.047201,0.0436 -0.063735,0.0587 -0.016535,0.0151 -0.022045,0.0151 -0.027592,0.0166 -0.00555,0.001 -0.010808,0.007 -0.02168,0.0131 -0.010872,0.006 -0.027258,0.0118 -0.049749,0.0302 -0.022491,0.0184 -0.050068,0.0515 -0.068992,0.0714 -0.018924,0.0199 -0.029747,0.0253 -0.038387,0.0304 -0.00864,0.005 -0.013901,0.0103 -0.02279,0.0239 -0.00889,0.0136 -0.0199,0.0356 -0.035569,0.0529 -0.01567,0.0173 -0.037865,0.0284 -0.05271,0.0414 -0.014845,0.013 -0.020347,0.0295 -0.025104,0.0408 -0.00476,0.0113 -0.010019,0.0166 -0.014187,0.0277 -0.00417,0.0111 -0.00417,0.0276 -0.00564,0.0387 -0.00147,0.0111 -0.00673,0.0163 -0.010898,0.0302 -0.00417,0.0139 -0.00417,0.0359 -0.011117,0.0552 -0.00695,0.0193 -0.023468,0.0358 -0.033064,0.0579 -0.0096,0.022 -0.0096,0.0496 -0.011065,0.0662 -0.00147,0.0166 -0.00673,0.0218 -0.010899,0.0357 -0.00417,0.0139 -0.00417,0.036 -0.00667,0.0633 -0.0025,0.0273 -0.00802,0.0604 -0.011027,0.0937 -0.00301,0.0332 -0.00301,0.0663 -0.00696,0.0861 -0.00395,0.0198 -0.014777,0.0252 -0.021948,0.0303 -0.00717,0.005 -0.00717,0.0101 -0.00717,0.0158 0,0.006 0,0.0107 0,0.0247 0,0.014 0,0.036 0,0.0498 0,0.0138 0,0.0188 0,0.0246 0,0.006 0,0.0107 -0.0045,0.0217 -0.0045,0.011 -0.015506,0.0275 -0.022041,0.0388 -0.00653,0.0113 -0.00653,0.0163 -0.00653,0.033 0,0.0167 0,0.0443 0,0.0609 0,0.0166 0,0.0216 0,0.0273 0,0.006 0,0.0108 -0.00147,0.0165 -0.00147,0.006 -0.00673,0.011 -0.010899,0.0276 -0.00417,0.0166 -0.00417,0.0442 -0.00605,0.0631 -0.00189,0.0189 -0.00754,0.0302 -0.011097,0.047 -0.00355,0.0168 -0.00355,0.0388 -0.00765,0.0553 -0.00409,0.0164 -0.0153,0.0277 -0.02214,0.0414 -0.00684,0.0138 -0.00684,0.0303 -0.011561,0.0493 -0.00472,0.019 -0.015731,0.041 -0.022042,0.0577 -0.00631,0.0166 -0.00631,0.028 -0.010404,0.039 -0.00409,0.0109 -0.0153,0.0222 -0.02214,0.0359 -0.00684,0.0138 -0.00684,0.0303 -0.00684,0.0414 0,0.0111 0,0.0161 -0.00147,0.0218 -0.00147,0.006 -0.00673,0.011 -0.013127,0.0218 -0.0064,0.0108 -0.011899,0.0273 -0.016622,0.0372 -0.00472,0.01 -0.010233,0.01 -0.016198,0.0136 -0.00596,0.004 -0.011623,0.0151 -0.018729,0.0293"
id="path973"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect975"
inkscape:original-d="m 3.7183874,284.62876 c -0.046192,0.0476 -0.095029,0.0979 -0.1465122,0.1508 -0.00838,0.003 -0.019402,0.008 -0.033073,0.0165 -0.024916,0.0249 -0.052476,0.0525 -0.082682,0.0827 -0.00287,-0.003 -0.00838,-0.003 -0.016536,0 -0.00287,0.003 -0.00838,0.008 -0.016537,0.0165 -0.013891,0.003 -0.030427,0.008 -0.049609,0.0165 -0.024916,0.0304 -0.052476,0.0635 -0.082682,0.0992 -0.00838,0.003 -0.019402,0.008 -0.033073,0.0165 -0.00287,0.003 -0.00838,0.008 -0.016536,0.0165 -0.00838,0.0194 -0.019402,0.0414 -0.033073,0.0661 -0.019402,0.008 -0.041451,0.0194 -0.066146,0.0331 -0.00287,0.0139 -0.00838,0.0304 -0.016536,0.0496 -0.00287,0.003 -0.00838,0.008 -0.016537,0.0165 0.00265,0.0139 0.00265,0.0304 0,0.0496 -0.00287,0.003 -0.00838,0.008 -0.016536,0.0165 0.00265,0.0194 0.00265,0.0414 0,0.0661 -0.013891,0.0139 -0.030427,0.0304 -0.049609,0.0496 0.00265,0.0249 0.00265,0.0525 0,0.0827 -0.00287,0.003 -0.00838,0.008 -0.016536,0.0165 0.00265,0.0194 0.00265,0.0415 0,0.0661 -0.00287,0.0304 -0.00838,0.0635 -0.016536,0.0992 0.00265,0.0304 0.00265,0.0635 0,0.0992 -0.00838,0.003 -0.019402,0.008 -0.033073,0.0165 0.00265,0.003 0.00265,0.008 0,0.0165 0.00265,0.003 0.00265,0.008 0,0.0165 0.00265,0.0194 0.00265,0.0414 0,0.0661 0.00265,0.003 0.00265,0.008 0,0.0165 0.00265,0.003 0.00265,0.008 0,0.0165 -0.00838,0.0139 -0.019402,0.0304 -0.033073,0.0496 0.00265,0.003 0.00265,0.008 0,0.0165 0.00265,0.0249 0.00265,0.0525 0,0.0827 0.00265,0.003 0.00265,0.008 0,0.0165 0.00265,0.003 0.00265,0.008 0,0.0165 -0.00287,0.003 -0.00838,0.008 -0.016536,0.0165 0.00265,0.0249 0.00265,0.0525 0,0.0827 -0.00287,0.008 -0.00838,0.0194 -0.016536,0.0331 0.00265,0.0194 0.00265,0.0414 0,0.0661 -0.00838,0.008 -0.019402,0.0194 -0.033073,0.0331 0.00265,0.0139 0.00265,0.0304 0,0.0496 -0.00838,0.0194 -0.019402,0.0414 -0.033073,0.0661 0.00265,0.008 0.00265,0.0194 0,0.0331 -0.00838,0.008 -0.019402,0.0194 -0.033073,0.0331 0.00265,0.0139 0.00265,0.0304 0,0.0496 0.00265,0.003 0.00265,0.008 0,0.0165 -0.00287,0.003 -0.00838,0.008 -0.016536,0.0165 -0.00287,0.0139 -0.00838,0.0304 -0.016536,0.0496 -0.00287,-0.003 -0.00838,-0.003 -0.016537,0 -0.00287,0.008 -0.00838,0.0194 -0.016536,0.0331" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 17.164845,288.93021 6.746875,2.4474 -3.208073,0.76067 -0.529167,2.64584 -3.009635,-5.72162"
id="path981"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 20.703647,292.13828 4.57671,3.90289"
id="path983"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB