Some more optimization/code cleanup

This commit is contained in:
Martin Tůma 2018-11-13 18:24:51 +01:00
parent 0c4624d28e
commit f4b1952b95
5 changed files with 45 additions and 30 deletions

View File

@ -113,7 +113,7 @@ static inline QPoint parameters(quint32 v1, quint32 v2)
return QPoint(zigzag32decode(v1), zigzag32decode(v2)); return QPoint(zigzag32decode(v1), zigzag32decode(v2));
} }
static void processFeature(const Feature &feature, Style *style, int styleLayer, static void drawFeature(const Feature &feature, Style *style, int styleLayer,
const QSizeF &factor, Tile &tile) const QSizeF &factor, Tile &tile)
{ {
if (!style->match(styleLayer, feature.tags())) if (!style->match(styleLayer, feature.tags()))
@ -151,7 +151,7 @@ static void processFeature(const Feature &feature, Style *style, int styleLayer,
} }
} }
style->processFeature(styleLayer, path, feature.tags(), tile); style->drawFeature(styleLayer, path, feature.tags(), tile);
} }
static void drawLayer(const Layer &layer, Style *style, int styleLayer, static void drawLayer(const Layer &layer, Style *style, int styleLayer,
@ -163,11 +163,9 @@ static void drawLayer(const Layer &layer, Style *style, int styleLayer,
QSizeF factor(tile.size().width() / (qreal)layer.data()->extent(), QSizeF factor(tile.size().width() / (qreal)layer.data()->extent(),
tile.size().height() / (qreal)layer.data()->extent()); tile.size().height() / (qreal)layer.data()->extent());
tile.painter().save();
style->setPainter(styleLayer, tile); style->setPainter(styleLayer, tile);
for (int i = 0; i < layer.features().size(); i++) for (int i = 0; i < layer.features().size(); i++)
processFeature(layer.features().at(i), style, styleLayer, factor, tile); drawFeature(layer.features().at(i), style, styleLayer, factor, tile);
tile.painter().restore();
} }
bool PBF::render(const QByteArray &data, int zoom, Style *style, qreal scale, bool PBF::render(const QByteArray &data, int zoom, Style *style, qreal scale,
@ -193,6 +191,8 @@ bool PBF::render(const QByteArray &data, int zoom, Style *style, qreal scale,
layers.insert(name, Layer(&layer)); layers.insert(name, Layer(&layer));
} }
t.painter().save();
// Process source layers in order of style layers // Process source layers in order of style layers
for (int i = 0; i < style->sourceLayers().size(); i++) { for (int i = 0; i < style->sourceLayers().size(); i++) {
QMap<QString, Layer>::const_iterator it = layers.find( QMap<QString, Layer>::const_iterator it = layers.find(
@ -203,6 +203,7 @@ bool PBF::render(const QByteArray &data, int zoom, Style *style, qreal scale,
drawLayer(*it, style, i, t); drawLayer(*it, style, i, t);
} }
t.painter().restore();
t.text().render(&t.painter()); t.text().render(&t.painter());
return true; return true;

View File

@ -276,6 +276,7 @@ Style::Layer::Layout::Layout(const QJsonObject &json)
: _textSize(16), _textMaxWidth(10), _textMaxAngle(45), _lineCap(Qt::FlatCap), : _textSize(16), _textMaxWidth(10), _textMaxAngle(45), _lineCap(Qt::FlatCap),
_lineJoin(Qt::MiterJoin), _font("Open Sans"), _capitalize(false) _lineJoin(Qt::MiterJoin), _font("Open Sans"), _capitalize(false)
{ {
// line
if (json.contains("line-cap") && json["line-cap"].isString()) { if (json.contains("line-cap") && json["line-cap"].isString()) {
if (json["line-cap"].toString() == "round") if (json["line-cap"].toString() == "round")
_lineCap = Qt::RoundCap; _lineCap = Qt::RoundCap;
@ -289,6 +290,7 @@ Style::Layer::Layout::Layout(const QJsonObject &json)
_lineJoin = Qt::RoundJoin; _lineJoin = Qt::RoundJoin;
} }
// text
if (!(json.contains("text-field") && json["text-field"].isString())) if (!(json.contains("text-field") && json["text-field"].isString()))
return; return;
_textField = json["text-field"].toString(); _textField = json["text-field"].toString();
@ -366,7 +368,7 @@ bool Style::Layer::match(int zoom, const QVariantHash &tags) const
return _filter.match(tags); return _filter.match(tags);
} }
void Style::Layer::setPainter(int zoom, Tile &tile) const void Style::Layer::setPathPainter(int zoom, Tile &tile) const
{ {
QPen pen(_paint.pen(_type, zoom)); QPen pen(_paint.pen(_type, zoom));
QBrush brush(_paint.brush(_type, zoom)); QBrush brush(_paint.brush(_type, zoom));
@ -381,6 +383,16 @@ void Style::Layer::setPainter(int zoom, Tile &tile) const
p.setOpacity(_paint.opacity(_type, zoom)); p.setOpacity(_paint.opacity(_type, zoom));
} }
void Style::Layer::setSymbolPainter(int zoom, Tile &tile) const
{
QPen pen(_paint.pen(_type, zoom));
QFont font(_layout.font(zoom));
QPainter &p = tile.painter();
p.setPen(pen);
p.setFont(font);
}
void Style::Layer::addSymbol(int zoom, const QPainterPath &path, void Style::Layer::addSymbol(int zoom, const QPainterPath &path,
const QVariantHash &tags, Tile &tile) const const QVariantHash &tags, Tile &tile) const
{ {
@ -399,14 +411,12 @@ void Style::Layer::addSymbol(int zoom, const QPainterPath &path,
if (tt.isEmpty()) if (tt.isEmpty())
return; return;
QPen pen(_paint.pen(_type, zoom));
QFont font(_layout.font(zoom));
if (path.elementCount() == 1 && path.elementAt(0).isMoveTo()) if (path.elementCount() == 1 && path.elementAt(0).isMoveTo())
tile.text().addLabel(tt, path.elementAt(0), font, pen, tile.text().addLabel(tt, path.elementAt(0), tile.painter(),
_layout.maxTextWidth(zoom)); _layout.maxTextWidth(zoom));
else else
tile.text().addLabel(tt, path, font, pen, _layout.maxTextAngle(zoom)); tile.text().addLabel(tt, path, tile.painter(),
_layout.maxTextAngle(zoom));
} }
bool Style::load(const QString &fileName) bool Style::load(const QString &fileName)
@ -450,10 +460,12 @@ void Style::setPainter(int layer, Tile &tile)
const Layer &sl = _styles.at(layer); const Layer &sl = _styles.at(layer);
if (sl.isPath()) if (sl.isPath())
sl.setPainter(_zoom, tile); sl.setPathPainter(_zoom, tile);
else if (sl.isSymbol())
sl.setSymbolPainter(_zoom, tile);
} }
void Style::processFeature(int layer, const QPainterPath &path, void Style::drawFeature(int layer, const QPainterPath &path,
const QVariantHash &tags, Tile &tile) const QVariantHash &tags, Tile &tile)
{ {
const Layer &sl = _styles.at(layer); const Layer &sl = _styles.at(layer);
@ -475,7 +487,7 @@ void Style::drawBackground(Tile &tile)
tile.painter().setPen(Qt::NoPen); tile.painter().setPen(Qt::NoPen);
tile.painter().drawRect(rect); tile.painter().drawRect(rect);
} else if (_styles.first().isBackground()) { } else if (_styles.first().isBackground()) {
_styles.first().setPainter(_zoom, tile); _styles.first().setPathPainter(_zoom, tile);
tile.painter().drawPath(path); tile.painter().drawPath(path);
} }
} }

View File

@ -30,12 +30,13 @@ public:
void drawBackground(Tile &tile); void drawBackground(Tile &tile);
void setPainter(int layer, Tile &tile); void setPainter(int layer, Tile &tile);
void processFeature(int layer, const QPainterPath &path, void drawFeature(int layer, const QPainterPath &path,
const QVariantHash &tags, Tile &tile); const QVariantHash &tags, Tile &tile);
private: private:
class Layer { class Layer {
public: public:
Layer() : _type(Unknown), _minZoom(-1), _maxZoom(-1) {}
Layer(const QJsonObject &json); Layer(const QJsonObject &json);
const QString &sourceLayer() const {return _sourceLayer;} const QString &sourceLayer() const {return _sourceLayer;}
@ -44,7 +45,8 @@ private:
bool isSymbol() const {return (_type == Symbol);} bool isSymbol() const {return (_type == Symbol);}
bool match(int zoom, const QVariantHash &tags) const; bool match(int zoom, const QVariantHash &tags) const;
void setPainter(int zoom, Tile &tile) const; void setPathPainter(int zoom, Tile &tile) const;
void setSymbolPainter(int zoom, Tile &tile) const;
void addSymbol(int zoom, const QPainterPath &path, void addSymbol(int zoom, const QPainterPath &path,
const QVariantHash &tags, Tile &tile) const; const QVariantHash &tags, Tile &tile) const;
@ -140,7 +142,7 @@ private:
}; };
int _zoom; int _zoom;
QList<Layer> _styles; QVector<Layer> _styles;
QStringList _sourceLayers; QStringList _sourceLayers;
}; };

View File

@ -149,8 +149,8 @@ void Text::render(QPainter *painter) const
} }
} }
void Text::addLabel(const QString &text, const QPointF &pos, const QFont &font, void Text::addLabel(const QString &text, const QPointF &pos,
const QPen &pen, qreal maxTextWidth) const QPainter &painter, qreal maxTextWidth)
{ {
if (text.isEmpty()) if (text.isEmpty())
return; return;
@ -158,13 +158,13 @@ void Text::addLabel(const QString &text, const QPointF &pos, const QFont &font,
TextPointItem *ti; TextPointItem *ti;
if (_fontScale != 1.0) { if (_fontScale != 1.0) {
QFont scaledFont(font); QFont scaledFont(painter.font());
scaledFont.setPixelSize(font.pixelSize() * _fontScale); scaledFont.setPixelSize(painter.font().pixelSize() * _fontScale);
ti = new TextPointItem(text, pos, scaledFont, maxTextWidth); ti = new TextPointItem(text, pos, scaledFont, maxTextWidth);
} else } else
ti = new TextPointItem(text, pos, font, maxTextWidth); ti = new TextPointItem(text, pos, painter.font(), maxTextWidth);
ti->setPen(pen); ti->setPen(painter.pen());
addItem(ti); addItem(ti);
QList<TextItem*> ci = collidingItems(ti); QList<TextItem*> ci = collidingItems(ti);
for (int i = 0; i < ci.size(); i++) for (int i = 0; i < ci.size(); i++)
@ -172,15 +172,15 @@ void Text::addLabel(const QString &text, const QPointF &pos, const QFont &font,
} }
void Text::addLabel(const QString &text, const QPainterPath &path, void Text::addLabel(const QString &text, const QPainterPath &path,
const QFont &font, const QPen &pen, qreal maxAngle) const QPainter &painter, qreal maxAngle)
{ {
if (path.isEmpty()) if (path.isEmpty())
return; return;
if (text.isEmpty()) if (text.isEmpty())
return; return;
QFont scaledFont(font); QFont scaledFont(painter.font());
scaledFont.setPixelSize(font.pixelSize() * _fontScale); scaledFont.setPixelSize(painter.font().pixelSize() * _fontScale);
int textWidth = text.size() * scaledFont.pixelSize() * 0.6; int textWidth = text.size() * scaledFont.pixelSize() * 0.6;
if (textWidth > path.length()) if (textWidth > path.length())
@ -197,7 +197,7 @@ void Text::addLabel(const QString &text, const QPainterPath &path,
delete pi; delete pi;
return; return;
} }
pi->setPen(pen); pi->setPen(painter.pen());
addItem(pi); addItem(pi);

View File

@ -12,10 +12,10 @@ public:
void render(QPainter *painter) const; void render(QPainter *painter) const;
void addLabel(const QString &text, const QPointF &pos, const QFont &font, void addLabel(const QString &text, const QPointF &pos,
const QPen &pen, qreal maxTextWidth); const QPainter &painter, qreal maxTextWidth);
void addLabel(const QString &text, const QPainterPath &path, void addLabel(const QString &text, const QPainterPath &path,
const QFont &font, const QPen &pen, qreal maxAngle); const QPainter &painter, qreal maxAngle);
private: private:
void addItem(TextItem *item) {_items.append(item);} void addItem(TextItem *item) {_items.append(item);}