1 #include <QJsonDocument>
2 #include <QJsonObject>
3 #include <QFile>
4 #include <QDebug>
5 #include "sprites.h"
6
7
8 /*
9 Loading the sprites atlas image must be deferred until all image plugins
10 are loaded, otherwise reading the image will cause a deadlock!
11 */
atlas(const QString & fileName)12 static const QImage *atlas(const QString &fileName)
13 {
14 static QImage *img = new QImage(fileName);
15 return img;
16 }
17
Sprite(const QJsonObject & json)18 Sprites::Sprite::Sprite(const QJsonObject &json)
19 {
20 int x, y, width, height;
21
22
23 if (json.contains("x") && json["x"].isDouble())
24 x = json["x"].toInt();
25 else
26 return;
27 if (json.contains("y") && json["y"].isDouble())
28 y = json["y"].toInt();
29 else
30 return;
31 if (json.contains("width") && json["width"].isDouble())
32 width = json["width"].toInt();
33 else
34 return;
35 if (json.contains("height") && json["height"].isDouble())
36 height = json["height"].toInt();
37 else
38 return;
39
40 _rect = QRect(x, y, width, height);
41
42
43 if (json.contains("pixelRatio") && json["pixelRatio"].isDouble())
44 _pixelRatio = json["pixelRatio"].toDouble();
45 else
46 _pixelRatio = 1.0;
47 }
48
load(const QString & jsonFile,const QString & imageFile)49 bool Sprites::load(const QString &jsonFile, const QString &imageFile)
50 {
51 _imageFile = imageFile;
52
53 QFile file(jsonFile);
54 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
55 qCritical() << jsonFile << ": error opening file";
56 return false;
57 }
58 QByteArray ba(file.readAll());
59
60 QJsonParseError error;
61 QJsonDocument doc(QJsonDocument::fromJson(ba, &error));
62 if (doc.isNull()) {
63 qCritical() << jsonFile << ":" << error.errorString();
64 return false;
65 }
66
67 QJsonObject json(doc.object());
68 for (QJsonObject::const_iterator it = json.constBegin();
69 it != json.constEnd(); it++) {
70 QJsonValue val(*it);
71 if (val.isObject()) {
72 Sprite s(val.toObject());
73 if (s.rect().isValid())
74 _sprites.insert(it.key(), s);
75 else
76 qWarning() << it.key() << ": invalid sprite definition";
77 } else
78 qWarning() << it.key() << ": invalid sprite definition";
79 }
80
81 return true;
82 }
83
icon(const QString & name) const84 QImage Sprites::icon(const QString &name) const
85 {
86 if (_imageFile.isEmpty())
87 return QImage();
88
89 const QImage *img = atlas(_imageFile);
90 if (img->isNull())
91 return QImage();
92
93 QMap<QString, Sprite>::const_iterator it = _sprites.find(name);
94 if (it == _sprites.constEnd())
95 return QImage();
96
97 if (!img->rect().contains(it->rect()))
98 return QImage();
99
100 QImage ret(img->copy(it->rect()));
101 ret.setDevicePixelRatio(it->pixelRatio());
102
103 return ret;
104 }
105