Refactored sprites handling code

This commit is contained in:
Martin Tůma 2018-12-05 00:03:41 +01:00
parent 08509f0930
commit 7442b76939
4 changed files with 55 additions and 76 deletions

View File

@ -15,17 +15,11 @@ static const QImage *atlas(const QString &fileName)
return img;
}
static const QImage *atlas2x(const QString &fileName)
{
static QImage *img = new QImage(fileName);
return img;
}
Sprites::Sprite::Sprite(const QJsonObject &json)
{
int x, y, width, height;
if (json.contains("x") && json["x"].isDouble())
x = json["x"].toInt();
else
@ -44,22 +38,18 @@ Sprites::Sprite::Sprite(const QJsonObject &json)
return;
_rect = QRect(x, y, width, height);
if (json.contains("pixelRatio") && json["pixelRatio"].isDouble())
_pixelRatio = json["pixelRatio"].toDouble();
else
_pixelRatio = 1.0;
}
bool Sprites::load(const QString &jsonFile, const QString &imageFile)
{
_imageFile = imageFile;
return load(jsonFile, _sprites);
}
bool Sprites::load2x(const QString &jsonFile, const QString &imageFile)
{
_image2xFile = imageFile;
return load(jsonFile, _sprites2x);
}
bool Sprites::load(const QString &jsonFile, QMap<QString, Sprite> &map)
{
QFile file(jsonFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCritical() << jsonFile << ": error opening file";
@ -81,7 +71,7 @@ bool Sprites::load(const QString &jsonFile, QMap<QString, Sprite> &map)
if (val.isObject()) {
Sprite s(val.toObject());
if (s.rect().isValid())
map.insert(it.key(), s);
_sprites.insert(it.key(), s);
else
qWarning() << it.key() << ": invalid sprite definition";
} else
@ -91,36 +81,21 @@ bool Sprites::load(const QString &jsonFile, QMap<QString, Sprite> &map)
return true;
}
QImage Sprites::icon(const QString &name, bool hidpi) const
QImage Sprites::icon(const QString &name) const
{
qreal ratio;
const QImage *img;
const QMap<QString, Sprite> *map;
if (hidpi && !_image2xFile.isNull()) {
img = atlas2x(_image2xFile);
map = &_sprites2x;
ratio = 2;
} else if (!_imageFile.isNull()) {
img = atlas(_imageFile);
map = &_sprites;
ratio = 1;
} else
return QImage();
const QImage *img = atlas(_imageFile);
if (img->isNull())
return QImage();
QMap<QString, Sprite>::const_iterator it = map->find(name);
if (it == map->constEnd())
QMap<QString, Sprite>::const_iterator it = _sprites.find(name);
if (it == _sprites.constEnd())
return QImage();
if (!img->rect().contains(it->rect()))
return QImage();
QImage ret(img->copy(it->rect()));
ret.setDevicePixelRatio(ratio);
ret.setDevicePixelRatio(it->pixelRatio());
return ret;
}

View File

@ -9,24 +9,25 @@ class Sprites
{
public:
bool load(const QString &jsonFile, const QString &imageFile);
bool load2x(const QString &jsonFile, const QString &imageFile);
QImage icon(const QString &name, bool hidpi) const;
bool isNull() const {return _imageFile.isNull();}
QImage icon(const QString &name) const;
private:
class Sprite {
public:
Sprite(const QJsonObject &json);
const QRect &rect() const {return _rect;}
qreal pixelRatio() const {return _pixelRatio;}
private:
QRect _rect;
qreal _pixelRatio;
};
bool load(const QString &jsonFile, QMap<QString, Sprite> &map);
QMap<QString, Sprite> _sprites, _sprites2x;
QString _imageFile, _image2xFile;
QMap<QString, Sprite> _sprites;
QString _imageFile;
};
#endif // SPRITES_H

View File

@ -223,8 +223,8 @@ QPen Style::Layer::Paint::pen(Type type, int zoom) const
return pen;
}
QBrush Style::Layer::Paint::brush(Type type, int zoom, const Sprites &sprites,
bool hidpi) const
QBrush Style::Layer::Paint::brush(Type type, int zoom, const Sprites &sprites)
const
{
QColor color;
QBrush brush(Qt::NoBrush);
@ -237,7 +237,7 @@ QBrush Style::Layer::Paint::brush(Type type, int zoom, const Sprites &sprites,
brush = QBrush(color);
pattern = _fillPattern.value(zoom);
if (!pattern.isNull())
brush.setTextureImage(sprites.icon(pattern, hidpi));
brush.setTextureImage(sprites.icon(pattern));
break;
case Background:
color = _backgroundColor.value(zoom);
@ -245,7 +245,7 @@ QBrush Style::Layer::Paint::brush(Type type, int zoom, const Sprites &sprites,
brush = QBrush(color);
pattern = _fillPattern.value(zoom);
if (!pattern.isNull())
brush.setTextureImage(sprites.icon(pattern, hidpi));
brush.setTextureImage(sprites.icon(pattern));
break;
default:
break;
@ -449,8 +449,7 @@ void Style::Layer::setPathPainter(Tile &tile, const Sprites &sprites) const
pen.setJoinStyle(_layout.lineJoin(zoom));
pen.setCapStyle(_layout.lineCap(zoom));
bool hidpi = qMax(tile.scale().x(), tile.scale().y()) > 1.0 ? true : false;
QBrush brush(_paint.brush(_type, zoom, sprites, hidpi));
QBrush brush(_paint.brush(_type, zoom, sprites));
p.setRenderHint(QPainter::Antialiasing, _paint.antialias(_type, zoom));
p.setPen(pen);
@ -480,8 +479,25 @@ void Style::Layer::addSymbol(Tile &tile, const QPainterPath &path,
return;
QString icon = _layout.icon(tile.zoom(), tags);
bool hidpi = qMax(tile.scale().x(), tile.scale().y()) > 1.0 ? true : false;
tile.text().addLabel(text, sprites.icon(icon, hidpi), path);
tile.text().addLabel(text, sprites.icon(icon), path);
}
static bool loadSprites(const QDir &styleDir, const QString &json,
const QString &img, Sprites &sprites)
{
QString spritesJSON(styleDir.filePath(json));
if (QFileInfo::exists(spritesJSON)) {
QString spritesImg(styleDir.filePath(img));
if (QFileInfo::exists(spritesImg))
return sprites.load(spritesJSON, spritesImg);
else {
qCritical() << spritesImg << ": no such file";
return false;
}
}
return true;
}
bool Style::load(const QString &fileName)
@ -512,26 +528,9 @@ bool Style::load(const QString &fileName)
for (int i = 0; i < _layers.size(); i++)
_sourceLayers.append(_layers.at(i).sourceLayer());
QDir styleDir = QFileInfo(fileName).absoluteDir();
QString spritesJSON(styleDir.filePath("sprite.json"));
if (QFileInfo::exists(spritesJSON)) {
QString spritesImg(styleDir.filePath("sprite.png"));
if (QFileInfo::exists(spritesImg))
_sprites.load(spritesJSON, spritesImg);
else
qCritical() << spritesImg << ": no such file";
}
QString sprites2xJSON(styleDir.filePath("sprite@2x.json"));
if (QFileInfo::exists(sprites2xJSON)) {
QString sprites2xImg(styleDir.filePath("sprite@2x.png"));
if (QFileInfo::exists(sprites2xImg))
_sprites.load2x(sprites2xJSON, sprites2xImg);
else
qCritical() << sprites2xImg << ": no such file";
}
loadSprites(styleDir, "sprite.json", "sprite.png", _sprites);
loadSprites(styleDir, "sprite@2x.json", "sprite@2x.png", _sprites2x);
return true;
}
@ -539,22 +538,26 @@ bool Style::load(const QString &fileName)
void Style::setupLayer(Tile &tile, int layer) const
{
const Layer &sl = _layers.at(layer);
const Sprites &sprites = (tile.scale().x() > 1.0 || tile.scale().y() > 1.0)
&& !_sprites2x.isNull() ? _sprites2x : _sprites;
if (sl.isSymbol())
sl.setTextProperties(tile);
else if (sl.isPath())
sl.setPathPainter(tile, _sprites);
sl.setPathPainter(tile, sprites);
}
void Style::drawFeature(Tile &tile, int layer, const QPainterPath &path,
const QVariantHash &tags) const
{
const Layer &sl = _layers.at(layer);
const Sprites &sprites = (tile.scale().x() > 1.0 || tile.scale().y() > 1.0)
&& !_sprites2x.isNull() ? _sprites2x : _sprites;
if (sl.isPath())
tile.painter().drawPath(path);
else if (sl.isSymbol())
sl.addSymbol(tile, path, tags, _sprites);
sl.addSymbol(tile, path, tags, sprites);
}
void Style::drawBackground(Tile &tile) const

View File

@ -136,8 +136,8 @@ private:
Paint(const QJsonObject &json);
QPen pen(Layer::Type type, int zoom) const;
QBrush brush(Layer::Type type, int zoom, const Sprites &sprites,
bool hidpi) const;
QBrush brush(Layer::Type type, int zoom, const Sprites &sprites)
const;
qreal opacity(Layer::Type type, int zoom) const;
bool antialias(Layer::Type type, int zoom) const;
QString fillPattern(int zoom) const
@ -167,7 +167,7 @@ private:
QVector<Layer> _layers;
QStringList _sourceLayers;
Sprites _sprites;
Sprites _sprites, _sprites2x;
};
#endif // STYLE_H