1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-06-28 03:59:15 +02:00

Improved mapsforge hi-dpi rendering

This commit is contained in:
2021-04-18 12:20:07 +02:00
parent b6add991d2
commit 663859ef1c
11 changed files with 114 additions and 81 deletions

View File

@ -79,6 +79,13 @@ static QString *pathLabel(const Style::TextRender *ri, MapData::Path &path,
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)
{
const Style &s = style();
@ -115,9 +122,11 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
const QImage *img = si ? &si->img() : 0;
const QFont *font = ti ? &ti->font() : 0;
const QColor *color = ti ? &ti->fillColor() : 0;
const QColor *hColor = ti ? haloColor(ti) : 0;
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))
textItems.append(item);
else
@ -125,8 +134,7 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
}
}
void RasterTile::processAreaLabels(const QRect &tileRect,
QList<TextItem*> &textItems)
void RasterTile::processAreaLabels(QList<TextItem*> &textItems)
{
const Style &s = style();
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 QFont *font = ti ? &ti->font() : 0;
const QColor *color = ti ? &ti->fillColor() : 0;
const QColor *hColor = ti ? haloColor(ti) : 0;
QPointF pos = path.labelPos.isNull()
? centroid(path.path) : ll2xy(path.labelPos);
TextPointItem *item = new TextPointItem(pos.toPoint(), label, font, img,
color, 0, false);
if (item->isValid() && tileRect.contains(item->boundingRect().toRect())
color, hColor, 0, false);
if (item->isValid() && _rect.contains(item->boundingRect().toRect())
&& !item->collides(textItems))
textItems.append(item);
else
@ -178,8 +187,7 @@ void RasterTile::processAreaLabels(const QRect &tileRect,
}
}
void RasterTile::processLineLabels(const QRect &tileRect,
QList<TextItem*> &textItems)
void RasterTile::processLineLabels(QList<TextItem*> &textItems)
{
const Style &s = style();
QList<const Style::TextRender*> instructions(s.pathLabels(_zoom));
@ -202,8 +210,8 @@ void RasterTile::processLineLabels(const QRect &tileRect,
if (limit && set.contains(path.label))
continue;
TextPathItem *item = new TextPathItem(path.path, label, tileRect,
&ri->font(), &ri->fillColor(), &ri->strokeColor());
TextPathItem *item = new TextPathItem(path.path, label, _rect,
&ri->font(), &ri->fillColor(), haloColor(ri));
if (item->isValid() && !item->collides(textItems)) {
textItems.append(item);
if (limit)
@ -271,11 +279,12 @@ void RasterTile::drawPaths(QPainter *painter)
const Style::PathRender *lri = 0;
QPixmap layer(_pixmap.size());
layer.setDevicePixelRatio(_ratio);
layer.fill(Qt::transparent);
QPainter lp(&layer);
lp.setRenderHint(QPainter::Antialiasing);
lp.translate(-_xy.x(), -_xy.y());
lp.translate(-_rect.x(), -_rect.y());
lp.setCompositionMode(QPainter::CompositionMode_Source);
for (int i = 0; i < instructions.size(); i++) {
@ -283,8 +292,8 @@ void RasterTile::drawPaths(QPainter *painter)
const Style::PathRender *ri = is.render();
if (lri && lri != ri) {
painter->drawPixmap(_xy, layer);
lp.fillRect(QRect(_xy, _pixmap.size()), Qt::transparent);
painter->drawPixmap(_rect.topLeft(), layer);
lp.fillRect(QRect(_rect.topLeft(), _pixmap.size()), Qt::transparent);
}
if (!is.path()->path.elementCount())
@ -304,7 +313,7 @@ void RasterTile::drawPaths(QPainter *painter)
}
if (lri)
painter->drawPixmap(_xy, layer);
painter->drawPixmap(_rect.topLeft(), layer);
}
void RasterTile::render()
@ -312,24 +321,24 @@ void RasterTile::render()
std::sort(_points.begin(), _points.end());
QList<TextItem*> textItems;
QRect tileRect(_xy, _pixmap.size());
_pixmap.fill(Qt::transparent);
QPainter painter(&_pixmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(-_xy.x(), -_xy.y());
painter.scale(_ratio, _ratio);
painter.translate(-_rect.x(), -_rect.y());
drawPaths(&painter);
processPointLabels(textItems);
processAreaLabels(tileRect, textItems);
processLineLabels(tileRect, textItems);
processAreaLabels(textItems);
processLineLabels(textItems);
drawTextItems(&painter, textItems);
//painter.setPen(Qt::red);
//painter.setBrush(Qt::NoBrush);
//painter.drawRect(QRect(_xy, _pixmap.size()));
//painter.drawRect(QRect(_rect.topLeft(), _pixmap.size()));
qDeleteAll(textItems);
}

View File

@ -16,13 +16,14 @@ class RasterTile
{
public:
RasterTile(const Projection &proj, const Transform &transform, int zoom,
const QRect &rect, const QString &key, const QList<MapData::Path> &paths,
const QList<MapData::Point> &points)
: _proj(proj), _transform(transform), _zoom(zoom), _xy(rect.topLeft()),
_key(key), _pixmap(rect.size()), _paths(paths), _points(points) {}
const QRect &rect, qreal ratio, const QString &key,
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
: _proj(proj), _transform(transform), _zoom(zoom), _rect(rect),
_ratio(ratio), _key(key), _pixmap(rect.width() * ratio,
rect.height() * ratio), _paths(paths), _points(points) {}
const QString &key() const {return _key;}
const QPoint &xy() const {return _xy;}
QPoint xy() const {return _rect.topLeft();}
const QPixmap &pixmap() const {return _pixmap;}
void render();
@ -72,8 +73,8 @@ private:
QPointF ll2xy(const Coordinates &c) const
{return _transform.proj2img(_proj.ll2xy(c));}
void processPointLabels(QList<TextItem*> &textItems);
void processAreaLabels(const QRect &tileRect, QList<TextItem*> &textItems);
void processLineLabels(const QRect &tileRect, QList<TextItem*> &textItems);
void processAreaLabels(QList<TextItem*> &textItems);
void processLineLabels(QList<TextItem*> &textItems);
QPainterPath painterPath(const Polygon &polygon) const;
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
void drawPaths(QPainter *painter);
@ -81,7 +82,8 @@ private:
Projection _proj;
Transform _transform;
int _zoom;
QPoint _xy;
QRect _rect;
qreal _ratio;
QString _key;
QPixmap _pixmap;
QList<MapData::Path> _paths;

View File

@ -159,6 +159,8 @@ void Style::text(QXmlStreamReader &reader, const Rule &rule,
ri._fillColor = QColor(attr.value("fill").toString());
if (attr.hasAttribute("stroke"))
ri._strokeColor = QColor(attr.value("stroke").toString());
if (attr.hasAttribute("stroke-width"))
ri._strokeWidth = attr.value("stroke-width").toFloat();
if (attr.hasAttribute("font-size"))
fontSize = attr.value("font-size").toInt();
if (attr.hasAttribute("font-style")) {

View File

@ -187,17 +187,20 @@ public:
{
public:
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 QColor &fillColor() const {return _fillColor;}
const QColor &strokeColor() const {return _strokeColor;}
qreal strokeWidth() const {return _strokeWidth;}
const QByteArray &key() const {return _key;}
private:
friend class Style;
QColor _fillColor, _strokeColor;
qreal _strokeWidth;
QFont _font;
QByteArray _key;
};