mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Polygon/polyline annotation graphics
This commit is contained in:
@ -1254,7 +1254,7 @@ void PDFLineAnnotation::draw(AnnotationDrawParameters& parameters) const
|
|||||||
|
|
||||||
QLineF lineToPaintOrig = info.LCStoGCS.map(lineToPaint);
|
QLineF lineToPaintOrig = info.LCStoGCS.map(lineToPaint);
|
||||||
info = LineGeometryInfo::create(lineToPaintOrig);
|
info = LineGeometryInfo::create(lineToPaintOrig);
|
||||||
drawLine(info, painter, lineEndingSize, getStartLineEnding(), getEndLineEnding(), boundingPath);
|
drawLine(info, painter, lineEndingSize, getStartLineEnding(), getEndLineEnding(), boundingPath, getCaptionOffset(), getContents(), getCaptionPosition() == CaptionPosition::Top);
|
||||||
|
|
||||||
parameters.boundingRectangle = boundingPath.boundingRect();
|
parameters.boundingRectangle = boundingPath.boundingRect();
|
||||||
parameters.boundingRectangle.adjust(-lineEndingSize, -lineEndingSize, lineEndingSize, lineEndingSize);
|
parameters.boundingRectangle.adjust(-lineEndingSize, -lineEndingSize, lineEndingSize, lineEndingSize);
|
||||||
@ -1270,6 +1270,79 @@ QColor PDFLineAnnotation::getFillColor() const
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPolygonalGeometryAnnotation::draw(AnnotationDrawParameters& parameters) const
|
||||||
|
{
|
||||||
|
if (m_vertices.empty())
|
||||||
|
{
|
||||||
|
// Jakub Melka: do not draw empty lines
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter& painter = *parameters.painter;
|
||||||
|
painter.setPen(getPen());
|
||||||
|
painter.setBrush(getBrush());
|
||||||
|
|
||||||
|
const PDFReal penWidth = painter.pen().widthF();
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case AnnotationType::Polygon:
|
||||||
|
{
|
||||||
|
QPolygonF polygon;
|
||||||
|
polygon.reserve(int(m_vertices.size() + 1));
|
||||||
|
for (const QPointF& point : m_vertices)
|
||||||
|
{
|
||||||
|
polygon << point;
|
||||||
|
}
|
||||||
|
if (!polygon.isClosed())
|
||||||
|
{
|
||||||
|
polygon << m_vertices.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.drawPolygon(polygon, Qt::OddEvenFill);
|
||||||
|
parameters.boundingRectangle = polygon.boundingRect();
|
||||||
|
parameters.boundingRectangle.adjust(-penWidth, -penWidth, penWidth, penWidth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case AnnotationType::Polyline:
|
||||||
|
{
|
||||||
|
const PDFReal lineEndingSize = painter.pen().widthF() * 5.0;
|
||||||
|
QPainterPath boundingPath;
|
||||||
|
|
||||||
|
const size_t pointCount = m_vertices.size();
|
||||||
|
const size_t lastPoint = pointCount - 1;
|
||||||
|
for (size_t i = 1; i < pointCount; ++i)
|
||||||
|
{
|
||||||
|
if (i == 1)
|
||||||
|
{
|
||||||
|
// We draw first line
|
||||||
|
drawLine(LineGeometryInfo::create(QLineF(m_vertices[i - 1], m_vertices[i])), painter, lineEndingSize, getStartLineEnding(), AnnotationLineEnding::None, boundingPath, QPointF(), QString(), true);
|
||||||
|
}
|
||||||
|
else if (i == lastPoint)
|
||||||
|
{
|
||||||
|
// We draw last line
|
||||||
|
drawLine(LineGeometryInfo::create(QLineF(m_vertices[i - 1], m_vertices[i])), painter, lineEndingSize, AnnotationLineEnding::None, getEndLineEnding(), boundingPath, QPointF(), QString(), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QLineF line(m_vertices[i - 1], m_vertices[i]);
|
||||||
|
boundingPath.moveTo(line.p1());
|
||||||
|
boundingPath.lineTo(line.p2());
|
||||||
|
painter.drawLine(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters.boundingRectangle = boundingPath.boundingRect();
|
||||||
|
parameters.boundingRectangle.adjust(-lineEndingSize, -lineEndingSize, lineEndingSize, lineEndingSize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QColor PDFPolygonalGeometryAnnotation::getFillColor() const
|
QColor PDFPolygonalGeometryAnnotation::getFillColor() const
|
||||||
{
|
{
|
||||||
QColor color = getDrawColorFromAnnotationColor(getInteriorColor());
|
QColor color = getDrawColorFromAnnotationColor(getInteriorColor());
|
||||||
@ -1308,7 +1381,10 @@ void PDFAnnotation::drawLine(const PDFAnnotation::LineGeometryInfo& info,
|
|||||||
PDFReal lineEndingSize,
|
PDFReal lineEndingSize,
|
||||||
AnnotationLineEnding p1Ending,
|
AnnotationLineEnding p1Ending,
|
||||||
AnnotationLineEnding p2Ending,
|
AnnotationLineEnding p2Ending,
|
||||||
QPainterPath& boundingPath) const
|
QPainterPath& boundingPath,
|
||||||
|
QPointF textOffset,
|
||||||
|
const QString& text,
|
||||||
|
bool textIsAboveLine) const
|
||||||
{
|
{
|
||||||
const PDFReal angle = 30;
|
const PDFReal angle = 30;
|
||||||
const PDFReal lineEndingHalfSize = lineEndingSize * 0.5;
|
const PDFReal lineEndingHalfSize = lineEndingSize * 0.5;
|
||||||
@ -1445,14 +1521,82 @@ void PDFAnnotation::drawLine(const PDFAnnotation::LineGeometryInfo& info,
|
|||||||
QLineF adjustedLine = info.transformedLine;
|
QLineF adjustedLine = info.transformedLine;
|
||||||
adjustedLine.setP1(adjustedLine.p1() + QPointF(startOffset, 0));
|
adjustedLine.setP1(adjustedLine.p1() + QPointF(startOffset, 0));
|
||||||
adjustedLine.setP2(adjustedLine.p2() - QPointF(endOffset, 0));
|
adjustedLine.setP2(adjustedLine.p2() - QPointF(endOffset, 0));
|
||||||
adjustedLine = info.LCStoGCS.map(adjustedLine);
|
|
||||||
|
int textVerticalOffset = 0;
|
||||||
|
const bool drawText = !text.isEmpty();
|
||||||
|
QPainterPath textPath;
|
||||||
|
|
||||||
|
if (drawText)
|
||||||
|
{
|
||||||
|
QFont font = QApplication::font();
|
||||||
|
font.setPixelSize(12.0);
|
||||||
|
|
||||||
|
QFontMetricsF fontMetrics(font, painter.device());
|
||||||
|
textVerticalOffset = fontMetrics.descent() + fontMetrics.leading();
|
||||||
|
|
||||||
|
textPath.addText(0, 0, font, text);
|
||||||
|
textPath = QMatrix(1, 0, 0, -1, 0, 0).map(textPath);
|
||||||
|
}
|
||||||
|
|
||||||
drawLineEnding(info.transformedLine.p1(), p1Ending, false);
|
drawLineEnding(info.transformedLine.p1(), p1Ending, false);
|
||||||
drawLineEnding(info.transformedLine.p2(), p2Ending, true);
|
drawLineEnding(info.transformedLine.p2(), p2Ending, true);
|
||||||
painter.drawLine(adjustedLine);
|
|
||||||
|
|
||||||
boundingPath.moveTo(adjustedLine.p1());
|
if (drawText && !textIsAboveLine)
|
||||||
boundingPath.lineTo(adjustedLine.p2());
|
{
|
||||||
|
// We will draw text in the line
|
||||||
|
QRectF textBoundingRect = textPath.controlPointRect();
|
||||||
|
QPointF center = textBoundingRect.center();
|
||||||
|
const qreal offsetY = center.y();
|
||||||
|
const qreal offsetX = center.x();
|
||||||
|
textPath.translate(textOffset + adjustedLine.center() - QPointF(offsetX, offsetY));
|
||||||
|
textBoundingRect = textPath.controlPointRect();
|
||||||
|
|
||||||
|
const qreal textPadding = 3.0;
|
||||||
|
const qreal textStart = textBoundingRect.left() - textPadding;
|
||||||
|
const qreal textEnd = textBoundingRect.right() + textPadding;
|
||||||
|
|
||||||
|
textPath = info.LCStoGCS.map(textPath);
|
||||||
|
painter.fillPath(textPath, QBrush(painter.pen().color(), Qt::SolidPattern));
|
||||||
|
boundingPath.addPath(textPath);
|
||||||
|
|
||||||
|
if (textStart > adjustedLine.p1().x())
|
||||||
|
{
|
||||||
|
QLineF leftLine(adjustedLine.p1(), QPointF(textStart, adjustedLine.p2().y()));
|
||||||
|
painter.drawLine(info.LCStoGCS.map(leftLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textEnd < adjustedLine.p2().x())
|
||||||
|
{
|
||||||
|
QLineF rightLine(QPointF(textEnd, adjustedLine.p2().y()), adjustedLine.p2());
|
||||||
|
painter.drawLine(info.LCStoGCS.map(rightLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include whole line to the bounding path
|
||||||
|
adjustedLine = info.LCStoGCS.map(adjustedLine);
|
||||||
|
boundingPath.moveTo(adjustedLine.p1());
|
||||||
|
boundingPath.lineTo(adjustedLine.p2());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (drawText)
|
||||||
|
{
|
||||||
|
// We will draw text above the line
|
||||||
|
QRectF textBoundingRect = textPath.controlPointRect();
|
||||||
|
const qreal offsetY = textBoundingRect.top() - textVerticalOffset;
|
||||||
|
const qreal offsetX = textBoundingRect.center().x();
|
||||||
|
textPath.translate(textOffset + adjustedLine.center() - QPointF(offsetX, offsetY));
|
||||||
|
|
||||||
|
textPath = info.LCStoGCS.map(textPath);
|
||||||
|
painter.fillPath(textPath, QBrush(painter.pen().color(), Qt::SolidPattern));
|
||||||
|
boundingPath.addPath(textPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustedLine = info.LCStoGCS.map(adjustedLine);
|
||||||
|
painter.drawLine(adjustedLine);
|
||||||
|
|
||||||
|
boundingPath.moveTo(adjustedLine.p1());
|
||||||
|
boundingPath.lineTo(adjustedLine.p2());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -526,12 +526,18 @@ protected:
|
|||||||
/// \param p1Ending Line endpoint graphics at p1
|
/// \param p1Ending Line endpoint graphics at p1
|
||||||
/// \param p2Ending Line endpoint graphics at p2
|
/// \param p2Ending Line endpoint graphics at p2
|
||||||
/// \param boundingPath Bounding path in global coordinate system
|
/// \param boundingPath Bounding path in global coordinate system
|
||||||
|
/// \param textOffset Additional text offset
|
||||||
|
/// \param text Text, which should be printed along the line
|
||||||
|
/// \param textIsAboveLine Text should be printed above line
|
||||||
void drawLine(const LineGeometryInfo& info,
|
void drawLine(const LineGeometryInfo& info,
|
||||||
QPainter& painter,
|
QPainter& painter,
|
||||||
PDFReal lineEndingSize,
|
PDFReal lineEndingSize,
|
||||||
AnnotationLineEnding p1Ending,
|
AnnotationLineEnding p1Ending,
|
||||||
AnnotationLineEnding p2Ending,
|
AnnotationLineEnding p2Ending,
|
||||||
QPainterPath& boundingPath) const;
|
QPainterPath& boundingPath,
|
||||||
|
QPointF textOffset,
|
||||||
|
const QString& text,
|
||||||
|
bool textIsAboveLine) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -822,6 +828,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual AnnotationType getType() const override { return m_type; }
|
virtual AnnotationType getType() const override { return m_type; }
|
||||||
|
virtual void draw(AnnotationDrawParameters& parameters) const override;
|
||||||
|
|
||||||
const std::vector<QPointF>& getVertices() const { return m_vertices; }
|
const std::vector<QPointF>& getVertices() const { return m_vertices; }
|
||||||
AnnotationLineEnding getStartLineEnding() const { return m_startLineEnding; }
|
AnnotationLineEnding getStartLineEnding() const { return m_startLineEnding; }
|
||||||
|
Reference in New Issue
Block a user