From 044e95e061c586ebf96fda66c1121c839fdae869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 2 Oct 2019 22:57:11 +0200 Subject: [PATCH] Some more text layout fiddeling --- src/text.cpp | 42 ++++++++++++++++++++++++++++-------------- src/textpointitem.cpp | 18 ++++++++++++++---- src/textpointitem.h | 4 ++++ 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/text.cpp b/src/text.cpp index fe5f92b..03a7738 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -31,22 +31,36 @@ void Text::addLabel(const QString &text, const QImage &icon, { TextItem *ti; - switch (_placement) { - case Line: - if (_alignment == Viewport) + if (_alignment == Viewport) { + QMap map; + for (int j = 0; j < path.elementCount(); j++) { + QLineF l(path.elementAt(j), _sceneRect.center()); + map.insert(l.length(), j); + } + QMap::const_iterator jt = map.constBegin(); + ti = new TextPointItem(text, path.elementAt(jt.value()), _font, + _maxWidth, _anchor, icon); + while (true) { + if (_sceneRect.contains(ti->boundingRect())) + break; + if (++jt == map.constEnd()) + break; + static_cast(ti)->setPos(path.elementAt( + jt.value())); + } + } else { + switch (_placement) { + case Line: + ti = new TextPathItem(text, path, _font, _maxAngle, _sceneRect); + break; + case LineCenter: + ti = new TextPointItem(text, path.pointAtPercent(0.5), _font, + _maxWidth, _anchor, icon); + break; + default: ti = new TextPointItem(text, path.elementAt(0), _font, _maxWidth, _anchor, icon); - else - ti = new TextPathItem(text, path, _font, _maxAngle, _sceneRect); - break; - case LineCenter: - ti = new TextPointItem(text, path.pointAtPercent(0.5), _font, - _maxWidth, _anchor, icon); - break; - default: - ti = new TextPointItem(text, path.elementAt(0), _font, _maxWidth, - _anchor, icon); - break; + } } // Note: empty path == point geometry (single move) diff --git a/src/textpointitem.cpp b/src/textpointitem.cpp index ef95aae..c219d47 100644 --- a/src/textpointitem.cpp +++ b/src/textpointitem.cpp @@ -16,6 +16,8 @@ QRectF TextPointItem::exactBoundingRect() const // Italic fonts overflow the computed bounding rect, so expand it if (font().italic()) br.adjust(-font().pixelSize() / 2.0, 0, font().pixelSize() / 2.0, 0); + if (hasHalo()) + br.adjust(-1, -1, 1, 1); return br; } @@ -119,9 +121,18 @@ TextPointItem::TextPointItem(const QString &text, const QPointF &pos, _shape.addRect(_boundingRect); } +void TextPointItem::setPos(const QPointF &pos) +{ + QPointF d(_boundingRect.left() - _pos.x(), _boundingRect.top() - _pos.y()); + _boundingRect.moveTopLeft(pos + d); + _shape = QPainterPath(); + _shape.addRect(_boundingRect); + _pos = pos; +} + void TextPointItem::paint(QPainter *painter) const { - QRectF textRect; + QRectF textRect(_boundingRect); if (!_icon.isNull()) { textRect = computeTextRect(true); @@ -133,10 +144,9 @@ void TextPointItem::paint(QPainter *painter) const painter->drawImage(_pos - QPointF(_icon.width() / 2, _icon.height() / 2), _icon); #endif // ENABLE_HIDPI - } else - textRect = _boundingRect; + } - if (halo().color().isValid() && halo().width() > 0) { + if (hasHalo()) { QRect ir(textRect.toRect()); QImage img(ir.size(), QImage::Format_ARGB32_Premultiplied); img.fill(Qt::transparent); diff --git a/src/textpointitem.h b/src/textpointitem.h index 2333c0f..b927e4d 100644 --- a/src/textpointitem.h +++ b/src/textpointitem.h @@ -15,10 +15,14 @@ public: QPainterPath shape() const {return _shape;} void paint(QPainter *painter) const; + void setPos(const QPointF &pos); + private: QRectF exactBoundingRect() const; QRectF fuzzyBoundingRect() const; QRectF computeTextRect(bool exact) const; + bool hasHalo() const + {return halo().color().isValid() && halo().width() > 0;} QPointF _pos; QPainterPath _shape;