3 Commits
1.3 ... 1.4

Author SHA1 Message Date
c28d10eafc Proper path-text halo drawing 2019-04-28 09:10:19 +02:00
76fb129651 Halo drawing performance improvement 2019-04-28 08:25:57 +02:00
3dfcf35e53 Added support for text halo 2019-04-27 22:52:18 +02:00
7 changed files with 89 additions and 6 deletions

View File

@ -230,6 +230,9 @@ Style::Layer::Paint::Paint(const QJsonObject &json)
// text
_textColor = FunctionC(json["text-color"]);
_textHaloColor = FunctionC(json["text-halo-color"], QColor());
_textHaloWidth = FunctionF(json["text-halo-width"]);
_textHaloBlur = FunctionF(json["text-halo-blur"]);
}
QPen Style::Layer::Paint::pen(Type type, int zoom) const
@ -511,6 +514,7 @@ void Style::Layer::setTextProperties(Tile &tile) const
t.setFont(_layout.font(zoom));
t.setSymbolPlacement(_layout.symbolPlacement(zoom));
t.setRotationAlignment(_layout.textRotationAlignment(zoom));
t.setHalo(_paint.halo(zoom));
}
void Style::Layer::addSymbol(Tile &tile, const QPainterPath &path,

View File

@ -137,9 +137,13 @@ private:
const;
qreal opacity(Layer::Type type, int zoom) const;
bool antialias(Layer::Type type, int zoom) const;
Text::Halo halo(int zoom) const
{return Text::Halo(_textHaloColor.value(zoom),
_textHaloWidth.value(zoom), _textHaloBlur.value(zoom));}
private:
FunctionC _textColor;
FunctionC _textHaloColor;
FunctionC _lineColor;
FunctionC _fillColor;
FunctionC _fillOutlineColor;
@ -147,6 +151,8 @@ private:
FunctionF _fillOpacity;
FunctionF _lineOpacity;
FunctionF _lineWidth;
FunctionF _textHaloWidth;
FunctionF _textHaloBlur;
FunctionB _fillAntialias;
QVector<qreal> _lineDasharray;
FunctionS _fillPattern;

View File

@ -56,6 +56,7 @@ void Text::addLabel(const QString &text, const QImage &icon,
}
ti->setPen(_pen);
ti->setHalo(_halo);
addItem(ti);
QList<TextItem*> ci = collidingItems(ti);

View File

@ -34,6 +34,22 @@ public:
Auto
};
class Halo {
public:
Halo() : _width(0), _blur(0) {}
Halo(const QColor &color, qreal width, qreal blur)
: _color(color), _width(width), _blur(blur) {}
const QColor &color() const {return _color;}
qreal width() const {return _width;}
qreal blur() const {return _blur;}
private:
QColor _color;
qreal _width;
qreal _blur;
};
Text(const QSize &size) : _sceneRect(QRectF(QPointF(0, 0), size)) {}
~Text();
@ -45,6 +61,7 @@ public:
void setSymbolPlacement(SymbolPlacement placement);
void setRotationAlignment(RotationAlignment alignment)
{_alignment = alignment;}
void setHalo(const Halo &halo) {_halo = halo;}
void addLabel(const QString &text, const QImage &icon,
const QPainterPath &path);
@ -65,6 +82,7 @@ private:
RotationAlignment _alignment;
QFont _font;
QPen _pen;
Halo _halo;
};
#endif // TEXT_H

View File

@ -6,6 +6,7 @@
#include <QPen>
#include <QFont>
#include <QRectF>
#include "text.h"
class QPainter;
@ -19,7 +20,9 @@ public:
const QString &text() const {return _text;}
const QFont &font() const {return _font;}
const QPen &pen() const {return _pen;}
const Text::Halo &halo() const {return _halo;}
void setPen(const QPen &pen) {_pen = pen;}
void setHalo(const Text::Halo &halo) {_halo = halo;}
virtual QPainterPath shape() const = 0;
virtual QRectF boundingRect() const = 0;
@ -37,6 +40,7 @@ private:
QString _text;
QFont _font;
QPen _pen;
Text::Halo _halo;
bool _visible;
};

View File

@ -166,10 +166,35 @@ void TextPathItem::paint(QPainter *painter) const
qreal percent = (1.0 - factor) / 2.0;
painter->setFont(font());
painter->setPen(pen());
QTransform t = painter->transform();
if (halo().color().isValid() && halo().width() > 0) {
painter->setPen(halo().color());
for (int i = 0; i < text().size(); i++) {
QPointF point = _path.pointAtPercent(percent);
qreal angle = _path.angleAtPercent(percent);
painter->translate(point);
painter->rotate(-angle);
painter->drawText(QPoint(-1, fm.descent() - 1), text().at(i));
painter->drawText(QPoint(1, fm.descent() + 1), text().at(i));
painter->drawText(QPoint(-1, fm.descent() + 1), text().at(i));
painter->drawText(QPoint(1, fm.descent() -1), text().at(i));
painter->drawText(QPoint(0, fm.descent() - 1), text().at(i));
painter->drawText(QPoint(0, fm.descent() + 1), text().at(i));
painter->drawText(QPoint(-1, fm.descent()), text().at(i));
painter->drawText(QPoint(1, fm.descent()), text().at(i));
painter->setTransform(t);
int width = fm.charWidth(text(), i);
percent += ((qreal)width / (qreal)textWidth) * factor;
}
percent = (1.0 - factor) / 2.0;
}
painter->setPen(pen());
for (int i = 0; i < text().size(); i++) {
QPointF point = _path.pointAtPercent(percent);
qreal angle = _path.angleAtPercent(percent);

View File

@ -128,9 +128,10 @@ void TextPointItem::paint(QPainter *painter) const
//painter->drawRect(_boundingRect);
QRectF textRect;
bool hasHalo = halo().color().isValid() && halo().width() > 0;
if (!_icon.isNull()) {
textRect = (_anchor != Text::Center)
textRect = (_anchor != Text::Center || hasHalo)
? computeTextRect(true) : _boundingRect;
#ifdef ENABLE_HIDPI
painter->drawImage(_pos - QPointF(_icon.width()
@ -141,9 +142,33 @@ void TextPointItem::paint(QPainter *painter) const
_icon.height() / 2), _icon);
#endif // ENABLE_HIDPI
} else
textRect = _boundingRect;
textRect = hasHalo ? computeTextRect(true) : _boundingRect;
painter->setFont(font());
painter->setPen(pen());
painter->drawText(textRect, FLAGS, text());
if (hasHalo) {
QRect ir(textRect.toRect());
QImage img(ir.size(), QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::transparent);
QPainter ip(&img);
ip.setPen(halo().color());
ip.setFont(font());
ip.drawText(img.rect(), FLAGS, text());
painter->drawImage(ir.x() - 1, ir.y() - 1, img);
painter->drawImage(ir.x() + 1, ir.y() + 1, img);
painter->drawImage(ir.x() - 1, ir.y() + 1, img);
painter->drawImage(ir.x() + 1, ir.y() - 1, img);
painter->drawImage(ir.x(), ir.y() - 1, img);
painter->drawImage(ir.x(), ir.y() + 1, img);
painter->drawImage(ir.x() - 1, ir.y(), img);
painter->drawImage(ir.x() + 1, ir.y(), img);
painter->setFont(font());
painter->setPen(pen());
painter->drawText(ir, FLAGS, text());
} else {
painter->setFont(font());
painter->setPen(pen());
painter->drawText(textRect, FLAGS, text());
}
}