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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const double logicalDPI_x = device->logicalDpiX();
|
||||
|
@ -37,6 +37,10 @@ public:
|
||||
/// \param device Paint device to obtain logical DPI for scaling
|
||||
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
|
||||
/// \param device Paint device to obtain logical DPI for scaling
|
||||
static PDFReal scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize);
|
||||
|
@ -17,8 +17,12 @@
|
||||
|
||||
#include "dimensionsplugin.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "settingsdialog.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QFontMetricsF>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
@ -131,42 +135,112 @@ void DimensionsPlugin::drawPage(QPainter* painter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
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
|
||||
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()
|
||||
{
|
||||
if (m_widget)
|
||||
{
|
||||
m_widget->update();
|
||||
}
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onClearDimensionsTriggered()
|
||||
{
|
||||
m_dimensions.clear();
|
||||
if (m_widget)
|
||||
{
|
||||
m_widget->update();
|
||||
}
|
||||
updateActions();
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onSettingsTriggered()
|
||||
{
|
||||
SettingsDialog dialog(m_widget, m_lengthUnit, m_areaUnit, m_angleUnit);
|
||||
dialog.exec();
|
||||
m_widget->update();
|
||||
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onDimensionCreated(Dimension dimension)
|
||||
{
|
||||
m_dimensions.emplace_back(qMove(dimension));
|
||||
updateActions();
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
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 onDimensionCreated(Dimension dimension);
|
||||
void updateActions();
|
||||
void updateGraphics();
|
||||
|
||||
std::array<DimensionTool*, DimensionTool::LastStyle> m_dimensionTools;
|
||||
std::vector<Dimension> m_dimensions;
|
||||
|
@ -77,10 +77,19 @@ void DimensionTool::drawPage(QPainter* painter,
|
||||
|
||||
void DimensionTool::onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint)
|
||||
{
|
||||
Q_UNUSED(pagePoint);
|
||||
|
||||
if (Dimension::isComplete(getDimensionType(), m_pickTool->getPickedPoints()))
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
@ -94,7 +103,17 @@ QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const
|
||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||
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;
|
||||
}
|
||||
@ -104,7 +123,17 @@ QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const
|
||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||
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;
|
||||
}
|
||||
@ -136,9 +165,10 @@ Dimension::Type DimensionTool::getDimensionType() const
|
||||
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())
|
||||
{
|
||||
@ -153,7 +183,7 @@ pdf::PDFReal DimensionTool::getMeasuredValue() const
|
||||
length += qSqrt(QPointF::dotProduct(vector, vector));
|
||||
}
|
||||
|
||||
break;
|
||||
return length * page->getUserUnit();
|
||||
}
|
||||
|
||||
case Dimension::Area:
|
||||
@ -171,7 +201,7 @@ pdf::PDFReal DimensionTool::getMeasuredValue() const
|
||||
}
|
||||
|
||||
area = qAbs(area) * 0.5;
|
||||
break;
|
||||
return area * page->getUserUnit() * page->getUserUnit();
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -48,15 +48,6 @@ class Dimension
|
||||
{
|
||||
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
|
||||
{
|
||||
Linear,
|
||||
@ -64,10 +55,26 @@ public:
|
||||
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
|
||||
static bool isComplete(Type type, const std::vector<QPointF>& polygon);
|
||||
|
||||
private:
|
||||
Type m_type = Linear;
|
||||
pdf::PDFInteger m_pageIndex = -1;
|
||||
pdf::PDFReal m_measuredValue = 0.0;
|
||||
std::vector<QPointF> m_polygon;
|
||||
@ -109,7 +116,7 @@ private:
|
||||
void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
|
||||
QPointF adjustPagePoint(QPointF pagePoint) const;
|
||||
Dimension::Type getDimensionType() const;
|
||||
pdf::PDFReal getMeasuredValue() const;
|
||||
pdf::PDFReal getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const;
|
||||
|
||||
Style m_style;
|
||||
int m_previewPointPixelSize;
|
||||
|
Loading…
x
Reference in New Issue
Block a user