diff --git a/profile-widget/divetextitem.cpp b/profile-widget/divetextitem.cpp index b8f03d794..6e6f97e95 100644 --- a/profile-widget/divetextitem.cpp +++ b/profile-widget/divetextitem.cpp @@ -5,33 +5,60 @@ #include "core/errorhelper.h" #include -#include #include -DiveTextItem::DiveTextItem(double dpr, double scale, int alignFlags, QGraphicsItem *parent) : QGraphicsItemGroup(parent), +static const double outlineSize = 3.0; + +DiveTextItem::DiveTextItem(double dpr, double scale, int alignFlags, QGraphicsItem *parent) : QGraphicsPixmapItem(parent), internalAlignFlags(alignFlags), - textBackgroundItem(new QGraphicsPathItem(this)), - textItem(new QGraphicsPathItem(this)), dpr(dpr), scale(scale) { setFlag(ItemIgnoresTransformations); - textBackgroundItem->setBrush(QBrush(getColor(TEXT_BACKGROUND))); - textBackgroundItem->setPen(Qt::NoPen); - textItem->setPen(Qt::NoPen); -} - -void DiveTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - updateText(); - QGraphicsItemGroup::paint(painter, option, widget); } void DiveTextItem::set(const QString &t, const QBrush &b) { - textItem->setBrush(b); internalText = t; - updateText(); + if (internalText.isEmpty()) { + setPixmap(QPixmap()); + return; + } + + QFont fnt = getFont(dpr, scale); + + QPainterPath textPath; + textPath.addText(0.0, 0.0, fnt, internalText); + QPainterPathStroker stroker; + stroker.setWidth(outlineSize * dpr); + QPainterPath outlinePath = stroker.createStroke(textPath); + + QRectF outlineRect = outlinePath.boundingRect(); + textPath.translate(-outlineRect.topLeft()); + outlinePath.translate(-outlineRect.topLeft()); + + QPixmap pixmap(outlineRect.size().toSize()); + pixmap.fill(Qt::transparent); + { + QPainter painter(&pixmap); + painter.setRenderHints(QPainter::Antialiasing); + painter.setBrush(QBrush(getColor(TEXT_BACKGROUND))); + painter.setPen(Qt::NoPen); + painter.drawPath(outlinePath); + painter.setBrush(b); + painter.setPen(Qt::NoPen); + painter.drawPath(textPath); + } + setPixmap(pixmap); + + double yOffset = (internalAlignFlags & Qt::AlignTop) ? 0.0 : + (internalAlignFlags & Qt::AlignBottom) ? -outlineRect.height() : + /*(internalAlignFlags & Qt::AlignVCenter ? */ -outlineRect.height() / 2.0; + + double xOffset = (internalAlignFlags & Qt::AlignLeft) ? -outlineRect.width() : + (internalAlignFlags & Qt::AlignHCenter) ? -outlineRect.width() / 2.0 : + /* (internalAlignFlags & Qt::AlignRight) */ 0.0; + setOffset(xOffset, yOffset); } const QString &DiveTextItem::text() @@ -64,32 +91,5 @@ double DiveTextItem::fontHeight(double dpr, double scale) double DiveTextItem::height() const { - return fontHeight(dpr, scale); -} - -void DiveTextItem::updateText() -{ - if (internalText.isEmpty()) - return; - - QFont fnt = getFont(dpr, scale); - QFontMetrics fm(fnt); - - QPainterPath textPath; - qreal xPos = 0, yPos = 0; - - QRectF rect = fm.boundingRect(internalText); - yPos = (internalAlignFlags & Qt::AlignTop) ? 0 : - (internalAlignFlags & Qt::AlignBottom) ? +rect.height() : - /*(internalAlignFlags & Qt::AlignVCenter ? */ +rect.height() / 4; - - xPos = (internalAlignFlags & Qt::AlignLeft) ? -rect.width() : - (internalAlignFlags & Qt::AlignHCenter) ? -rect.width() / 2 : - /* (internalAlignFlags & Qt::AlignRight) */ 0; - - textPath.addText(xPos, yPos, fnt, internalText); - QPainterPathStroker stroker; - stroker.setWidth(3); - textBackgroundItem->setPath(stroker.createStroke(textPath)); - textItem->setPath(textPath); + return fontHeight(dpr, scale) + outlineSize * dpr; } diff --git a/profile-widget/divetextitem.h b/profile-widget/divetextitem.h index 28bafe257..cb7d054b1 100644 --- a/profile-widget/divetextitem.h +++ b/profile-widget/divetextitem.h @@ -4,29 +4,28 @@ #include #include -#include +#include class QBrush; /* A Line Item that has animated-properties. */ -class DiveTextItem : public QObject, public QGraphicsItemGroup { +class DiveTextItem : public QObject, public QGraphicsPixmapItem { Q_OBJECT Q_PROPERTY(QPointF pos READ pos WRITE setPos) Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) public: + // Note: vertical centring is based on the actual rendered text, not on the font metrics. + // This is fine for placing text in the "tankbar", but it will look disastrous when + // placing text items next to each other. This may have to be fixed. DiveTextItem(double dpr, double scale, int alignFlags, QGraphicsItem *parent); void set(const QString &text, const QBrush &brush); const QString &text(); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); static QFont getFont(double dpr, double scale); static double fontHeight(double dpr, double scale); double height() const; private: - void updateText(); int internalAlignFlags; - QGraphicsPathItem *textBackgroundItem; - QGraphicsPathItem *textItem; QString internalText; double dpr; double scale;