Use a dedicated graphics item for drawing the text instead a pixmap

This commit is contained in:
Martin Tůma 2018-10-29 18:30:55 +01:00
parent 5d5401e745
commit 5d68f31124
4 changed files with 71 additions and 22 deletions

View File

@ -18,7 +18,8 @@ HEADERS += src/pbfhandler.h \
src/text.h \ src/text.h \
src/tile.h \ src/tile.h \
src/function.h \ src/function.h \
src/textpathitem.h src/textpathitem.h \
src/textitem.h
SOURCES += src/pbfplugin.cpp \ SOURCES += src/pbfplugin.cpp \
src/pbfhandler.cpp \ src/pbfhandler.cpp \
src/gzip.cpp \ src/gzip.cpp \
@ -27,7 +28,8 @@ SOURCES += src/pbfplugin.cpp \
src/color.cpp \ src/color.cpp \
src/text.cpp \ src/text.cpp \
src/function.cpp \ src/function.cpp \
src/textpathitem.cpp src/textpathitem.cpp \
src/textitem.cpp
LIBS += -lprotobuf-lite LIBS += -lprotobuf-lite

View File

@ -2,6 +2,7 @@
#include <QFontMetrics> #include <QFontMetrics>
#include <QPainter> #include <QPainter>
#include "text.h" #include "text.h"
#include "textitem.h"
#include "textpathitem.h" #include "textpathitem.h"
@ -51,27 +52,16 @@ void Text::addLabel(const QString &text, const QPointF &pos, const QFont &font,
if (text.isEmpty()) if (text.isEmpty())
return; return;
QFontMetrics fm(font); TextItem *ti = new TextItem(text, pos, font, maxTextWidth);
int limit = fm.width('M') * maxTextWidth; addItem(ti);
int flags = Qt::AlignCenter | Qt::TextWordWrap | Qt::TextDontClip; if (!sceneRect().contains(ti->sceneBoundingRect())) {
delete ti;
QRect br = fm.boundingRect(QRect(0, 0, limit, 0), flags, text);
if (!br.isValid())
return; return;
br.moveTo((pos - QPointF(br.width() / 2.0, br.height() / 2.0)).toPoint()); }
if (!sceneRect().contains(br))
return;
QPixmap pm(br.size());
pm.fill(Qt::transparent);
QPainter p(&pm);
p.setFont(font);
p.setPen(pen);
p.drawText(pm.rect(), flags, text);
QGraphicsPixmapItem *pi = addPixmap(pm); ti->setPen(pen);
pi->setPos(br.topLeft());
QList<QGraphicsItem*> ci = collidingItems(pi); QList<QGraphicsItem*> ci = collidingItems(ti);
for (int i = 0; i < ci.size(); i++) for (int i = 0; i < ci.size(); i++)
ci[i]->setVisible(false); ci[i]->setVisible(false);
} }
@ -95,14 +85,14 @@ void Text::addLabel(const QString &text, const QPainterPath &path,
const QPainterPath &segment = list.at(i); const QPainterPath &segment = list.at(i);
TextPathItem *pi = new TextPathItem(text, reverse(segment) TextPathItem *pi = new TextPathItem(text, reverse(segment)
? segment.toReversed() : segment, font); ? segment.toReversed() : segment, font);
pi->setPen(pen);
addItem(pi); addItem(pi);
if (!sceneRect().contains(pi->sceneBoundingRect())) { if (!sceneRect().contains(pi->sceneBoundingRect())) {
delete pi; delete pi;
continue; continue;
} }
pi->setPen(pen);
QList<QGraphicsItem*> ci = collidingItems(pi); QList<QGraphicsItem*> ci = collidingItems(pi);
for (int j = 0; j < ci.size(); j++) for (int j = 0; j < ci.size(); j++)
ci[j]->setVisible(false); ci[j]->setVisible(false);

29
src/textitem.cpp Normal file
View File

@ -0,0 +1,29 @@
#include <QPainter>
#include "textitem.h"
#define FLAGS (Qt::AlignCenter | Qt::TextWordWrap | Qt::TextDontClip)
TextItem::TextItem(const QString &text, const QPointF &pos, const QFont &font,
int maxTextWidth, QGraphicsItem *parent) : QGraphicsItem(parent), _text(text),
_font(font)
{
QFontMetrics fm(font);
int limit = fm.width('M') * maxTextWidth;
QRect br = fm.boundingRect(QRect(0, 0, limit, 0), FLAGS, text);
Q_ASSERT(br.isValid());
setPos((pos - QPointF(br.width() / 2.0, br.height() / 2.0)).toPoint());
_boundingRect = QRectF(0, 0, br.width(), br.height());
}
void TextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setFont(_font);
painter->setPen(_pen);
painter->drawText(_boundingRect, FLAGS, _text);
}

28
src/textitem.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef TEXTITEM_H
#define TEXTITEM_H
#include <QGraphicsItem>
#include <QPen>
#include <QFont>
#include <QString>
class TextItem : public QGraphicsItem
{
public:
TextItem(const QString &text, const QPointF &pos, const QFont &font,
int maxTextWidth, QGraphicsItem *parent = 0);
QRectF boundingRect() const {return _boundingRect;}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setPen(const QPen &pen) {_pen = pen;}
private:
QString _text;
QRectF _boundingRect;
QFont _font;
QPen _pen;
};
#endif // TEXTITEM_H