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