mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-28 17:37:46 +01:00
Dimension painting
This commit is contained in:
parent
ae970640bb
commit
762a239193
@ -50,6 +50,13 @@ int PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, int unscaledSize)
|
|||||||
return (logicalDPI_x / defaultDPI_x) * unscaledSize;
|
return (logicalDPI_x / defaultDPI_x) * unscaledSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PDFWidgetUtils::scaleDPI_y(QPaintDevice* device, int unscaledSize)
|
||||||
|
{
|
||||||
|
const double logicalDPI_y = device->logicalDpiY();
|
||||||
|
const double defaultDPI_y = qt_default_dpi_y();
|
||||||
|
return (logicalDPI_y / defaultDPI_y) * unscaledSize;
|
||||||
|
}
|
||||||
|
|
||||||
PDFReal PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize)
|
PDFReal PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize)
|
||||||
{
|
{
|
||||||
const double logicalDPI_x = device->logicalDpiX();
|
const double logicalDPI_x = device->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 vertical DPI value
|
||||||
|
/// \param device Paint device to obtain logical DPI for scaling
|
||||||
|
static int scaleDPI_y(QPaintDevice* device, int unscaledSize);
|
||||||
|
|
||||||
/// Scale horizontal DPI value
|
/// Scale horizontal DPI value
|
||||||
/// \param device Paint device to obtain logical DPI for scaling
|
/// \param device Paint device to obtain logical DPI for scaling
|
||||||
static PDFReal scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize);
|
static PDFReal scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize);
|
||||||
|
@ -17,8 +17,12 @@
|
|||||||
|
|
||||||
#include "dimensionsplugin.h"
|
#include "dimensionsplugin.h"
|
||||||
#include "pdfdrawwidget.h"
|
#include "pdfdrawwidget.h"
|
||||||
|
#include "pdfwidgetutils.h"
|
||||||
#include "settingsdialog.h"
|
#include "settingsdialog.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QFontMetricsF>
|
||||||
|
|
||||||
namespace pdfplugin
|
namespace pdfplugin
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -131,42 +135,112 @@ void DimensionsPlugin::drawPage(QPainter* painter,
|
|||||||
const QMatrix& pagePointToDevicePointMatrix,
|
const QMatrix& pagePointToDevicePointMatrix,
|
||||||
QList<pdf::PDFRenderError>& errors) const
|
QList<pdf::PDFRenderError>& errors) const
|
||||||
{
|
{
|
||||||
if (!m_showDimensionsAction || !m_showDimensionsAction->isChecked())
|
Q_UNUSED(compiledPage);
|
||||||
|
Q_UNUSED(layoutGetter);
|
||||||
|
Q_UNUSED(errors);
|
||||||
|
|
||||||
|
if (!m_showDimensionsAction || !m_showDimensionsAction->isChecked() || m_dimensions.empty())
|
||||||
{
|
{
|
||||||
// Nothing to draw
|
// Nothing to draw
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLocale locale;
|
||||||
|
for (const Dimension& dimension : m_dimensions)
|
||||||
|
{
|
||||||
|
if (pageIndex != dimension.getPageIndex())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (dimension.getType())
|
||||||
|
{
|
||||||
|
case Dimension::Linear:
|
||||||
|
{
|
||||||
|
QPointF p1 = pagePointToDevicePointMatrix.map(dimension.getPolygon().front());
|
||||||
|
QPointF p2 = pagePointToDevicePointMatrix.map(dimension.getPolygon().back());
|
||||||
|
|
||||||
|
// Swap so p1 is to the left of the page, before p2 (for correct determination of angle)
|
||||||
|
if (p1.x() > p2.x())
|
||||||
|
{
|
||||||
|
qSwap(p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineF line(p1, p2);
|
||||||
|
|
||||||
|
if (qFuzzyIsNull(line.length()))
|
||||||
|
{
|
||||||
|
// If we have zero line, then do nothing
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineF unitVectorLine = line.normalVector().unitVector();
|
||||||
|
QPointF unitVector = unitVectorLine.p2() - unitVectorLine.p1();
|
||||||
|
qreal extensionLineSize = pdf::PDFWidgetUtils::scaleDPI_y(painter->device(), 5);
|
||||||
|
|
||||||
|
painter->setPen(Qt::black);
|
||||||
|
painter->drawLine(line);
|
||||||
|
|
||||||
|
QLineF extensionLineLeft(p1 - unitVector * extensionLineSize, p1 + unitVector * extensionLineSize);
|
||||||
|
QLineF extensionLineRight(p2 - unitVector * extensionLineSize, p2 + unitVector * extensionLineSize);
|
||||||
|
|
||||||
|
painter->drawLine(extensionLineLeft);
|
||||||
|
painter->drawLine(extensionLineRight);
|
||||||
|
|
||||||
|
QPointF textPoint = line.center();
|
||||||
|
qreal angle = line.angle();
|
||||||
|
QFontMetricsF fontMetrics(painter->font());
|
||||||
|
QRectF textRect(-line.length() * 0.5, -fontMetrics.lineSpacing(), line.length(), fontMetrics.lineSpacing());
|
||||||
|
|
||||||
|
QString text = QString("%1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_lengthUnit.scale, 'f', 2), m_lengthUnit.symbol);
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->translate(textPoint);
|
||||||
|
painter->rotate(-angle);
|
||||||
|
painter->drawText(textRect, Qt::AlignCenter | Qt::TextDontClip, text);
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Dimension::Perimeter:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Dimension::Area:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimensionsPlugin::onShowDimensionsTriggered()
|
void DimensionsPlugin::onShowDimensionsTriggered()
|
||||||
{
|
{
|
||||||
if (m_widget)
|
updateGraphics();
|
||||||
{
|
|
||||||
m_widget->update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimensionsPlugin::onClearDimensionsTriggered()
|
void DimensionsPlugin::onClearDimensionsTriggered()
|
||||||
{
|
{
|
||||||
m_dimensions.clear();
|
m_dimensions.clear();
|
||||||
if (m_widget)
|
|
||||||
{
|
|
||||||
m_widget->update();
|
|
||||||
}
|
|
||||||
updateActions();
|
updateActions();
|
||||||
|
updateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimensionsPlugin::onSettingsTriggered()
|
void DimensionsPlugin::onSettingsTriggered()
|
||||||
{
|
{
|
||||||
SettingsDialog dialog(m_widget, m_lengthUnit, m_areaUnit, m_angleUnit);
|
SettingsDialog dialog(m_widget, m_lengthUnit, m_areaUnit, m_angleUnit);
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
m_widget->update();
|
|
||||||
|
updateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimensionsPlugin::onDimensionCreated(Dimension dimension)
|
void DimensionsPlugin::onDimensionCreated(Dimension dimension)
|
||||||
{
|
{
|
||||||
m_dimensions.emplace_back(qMove(dimension));
|
m_dimensions.emplace_back(qMove(dimension));
|
||||||
updateActions();
|
updateActions();
|
||||||
|
updateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimensionsPlugin::updateActions()
|
void DimensionsPlugin::updateActions()
|
||||||
@ -181,4 +255,12 @@ void DimensionsPlugin::updateActions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DimensionsPlugin::updateGraphics()
|
||||||
|
{
|
||||||
|
if (m_widget)
|
||||||
|
{
|
||||||
|
m_widget->getDrawWidget()->getWidget()->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ private:
|
|||||||
void onSettingsTriggered();
|
void onSettingsTriggered();
|
||||||
void onDimensionCreated(Dimension dimension);
|
void onDimensionCreated(Dimension dimension);
|
||||||
void updateActions();
|
void updateActions();
|
||||||
|
void updateGraphics();
|
||||||
|
|
||||||
std::array<DimensionTool*, DimensionTool::LastStyle> m_dimensionTools;
|
std::array<DimensionTool*, DimensionTool::LastStyle> m_dimensionTools;
|
||||||
std::vector<Dimension> m_dimensions;
|
std::vector<Dimension> m_dimensions;
|
||||||
|
@ -77,10 +77,19 @@ void DimensionTool::drawPage(QPainter* painter,
|
|||||||
|
|
||||||
void DimensionTool::onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint)
|
void DimensionTool::onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(pagePoint);
|
||||||
|
|
||||||
if (Dimension::isComplete(getDimensionType(), m_pickTool->getPickedPoints()))
|
if (Dimension::isComplete(getDimensionType(), m_pickTool->getPickedPoints()))
|
||||||
{
|
{
|
||||||
// Create a new dimension...
|
// Create a new dimension...
|
||||||
emit dimensionCreated(Dimension(pageIndex, getMeasuredValue(), m_pickTool->getPickedPoints()));
|
std::vector<QPointF> points = m_pickTool->getPickedPoints();
|
||||||
|
for (QPointF& point : points)
|
||||||
|
{
|
||||||
|
point = adjustPagePoint(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf::PDFReal measuredValue = getMeasuredValue(pageIndex, points);
|
||||||
|
emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points)));
|
||||||
m_pickTool->resetTool();
|
m_pickTool->resetTool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +103,17 @@ QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const
|
|||||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||||
if (!pickedPoints.empty())
|
if (!pickedPoints.empty())
|
||||||
{
|
{
|
||||||
pagePoint.setY(pickedPoints.front().y());
|
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex());
|
||||||
|
const bool rotated = page->getPageRotation() == pdf::PageRotation::Rotate90 || page->getPageRotation() == pdf::PageRotation::Rotate270;
|
||||||
|
|
||||||
|
if (rotated)
|
||||||
|
{
|
||||||
|
pagePoint.setX(pickedPoints.front().x());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pagePoint.setY(pickedPoints.front().y());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -104,7 +123,17 @@ QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const
|
|||||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||||
if (!pickedPoints.empty())
|
if (!pickedPoints.empty())
|
||||||
{
|
{
|
||||||
pagePoint.setX(pickedPoints.front().x());
|
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex());
|
||||||
|
const bool rotated = page->getPageRotation() == pdf::PageRotation::Rotate90 || page->getPageRotation() == pdf::PageRotation::Rotate270;
|
||||||
|
|
||||||
|
if (!rotated)
|
||||||
|
{
|
||||||
|
pagePoint.setX(pickedPoints.front().x());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pagePoint.setY(pickedPoints.front().y());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -136,9 +165,10 @@ Dimension::Type DimensionTool::getDimensionType() const
|
|||||||
return Dimension::Type::Linear;
|
return Dimension::Type::Linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf::PDFReal DimensionTool::getMeasuredValue() const
|
pdf::PDFReal DimensionTool::getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const
|
||||||
{
|
{
|
||||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(pageIndex);
|
||||||
|
Q_ASSERT(page);
|
||||||
|
|
||||||
switch (getDimensionType())
|
switch (getDimensionType())
|
||||||
{
|
{
|
||||||
@ -153,7 +183,7 @@ pdf::PDFReal DimensionTool::getMeasuredValue() const
|
|||||||
length += qSqrt(QPointF::dotProduct(vector, vector));
|
length += qSqrt(QPointF::dotProduct(vector, vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
return length * page->getUserUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Dimension::Area:
|
case Dimension::Area:
|
||||||
@ -171,7 +201,7 @@ pdf::PDFReal DimensionTool::getMeasuredValue() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
area = qAbs(area) * 0.5;
|
area = qAbs(area) * 0.5;
|
||||||
break;
|
return area * page->getUserUnit() * page->getUserUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -48,15 +48,6 @@ class Dimension
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline explicit Dimension() = default;
|
|
||||||
inline explicit Dimension(pdf::PDFInteger pageIndex, pdf::PDFReal measuredValue, std::vector<QPointF> polygon) :
|
|
||||||
m_pageIndex(pageIndex),
|
|
||||||
m_measuredValue(measuredValue),
|
|
||||||
m_polygon(qMove(polygon))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
Linear,
|
Linear,
|
||||||
@ -64,10 +55,26 @@ public:
|
|||||||
Area
|
Area
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline explicit Dimension() = default;
|
||||||
|
inline explicit Dimension(Type type, pdf::PDFInteger pageIndex, pdf::PDFReal measuredValue, std::vector<QPointF> polygon) :
|
||||||
|
m_type(type),
|
||||||
|
m_pageIndex(pageIndex),
|
||||||
|
m_measuredValue(measuredValue),
|
||||||
|
m_polygon(qMove(polygon))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Type getType() const { return m_type; }
|
||||||
|
pdf::PDFInteger getPageIndex() const { return m_pageIndex; }
|
||||||
|
pdf::PDFReal getMeasuredValue() const { return m_measuredValue; }
|
||||||
|
const std::vector<QPointF>& getPolygon() const { return m_polygon; }
|
||||||
|
|
||||||
/// Returns true, if definition fo given type is complete
|
/// Returns true, if definition fo given type is complete
|
||||||
static bool isComplete(Type type, const std::vector<QPointF>& polygon);
|
static bool isComplete(Type type, const std::vector<QPointF>& polygon);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Type m_type = Linear;
|
||||||
pdf::PDFInteger m_pageIndex = -1;
|
pdf::PDFInteger m_pageIndex = -1;
|
||||||
pdf::PDFReal m_measuredValue = 0.0;
|
pdf::PDFReal m_measuredValue = 0.0;
|
||||||
std::vector<QPointF> m_polygon;
|
std::vector<QPointF> m_polygon;
|
||||||
@ -109,7 +116,7 @@ private:
|
|||||||
void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
|
void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
|
||||||
QPointF adjustPagePoint(QPointF pagePoint) const;
|
QPointF adjustPagePoint(QPointF pagePoint) const;
|
||||||
Dimension::Type getDimensionType() const;
|
Dimension::Type getDimensionType() const;
|
||||||
pdf::PDFReal getMeasuredValue() const;
|
pdf::PDFReal getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const;
|
||||||
|
|
||||||
Style m_style;
|
Style m_style;
|
||||||
int m_previewPointPixelSize;
|
int m_previewPointPixelSize;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user