mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 05:34:47 +01:00
Improved mapsforge hi-dpi rendering
This commit is contained in:
parent
b6add991d2
commit
663859ef1c
@ -13,6 +13,8 @@ using namespace IMG;
|
|||||||
#define AREA(rect) \
|
#define AREA(rect) \
|
||||||
(rect.size().width() * rect.size().height())
|
(rect.size().width() * rect.size().height())
|
||||||
|
|
||||||
|
static const QColor textColor(Qt::black);
|
||||||
|
static const QColor haloColor(Qt::white);
|
||||||
static const QColor shieldColor(Qt::white);
|
static const QColor shieldColor(Qt::white);
|
||||||
static const QColor shieldBgColor1("#dd3e3e");
|
static const QColor shieldBgColor1("#dd3e3e");
|
||||||
static const QColor shieldBgColor2("#379947");
|
static const QColor shieldBgColor2("#379947");
|
||||||
@ -316,8 +318,8 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
|| Style::isNatureReserve(poly.type))) {
|
|| Style::isNatureReserve(poly.type))) {
|
||||||
const Style::Polygon &style = _style->polygon(poly.type);
|
const Style::Polygon &style = _style->polygon(poly.type);
|
||||||
TextPointItem *item = new TextPointItem(
|
TextPointItem *item = new TextPointItem(
|
||||||
centroid(poly.points).toPoint(), &poly.label.text(),
|
centroid(poly.points).toPoint(), &poly.label.text(), poiFont(),
|
||||||
poiFont(), 0, &style.brush().color());
|
0, &style.brush().color(), &haloColor);
|
||||||
if (item->isValid() && !item->collides(textItems)
|
if (item->isValid() && !item->collides(textItems)
|
||||||
&& !item->collides(labels)
|
&& !item->collides(labels)
|
||||||
&& !(exists && tileRect.contains(item->boundingRect()))
|
&& !(exists && tileRect.contains(item->boundingRect()))
|
||||||
@ -417,7 +419,7 @@ void RasterTile::processShields(const QRect &tileRect,
|
|||||||
|
|
||||||
TextPointItem *item = new TextPointItem(
|
TextPointItem *item = new TextPointItem(
|
||||||
p.at(jt.value()).toPoint(), &(sp.value(it.key())->text()),
|
p.at(jt.value()).toPoint(), &(sp.value(it.key())->text()),
|
||||||
poiFont(), 0, &shieldColor, shieldBgColor(it.key().type()));
|
poiFont(), 0, &shieldColor, 0, shieldBgColor(it.key().type()));
|
||||||
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -457,7 +459,7 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
|||||||
const QFont *fnt = poi
|
const QFont *fnt = poi
|
||||||
? poiFont(style.textFontSize()) : font(style.textFontSize());
|
? poiFont(style.textFontSize()) : font(style.textFontSize());
|
||||||
const QColor *color = style.textColor().isValid()
|
const QColor *color = style.textColor().isValid()
|
||||||
? &style.textColor() : 0;
|
? &style.textColor() : &textColor;
|
||||||
|
|
||||||
if ((!label || !fnt) && !img)
|
if ((!label || !fnt) && !img)
|
||||||
continue;
|
continue;
|
||||||
@ -471,7 +473,7 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextPointItem *item = new TextPointItem(QPoint(point.coordinates.lon(),
|
TextPointItem *item = new TextPointItem(QPoint(point.coordinates.lon(),
|
||||||
point.coordinates.lat()), label, fnt, img, color);
|
point.coordinates.lat()), label, fnt, img, color, &haloColor);
|
||||||
if (item->isValid() && !item->collides(textItems))
|
if (item->isValid() && !item->collides(textItems))
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
else
|
else
|
||||||
|
@ -79,6 +79,13 @@ static QString *pathLabel(const Style::TextRender *ri, MapData::Path &path,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const QColor *haloColor(const Style::TextRender *ti)
|
||||||
|
{
|
||||||
|
return (ti->strokeColor() != ti->fillColor() && ti->strokeWidth() > 0)
|
||||||
|
? &ti->strokeColor() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
@ -115,9 +122,11 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
|||||||
const QImage *img = si ? &si->img() : 0;
|
const QImage *img = si ? &si->img() : 0;
|
||||||
const QFont *font = ti ? &ti->font() : 0;
|
const QFont *font = ti ? &ti->font() : 0;
|
||||||
const QColor *color = ti ? &ti->fillColor() : 0;
|
const QColor *color = ti ? &ti->fillColor() : 0;
|
||||||
|
const QColor *hColor = ti ? haloColor(ti) : 0;
|
||||||
|
|
||||||
TextPointItem *item = new TextPointItem(
|
TextPointItem *item = new TextPointItem(
|
||||||
ll2xy(point.coordinates).toPoint(), label, font, img, color, 0, false);
|
ll2xy(point.coordinates).toPoint(), label, font, img, color,
|
||||||
|
hColor, 0, false);
|
||||||
if (item->isValid() && !item->collides(textItems))
|
if (item->isValid() && !item->collides(textItems))
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
else
|
else
|
||||||
@ -125,8 +134,7 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processAreaLabels(const QRect &tileRect,
|
void RasterTile::processAreaLabels(QList<TextItem*> &textItems)
|
||||||
QList<TextItem*> &textItems)
|
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
QList<const Style::TextRender*> labels(s.areaLabels(_zoom));
|
QList<const Style::TextRender*> labels(s.areaLabels(_zoom));
|
||||||
@ -165,12 +173,13 @@ void RasterTile::processAreaLabels(const QRect &tileRect,
|
|||||||
const QImage *img = si ? &si->img() : 0;
|
const QImage *img = si ? &si->img() : 0;
|
||||||
const QFont *font = ti ? &ti->font() : 0;
|
const QFont *font = ti ? &ti->font() : 0;
|
||||||
const QColor *color = ti ? &ti->fillColor() : 0;
|
const QColor *color = ti ? &ti->fillColor() : 0;
|
||||||
|
const QColor *hColor = ti ? haloColor(ti) : 0;
|
||||||
QPointF pos = path.labelPos.isNull()
|
QPointF pos = path.labelPos.isNull()
|
||||||
? centroid(path.path) : ll2xy(path.labelPos);
|
? centroid(path.path) : ll2xy(path.labelPos);
|
||||||
|
|
||||||
TextPointItem *item = new TextPointItem(pos.toPoint(), label, font, img,
|
TextPointItem *item = new TextPointItem(pos.toPoint(), label, font, img,
|
||||||
color, 0, false);
|
color, hColor, 0, false);
|
||||||
if (item->isValid() && tileRect.contains(item->boundingRect().toRect())
|
if (item->isValid() && _rect.contains(item->boundingRect().toRect())
|
||||||
&& !item->collides(textItems))
|
&& !item->collides(textItems))
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
else
|
else
|
||||||
@ -178,8 +187,7 @@ void RasterTile::processAreaLabels(const QRect &tileRect,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processLineLabels(const QRect &tileRect,
|
void RasterTile::processLineLabels(QList<TextItem*> &textItems)
|
||||||
QList<TextItem*> &textItems)
|
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
QList<const Style::TextRender*> instructions(s.pathLabels(_zoom));
|
QList<const Style::TextRender*> instructions(s.pathLabels(_zoom));
|
||||||
@ -202,8 +210,8 @@ void RasterTile::processLineLabels(const QRect &tileRect,
|
|||||||
if (limit && set.contains(path.label))
|
if (limit && set.contains(path.label))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TextPathItem *item = new TextPathItem(path.path, label, tileRect,
|
TextPathItem *item = new TextPathItem(path.path, label, _rect,
|
||||||
&ri->font(), &ri->fillColor(), &ri->strokeColor());
|
&ri->font(), &ri->fillColor(), haloColor(ri));
|
||||||
if (item->isValid() && !item->collides(textItems)) {
|
if (item->isValid() && !item->collides(textItems)) {
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
if (limit)
|
if (limit)
|
||||||
@ -271,11 +279,12 @@ void RasterTile::drawPaths(QPainter *painter)
|
|||||||
const Style::PathRender *lri = 0;
|
const Style::PathRender *lri = 0;
|
||||||
|
|
||||||
QPixmap layer(_pixmap.size());
|
QPixmap layer(_pixmap.size());
|
||||||
|
layer.setDevicePixelRatio(_ratio);
|
||||||
layer.fill(Qt::transparent);
|
layer.fill(Qt::transparent);
|
||||||
|
|
||||||
QPainter lp(&layer);
|
QPainter lp(&layer);
|
||||||
lp.setRenderHint(QPainter::Antialiasing);
|
lp.setRenderHint(QPainter::Antialiasing);
|
||||||
lp.translate(-_xy.x(), -_xy.y());
|
lp.translate(-_rect.x(), -_rect.y());
|
||||||
lp.setCompositionMode(QPainter::CompositionMode_Source);
|
lp.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
|
||||||
for (int i = 0; i < instructions.size(); i++) {
|
for (int i = 0; i < instructions.size(); i++) {
|
||||||
@ -283,8 +292,8 @@ void RasterTile::drawPaths(QPainter *painter)
|
|||||||
const Style::PathRender *ri = is.render();
|
const Style::PathRender *ri = is.render();
|
||||||
|
|
||||||
if (lri && lri != ri) {
|
if (lri && lri != ri) {
|
||||||
painter->drawPixmap(_xy, layer);
|
painter->drawPixmap(_rect.topLeft(), layer);
|
||||||
lp.fillRect(QRect(_xy, _pixmap.size()), Qt::transparent);
|
lp.fillRect(QRect(_rect.topLeft(), _pixmap.size()), Qt::transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is.path()->path.elementCount())
|
if (!is.path()->path.elementCount())
|
||||||
@ -304,7 +313,7 @@ void RasterTile::drawPaths(QPainter *painter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lri)
|
if (lri)
|
||||||
painter->drawPixmap(_xy, layer);
|
painter->drawPixmap(_rect.topLeft(), layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::render()
|
void RasterTile::render()
|
||||||
@ -312,24 +321,24 @@ void RasterTile::render()
|
|||||||
std::sort(_points.begin(), _points.end());
|
std::sort(_points.begin(), _points.end());
|
||||||
|
|
||||||
QList<TextItem*> textItems;
|
QList<TextItem*> textItems;
|
||||||
QRect tileRect(_xy, _pixmap.size());
|
|
||||||
|
|
||||||
_pixmap.fill(Qt::transparent);
|
_pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
QPainter painter(&_pixmap);
|
QPainter painter(&_pixmap);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
painter.translate(-_xy.x(), -_xy.y());
|
painter.scale(_ratio, _ratio);
|
||||||
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
drawPaths(&painter);
|
drawPaths(&painter);
|
||||||
|
|
||||||
processPointLabels(textItems);
|
processPointLabels(textItems);
|
||||||
processAreaLabels(tileRect, textItems);
|
processAreaLabels(textItems);
|
||||||
processLineLabels(tileRect, textItems);
|
processLineLabels(textItems);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
//painter.setPen(Qt::red);
|
//painter.setPen(Qt::red);
|
||||||
//painter.setBrush(Qt::NoBrush);
|
//painter.setBrush(Qt::NoBrush);
|
||||||
//painter.drawRect(QRect(_xy, _pixmap.size()));
|
//painter.drawRect(QRect(_rect.topLeft(), _pixmap.size()));
|
||||||
|
|
||||||
qDeleteAll(textItems);
|
qDeleteAll(textItems);
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,14 @@ class RasterTile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform, int zoom,
|
RasterTile(const Projection &proj, const Transform &transform, int zoom,
|
||||||
const QRect &rect, const QString &key, const QList<MapData::Path> &paths,
|
const QRect &rect, qreal ratio, const QString &key,
|
||||||
const QList<MapData::Point> &points)
|
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
|
||||||
: _proj(proj), _transform(transform), _zoom(zoom), _xy(rect.topLeft()),
|
: _proj(proj), _transform(transform), _zoom(zoom), _rect(rect),
|
||||||
_key(key), _pixmap(rect.size()), _paths(paths), _points(points) {}
|
_ratio(ratio), _key(key), _pixmap(rect.width() * ratio,
|
||||||
|
rect.height() * ratio), _paths(paths), _points(points) {}
|
||||||
|
|
||||||
const QString &key() const {return _key;}
|
const QString &key() const {return _key;}
|
||||||
const QPoint &xy() const {return _xy;}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
const QPixmap &pixmap() const {return _pixmap;}
|
const QPixmap &pixmap() const {return _pixmap;}
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
@ -72,8 +73,8 @@ private:
|
|||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
void processPointLabels(QList<TextItem*> &textItems);
|
void processPointLabels(QList<TextItem*> &textItems);
|
||||||
void processAreaLabels(const QRect &tileRect, QList<TextItem*> &textItems);
|
void processAreaLabels(QList<TextItem*> &textItems);
|
||||||
void processLineLabels(const QRect &tileRect, QList<TextItem*> &textItems);
|
void processLineLabels(QList<TextItem*> &textItems);
|
||||||
QPainterPath painterPath(const Polygon &polygon) const;
|
QPainterPath painterPath(const Polygon &polygon) const;
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
void drawPaths(QPainter *painter);
|
void drawPaths(QPainter *painter);
|
||||||
@ -81,7 +82,8 @@ private:
|
|||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QPoint _xy;
|
QRect _rect;
|
||||||
|
qreal _ratio;
|
||||||
QString _key;
|
QString _key;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Path> _paths;
|
QList<MapData::Path> _paths;
|
||||||
|
@ -159,6 +159,8 @@ void Style::text(QXmlStreamReader &reader, const Rule &rule,
|
|||||||
ri._fillColor = QColor(attr.value("fill").toString());
|
ri._fillColor = QColor(attr.value("fill").toString());
|
||||||
if (attr.hasAttribute("stroke"))
|
if (attr.hasAttribute("stroke"))
|
||||||
ri._strokeColor = QColor(attr.value("stroke").toString());
|
ri._strokeColor = QColor(attr.value("stroke").toString());
|
||||||
|
if (attr.hasAttribute("stroke-width"))
|
||||||
|
ri._strokeWidth = attr.value("stroke-width").toFloat();
|
||||||
if (attr.hasAttribute("font-size"))
|
if (attr.hasAttribute("font-size"))
|
||||||
fontSize = attr.value("font-size").toInt();
|
fontSize = attr.value("font-size").toInt();
|
||||||
if (attr.hasAttribute("font-style")) {
|
if (attr.hasAttribute("font-style")) {
|
||||||
|
@ -187,17 +187,20 @@ public:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextRender(const Rule &rule)
|
TextRender(const Rule &rule)
|
||||||
: Render(rule), _fillColor(Qt::black), _strokeColor(Qt::white) {}
|
: Render(rule), _fillColor(Qt::black), _strokeColor(Qt::black),
|
||||||
|
_strokeWidth(0) {}
|
||||||
|
|
||||||
const QFont &font() const {return _font;}
|
const QFont &font() const {return _font;}
|
||||||
const QColor &fillColor() const {return _fillColor;}
|
const QColor &fillColor() const {return _fillColor;}
|
||||||
const QColor &strokeColor() const {return _strokeColor;}
|
const QColor &strokeColor() const {return _strokeColor;}
|
||||||
|
qreal strokeWidth() const {return _strokeWidth;}
|
||||||
const QByteArray &key() const {return _key;}
|
const QByteArray &key() const {return _key;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Style;
|
friend class Style;
|
||||||
|
|
||||||
QColor _fillColor, _strokeColor;
|
QColor _fillColor, _strokeColor;
|
||||||
|
qreal _strokeWidth;
|
||||||
QFont _font;
|
QFont _font;
|
||||||
QByteArray _key;
|
QByteArray _key;
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,8 @@ static int log2i(unsigned val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
||||||
: Map(fileName, parent), _data(fileName), _zoom(0), _projection(PCS::pcs(3857))
|
: Map(fileName, parent), _data(fileName), _zoom(0),
|
||||||
|
_projection(PCS::pcs(3857)), _tileRatio(1.0)
|
||||||
{
|
{
|
||||||
_zoom = _data.zooms().min();
|
_zoom = _data.zooms().min();
|
||||||
updateTransform();
|
updateTransform();
|
||||||
@ -147,9 +148,10 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
if (isRunning(key))
|
if (isRunning(key))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (QPixmapCache::find(key, &pm))
|
if (QPixmapCache::find(key, &pm)) {
|
||||||
|
pm.setDevicePixelRatio(_tileRatio);
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
} else {
|
||||||
QList<MapData::Path> paths;
|
QList<MapData::Path> paths;
|
||||||
QList<MapData::Point> points;
|
QList<MapData::Point> points;
|
||||||
|
|
||||||
@ -170,11 +172,12 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
pointRect &= _bounds;
|
pointRect &= _bounds;
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
_data.points(pointRectD.toRectC(_projection, 20), _zoom, &points);
|
_data.points(pointRectD.toRectC(_projection, 20), _zoom,
|
||||||
|
&points);
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform, _zoom,
|
tiles.append(RasterTile(_projection, _transform, _zoom,
|
||||||
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())), key,
|
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
||||||
paths, points));
|
_tileRatio, key, paths, points));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,6 +191,13 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapsforgeMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mapRatio);
|
||||||
|
|
||||||
|
_tileRatio = deviceRatio;
|
||||||
|
}
|
||||||
|
|
||||||
void MapsforgeMap::setOutputProjection(const Projection &projection)
|
void MapsforgeMap::setOutputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (projection == _projection)
|
if (projection == _projection)
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
void setOutputProjection(const Projection &projection);
|
void setOutputProjection(const Projection &projection);
|
||||||
|
void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
|
||||||
|
|
||||||
QPointF ll2xy(const Coordinates &c)
|
QPointF ll2xy(const Coordinates &c)
|
||||||
{return _transform.proj2img(_projection.ll2xy(c));}
|
{return _transform.proj2img(_projection.ll2xy(c));}
|
||||||
@ -99,6 +100,7 @@ private:
|
|||||||
Projection _projection;
|
Projection _projection;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
QRectF _bounds;
|
QRectF _bounds;
|
||||||
|
qreal _tileRatio;
|
||||||
|
|
||||||
QSet<QString> _running;
|
QSet<QString> _running;
|
||||||
};
|
};
|
||||||
|
@ -238,7 +238,7 @@ static bool reverse(const QPainterPath &path)
|
|||||||
|
|
||||||
TextPathItem::TextPathItem(const QPolygonF &line, const QString *label,
|
TextPathItem::TextPathItem(const QPolygonF &line, const QString *label,
|
||||||
const QRect &tileRect, const QFont *font, const QColor *color)
|
const QRect &tileRect, const QFont *font, const QColor *color)
|
||||||
: TextItem(label), _font(font), _color(color), _outlineColor(0)
|
: TextItem(label), _font(font), _color(color), _haloColor(0)
|
||||||
{
|
{
|
||||||
qreal cw = font->pixelSize() * 0.6;
|
qreal cw = font->pixelSize() * 0.6;
|
||||||
qreal textWidth = _text->size() * cw;
|
qreal textWidth = _text->size() * cw;
|
||||||
@ -259,8 +259,8 @@ TextPathItem::TextPathItem(const QPolygonF &line, const QString *label,
|
|||||||
|
|
||||||
TextPathItem::TextPathItem(const QPainterPath &line, const QString *label,
|
TextPathItem::TextPathItem(const QPainterPath &line, const QString *label,
|
||||||
const QRect &tileRect, const QFont *font, const QColor *color,
|
const QRect &tileRect, const QFont *font, const QColor *color,
|
||||||
const QColor *outlineColor) : TextItem(label), _font(font), _color(color),
|
const QColor *haloColor) : TextItem(label), _font(font), _color(color),
|
||||||
_outlineColor(outlineColor)
|
_haloColor(haloColor)
|
||||||
{
|
{
|
||||||
qreal cw = font->pixelSize() * 0.6;
|
qreal cw = font->pixelSize() * 0.6;
|
||||||
qreal textWidth = _text->size() * cw;
|
qreal textWidth = _text->size() * cw;
|
||||||
@ -290,22 +290,23 @@ void TextPathItem::paint(QPainter *painter) const
|
|||||||
QTransform t = painter->transform();
|
QTransform t = painter->transform();
|
||||||
|
|
||||||
painter->setFont(*_font);
|
painter->setFont(*_font);
|
||||||
painter->setPen(_outlineColor ? *_outlineColor : Qt::white);
|
painter->setPen(_haloColor ? *_haloColor : Qt::white);
|
||||||
|
|
||||||
for (int i = 0; i < _text->size(); i++) {
|
for (int i = 0; i < _text->size(); i++) {
|
||||||
QPointF point = _path.pointAtPercent(percent);
|
QPointF point = _path.pointAtPercent(percent);
|
||||||
qreal angle = _path.angleAtPercent(percent);
|
qreal angle = _path.angleAtPercent(percent);
|
||||||
|
QChar c = _text->at(i);
|
||||||
|
|
||||||
painter->translate(point);
|
painter->translate(point);
|
||||||
painter->rotate(-angle);
|
painter->rotate(-angle);
|
||||||
painter->drawText(QPoint(-1, fm.descent() - 1), _text->at(i));
|
painter->drawText(QPoint(-1, fm.descent() - 1), c);
|
||||||
painter->drawText(QPoint(1, fm.descent() + 1), _text->at(i));
|
painter->drawText(QPoint(1, fm.descent() + 1), c);
|
||||||
painter->drawText(QPoint(-1, fm.descent() + 1), _text->at(i));
|
painter->drawText(QPoint(-1, fm.descent() + 1), c);
|
||||||
painter->drawText(QPoint(1, fm.descent() -1), _text->at(i));
|
painter->drawText(QPoint(1, fm.descent() -1), c);
|
||||||
painter->drawText(QPoint(0, fm.descent() - 1), _text->at(i));
|
painter->drawText(QPoint(0, fm.descent() - 1), c);
|
||||||
painter->drawText(QPoint(0, fm.descent() + 1), _text->at(i));
|
painter->drawText(QPoint(0, fm.descent() + 1), c);
|
||||||
painter->drawText(QPoint(-1, fm.descent()), _text->at(i));
|
painter->drawText(QPoint(-1, fm.descent()), c);
|
||||||
painter->drawText(QPoint(1, fm.descent()), _text->at(i));
|
painter->drawText(QPoint(1, fm.descent()), c);
|
||||||
painter->setTransform(t);
|
painter->setTransform(t);
|
||||||
|
|
||||||
int width = fm.horizontalAdvance(_text->at(i));
|
int width = fm.horizontalAdvance(_text->at(i));
|
||||||
|
@ -13,7 +13,7 @@ public:
|
|||||||
const QRect &tileRect, const QFont *font, const QColor *color);
|
const QRect &tileRect, const QFont *font, const QColor *color);
|
||||||
TextPathItem(const QPainterPath &line, const QString *label,
|
TextPathItem(const QPainterPath &line, const QString *label,
|
||||||
const QRect &tileRect, const QFont *font, const QColor *color,
|
const QRect &tileRect, const QFont *font, const QColor *color,
|
||||||
const QColor *outlineColor);
|
const QColor *haloColor);
|
||||||
|
|
||||||
bool isValid() const {return !_path.isEmpty();}
|
bool isValid() const {return !_path.isEmpty();}
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
const QFont *_font;
|
const QFont *_font;
|
||||||
const QColor *_color;
|
const QColor *_color;
|
||||||
const QColor *_outlineColor;
|
const QColor *_haloColor;
|
||||||
QPainterPath _path;
|
QPainterPath _path;
|
||||||
QRectF _rect;
|
QRectF _rect;
|
||||||
QPainterPath _shape;
|
QPainterPath _shape;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QStaticText>
|
||||||
#include "textpointitem.h"
|
#include "textpointitem.h"
|
||||||
|
|
||||||
|
|
||||||
@ -17,8 +18,9 @@ static void expand(QRect &rect, int width)
|
|||||||
|
|
||||||
TextPointItem::TextPointItem(const QPoint &point, const QString *text,
|
TextPointItem::TextPointItem(const QPoint &point, const QString *text,
|
||||||
const QFont *font, const QImage *img, const QColor *color,
|
const QFont *font, const QImage *img, const QColor *color,
|
||||||
const QColor *bgColor, bool padding) : TextItem(font ? text : 0),
|
const QColor *haloColor, const QColor *bgColor, bool padding)
|
||||||
_font(font), _img(img), _color(color), _bgColor(bgColor)
|
: TextItem(font ? text : 0), _font(font), _img(img), _color(color),
|
||||||
|
_haloColor(haloColor), _bgColor(bgColor)
|
||||||
{
|
{
|
||||||
if (_text) {
|
if (_text) {
|
||||||
QFontMetrics fm(*_font);
|
QFontMetrics fm(*_font);
|
||||||
@ -66,31 +68,31 @@ void TextPointItem::paint(QPainter *painter) const
|
|||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
painter->setFont(*_font);
|
painter->setFont(*_font);
|
||||||
painter->drawText(_textRect, FLAGS, *_text);
|
painter->drawText(_textRect, FLAGS, *_text);
|
||||||
} else {
|
} else if (_haloColor) {
|
||||||
QImage img(_textRect.size(), QImage::Format_ARGB32_Premultiplied);
|
QStaticText st(*_text);
|
||||||
img.fill(Qt::transparent);
|
st.setTextFormat(Qt::PlainText);
|
||||||
QPainter ip(&img);
|
st.setTextWidth(_textRect.width());
|
||||||
ip.setPen(Qt::white);
|
st.setTextOption(QTextOption(Qt::AlignHCenter));
|
||||||
ip.setFont(*_font);
|
st.setPerformanceHint(QStaticText::AggressiveCaching);
|
||||||
ip.drawText(img.rect(), FLAGS, *_text);
|
|
||||||
|
|
||||||
painter->drawImage(_textRect.x() - 1, _textRect.y() - 1, img);
|
painter->setPen(*_haloColor);
|
||||||
painter->drawImage(_textRect.x() + 1, _textRect.y() + 1, img);
|
|
||||||
painter->drawImage(_textRect.x() - 1, _textRect.y() + 1, img);
|
|
||||||
painter->drawImage(_textRect.x() + 1, _textRect.y() - 1, img);
|
|
||||||
painter->drawImage(_textRect.x(), _textRect.y() - 1, img);
|
|
||||||
painter->drawImage(_textRect.x(), _textRect.y() + 1, img);
|
|
||||||
painter->drawImage(_textRect.x() - 1, _textRect.y(), img);
|
|
||||||
painter->drawImage(_textRect.x() + 1, _textRect.y(), img);
|
|
||||||
|
|
||||||
if (_color) {
|
|
||||||
painter->setFont(*_font);
|
painter->setFont(*_font);
|
||||||
|
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(-1, -1), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(+1, +1), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(-1, +1), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(+1, -1), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(0, -1), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(0, +1), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(-1, 0), st);
|
||||||
|
painter->drawStaticText(_textRect.topLeft() + QPointF(+1, 0), st);
|
||||||
|
|
||||||
painter->setPen(*_color);
|
painter->setPen(*_color);
|
||||||
painter->drawText(_textRect, FLAGS, *_text);
|
painter->drawStaticText(_textRect.topLeft(), st);
|
||||||
} else {
|
} else {
|
||||||
img.invertPixels();
|
painter->setPen(*_color);
|
||||||
painter->drawImage(_textRect, img);
|
painter->setFont(*_font);
|
||||||
}
|
painter->drawText(_textRect, FLAGS, *_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ class TextPointItem : public TextItem
|
|||||||
public:
|
public:
|
||||||
TextPointItem() : TextItem(0), _font(0), _img(0) {}
|
TextPointItem() : TextItem(0), _font(0), _img(0) {}
|
||||||
TextPointItem(const QPoint &point, const QString *text, const QFont *font,
|
TextPointItem(const QPoint &point, const QString *text, const QFont *font,
|
||||||
const QImage *img, const QColor *color, const QColor *bgColor = 0,
|
const QImage *img, const QColor *color, const QColor *haloColor,
|
||||||
bool padding = true);
|
const QColor *bgColor = 0, bool padding = true);
|
||||||
|
|
||||||
bool isValid() const {return !_rect.isEmpty();}
|
bool isValid() const {return !_rect.isEmpty();}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
const QFont *_font;
|
const QFont *_font;
|
||||||
const QImage *_img;
|
const QImage *_img;
|
||||||
const QColor *_color, *_bgColor;
|
const QColor *_color, *_haloColor, *_bgColor;
|
||||||
QRect _rect, _textRect;
|
QRect _rect, _textRect;
|
||||||
QPainterPath _shape;
|
QPainterPath _shape;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user