mirror of
https://github.com/tumic0/QtPBFImagePlugin.git
synced 2025-04-10 08:19:10 +02:00
111 lines
2.6 KiB
C++
111 lines
2.6 KiB
C++
#include <QGraphicsPixmapItem>
|
|
#include <QFontMetrics>
|
|
#include <QPainter>
|
|
#include "text.h"
|
|
#include "textitem.h"
|
|
#include "textpathitem.h"
|
|
|
|
|
|
static QPainterPath subpath(const QPainterPath &path, int start, int end)
|
|
{
|
|
QPainterPath p(path.elementAt(start));
|
|
for (int i = start + 1; i <= end; i++)
|
|
p.lineTo(path.elementAt(i));
|
|
return p;
|
|
}
|
|
|
|
static QList<QPainterPath> segments(const QPainterPath &path, qreal pathLimit,
|
|
qreal maxAngle, qreal charWidth, const QRectF &tileRect)
|
|
{
|
|
QList<QPainterPath> list;
|
|
int start = 0;
|
|
qreal length = 0;
|
|
qreal angle = -1;
|
|
|
|
for (int i = 1; i < path.elementCount(); i++) {
|
|
QLineF l(path.elementAt(i-1), path.elementAt(i));
|
|
qreal a = l.angle();
|
|
qreal sl = l.length();
|
|
if (angle < 0)
|
|
angle = a;
|
|
if (!tileRect.contains(path.elementAt(i))
|
|
|| sl < charWidth || qAbs(angle - a) > maxAngle
|
|
|| length > pathLimit) {
|
|
if (length > pathLimit)
|
|
list.append(subpath(path, start, i - 1));
|
|
start = i;
|
|
length = 0;
|
|
} else
|
|
length += sl;
|
|
angle = a;
|
|
}
|
|
|
|
if (length > pathLimit)
|
|
list.append(subpath(path, start, path.elementCount() - 1));
|
|
|
|
return list;
|
|
}
|
|
|
|
static bool reverse(const QPainterPath &path)
|
|
{
|
|
QLineF l(path.elementAt(0), path.elementAt(1));
|
|
qreal angle = l.angle();
|
|
return (angle > 90 && angle < 270) ? true : false;
|
|
}
|
|
|
|
void Text::addLabel(const QString &text, const QPointF &pos, const QFont &font,
|
|
const QPen &pen, qreal maxTextWidth)
|
|
{
|
|
if (text.isEmpty())
|
|
return;
|
|
if (!sceneRect().contains(pos))
|
|
return;
|
|
|
|
TextItem *ti = new TextItem(text, pos, font, maxTextWidth);
|
|
addItem(ti);
|
|
if (!sceneRect().contains(ti->sceneBoundingRect())) {
|
|
delete ti;
|
|
return;
|
|
}
|
|
|
|
ti->setPen(pen);
|
|
|
|
QList<QGraphicsItem*> ci = collidingItems(ti);
|
|
for (int i = 0; i < ci.size(); i++)
|
|
ci[i]->setVisible(false);
|
|
}
|
|
|
|
void Text::addLabel(const QString &text, const QPainterPath &path,
|
|
const QFont &font, const QPen &pen, qreal maxAngle)
|
|
{
|
|
if (path.elementCount() < 2 || !path.elementAt(0).isMoveTo())
|
|
return;
|
|
if (text.isEmpty())
|
|
return;
|
|
|
|
QFontMetrics fm(font);
|
|
int textWidth = fm.width(text);
|
|
|
|
if (textWidth > path.length())
|
|
return;
|
|
|
|
QList<QPainterPath> list(segments(path, textWidth, maxAngle,
|
|
fm.averageCharWidth(), sceneRect()));
|
|
for (int i = 0; i < list.size(); i++) {
|
|
const QPainterPath &segment = list.at(i);
|
|
TextPathItem *pi = new TextPathItem(text, reverse(segment)
|
|
? segment.toReversed() : segment, font);
|
|
addItem(pi);
|
|
if (!sceneRect().contains(pi->sceneBoundingRect())) {
|
|
delete pi;
|
|
continue;
|
|
}
|
|
|
|
pi->setPen(pen);
|
|
|
|
QList<QGraphicsItem*> ci = collidingItems(pi);
|
|
for (int j = 0; j < ci.size(); j++)
|
|
ci[j]->setVisible(false);
|
|
}
|
|
}
|