1 /*
2 SPDX-FileCopyrightText: 1997 Mathias Mueller <in5y158@public.uni-hamburg.de>
3 SPDX-FileCopyrightText: 2006 Mauricio Piacentini <mauricio@tabuleiro.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 // own
9 #include "kmahjonggbackground.h"
10
11 // Qt
12 #include <QFile>
13 #include <QImage>
14 #include <QMap>
15 #include <QPainter>
16 #include <QPixmap>
17 #include <QPixmapCache>
18 #include <QSvgRenderer>
19
20 // KF
21 #include <KConfig>
22 #include <KConfigGroup>
23 #include <KLocalizedString>
24
25 // LibKMahjongg
26 #include "libkmahjongg_debug.h"
27
28 class KMahjonggBackgroundPrivate
29 {
30 public:
KMahjonggBackgroundPrivate()31 KMahjonggBackgroundPrivate()
32 : w(1)
33 , h(1)
34 , graphicsLoaded(false)
35 , isPlain(false)
36 , isTiled(true)
37 , isSVG(false)
38 {
39 }
40
41 QMap<QString, QString> authorproperties;
42 QString pixmapCacheNameFromElementId(const QString & elementid);
43 QPixmap renderBG(short width, short height);
44
45 QPixmap backgroundPixmap;
46 QBrush backgroundBrush;
47 QString filename;
48 QString graphicspath;
49 short w;
50 short h;
51
52 QSvgRenderer svg;
53
54 bool graphicsLoaded;
55 bool isPlain;
56 bool isTiled;
57 bool isSVG;
58 };
59
KMahjonggBackground()60 KMahjonggBackground::KMahjonggBackground()
61 : d(new KMahjonggBackgroundPrivate)
62 {
63 static bool _inited = false;
64 if (_inited) {
65 return;
66 }
67 _inited = true;
68 }
69
70 KMahjonggBackground::~KMahjonggBackground() = default;
71
loadDefault()72 bool KMahjonggBackground::loadDefault()
73 {
74 // Set default background here.
75 QLatin1String idx("egyptian.desktop");
76
77 QString bgPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kmahjongglib/backgrounds/") + idx);
78 qCDebug(LIBKMAHJONGG_LOG) << "Inside LoadDefault(), located background at" << bgPath;
79 if (bgPath.isEmpty()) {
80 return false;
81 }
82 return load(bgPath, 0, 0);
83 }
84
85 #define kBGVersionFormat 1
86
load(const QString & file,short width,short height)87 bool KMahjonggBackground::load(const QString & file, short width, short height)
88 {
89 //qCDebug(LIBKMAHJONGG_LOG) << "Background loading";
90 d->isSVG = false;
91
92 //qCDebug(LIBKMAHJONGG_LOG) << "Attempting to load .desktop at" << file;
93
94 // verify if it is a valid file first and if we can open it
95 QFile bgfile(file);
96 if (!bgfile.open(QIODevice::ReadOnly)) {
97 return false;
98 }
99 bgfile.close();
100
101 KConfig bgconfig(file, KConfig::SimpleConfig);
102 KConfigGroup group = bgconfig.group("KMahjonggBackground");
103
104 d->authorproperties.insert(QStringLiteral("Name"), group.readEntry("Name")); // Returns translated data
105 d->authorproperties.insert(QStringLiteral("Author"), group.readEntry("Author"));
106 d->authorproperties.insert(QStringLiteral("Description"), group.readEntry("Description"));
107 d->authorproperties.insert(QStringLiteral("AuthorEmail"), group.readEntry("AuthorEmail"));
108 //The "Plain" key is set to 1 by the color_plain background.
109 d->isPlain = group.readEntry("Plain", 0) != 0;
110 d->authorproperties.insert(QStringLiteral("Plain"), d->isPlain ? QStringLiteral("1") : QStringLiteral("0"));
111
112 //Version control
113 int bgversion = group.readEntry("VersionFormat", 0);
114 //Format is increased when we have incompatible changes, meaning that older clients are not able to use the remaining information safely
115 if (bgversion > kBGVersionFormat) {
116 return false;
117 }
118
119 if (d->isPlain) {
120 //qCDebug(LIBKMAHJONGG_LOG) << "Using plain background";
121 d->graphicspath.clear();
122 d->filename = file;
123 return true;
124 }
125
126 QString graphName = group.readEntry("FileName");
127
128 d->graphicspath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kmahjongglib/backgrounds/") + graphName);
129
130 qCDebug(LIBKMAHJONGG_LOG) << "Using background at" << d->graphicspath;
131
132 if (d->graphicspath.isEmpty()) {
133 return false;
134 }
135
136 if (group.readEntry("Tiled", 0) != 0) {
137 d->w = group.readEntry("Width", 0);
138 d->h = group.readEntry("Height", 0);
139 d->isTiled = true;
140 } else {
141 d->w = width;
142 d->h = height;
143 d->isTiled = false;
144 }
145 d->graphicsLoaded = false;
146 d->filename = file;
147 return true;
148 }
149
loadGraphics()150 bool KMahjonggBackground::loadGraphics()
151 {
152 if (d->graphicsLoaded || d->isPlain) {
153 return true;
154 }
155
156 d->svg.load(d->graphicspath);
157 if (d->svg.isValid()) {
158 d->isSVG = true;
159 } else {
160 //qCDebug(LIBKMAHJONGG_LOG) << "could not load svg";
161 return false;
162 }
163 return true;
164 }
165
sizeChanged(int newW,int newH)166 void KMahjonggBackground::sizeChanged(int newW, int newH)
167 {
168 //in tiled mode we do not care about the whole field size
169 if (d->isTiled || d->isPlain) {
170 return;
171 }
172
173 if (newW == d->w && newH == d->h) {
174 return;
175 }
176 d->w = newW;
177 d->h = newH;
178 }
179
pixmapCacheNameFromElementId(const QString & elementid)180 QString KMahjonggBackgroundPrivate::pixmapCacheNameFromElementId(const QString & elementid)
181 {
182 return authorproperties[QStringLiteral("Name")] + elementid + QStringLiteral("W%1H%2").arg(w).arg(h);
183 }
184
renderBG(short width,short height)185 QPixmap KMahjonggBackgroundPrivate::renderBG(short width, short height)
186 {
187 QImage qiRend(QSize(width, height), QImage::Format_ARGB32_Premultiplied);
188 qiRend.fill(0);
189
190 if (svg.isValid()) {
191 QPainter p(&qiRend);
192 svg.render(&p);
193 }
194 return QPixmap::fromImage(qiRend);
195 }
196
getBackground()197 QBrush & KMahjonggBackground::getBackground()
198 {
199 if (d->isPlain) {
200 d->backgroundBrush = QBrush(QPixmap());
201 } else {
202 if (!QPixmapCache::find(d->pixmapCacheNameFromElementId(d->filename), &d->backgroundPixmap)) {
203 d->backgroundPixmap = d->renderBG(d->w, d->h);
204 QPixmapCache::insert(d->pixmapCacheNameFromElementId(d->filename), d->backgroundPixmap);
205 }
206 d->backgroundBrush = QBrush(d->backgroundPixmap);
207 }
208 return d->backgroundBrush;
209 }
210
path() const211 QString KMahjonggBackground::path() const
212 {
213 return d->filename;
214 }
215
authorProperty(const QString & key) const216 QString KMahjonggBackground::authorProperty(const QString & key) const
217 {
218 return d->authorproperties[key];
219 }
220