• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

libkmahjongg

  • sources
  • kde-4.14
  • kdegames
  • libkmahjongg
kmahjonggtileset.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997 Mathias Mueller <in5y158@public.uni-hamburg.de>
3  Copyright (C) 2006 Mauricio Piacentini <mauricio@tabuleiro.com>
4 
5  Libkmahjongg is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kmahjonggtileset.h"
21 
22 #include <klocale.h>
23 #include <kconfig.h>
24 #include <kconfiggroup.h>
25 #include <qimage.h>
26 #include <kstandarddirs.h>
27 #include <qsvgrenderer.h>
28 #include <QPainter>
29 #include <QPixmapCache>
30 #include <QFile>
31 #include <KDebug>
32 #include <QMap>
33 
34 #include <stdlib.h>
35 
36 class KMahjonggTilesetMetricsData
37 {
38  public:
39  short lvloffx; // used for 3D indentation, x value
40  short lvloffy; // used for 3D indentation, y value
41  short w; // tile width ( +border +shadow)
42  short h; // tile height ( +border +shadow)
43  short fw; // face width
44  short fh; // face height
45 
46  KMahjonggTilesetMetricsData()
47  : lvloffx(0), lvloffy(0), w(0), h(0), fw(0), fh(0)
48  {}
49 };
50 
51 class KMahjonggTilesetPrivate
52 {
53  public:
54  KMahjonggTilesetPrivate() : isSVG(false), graphicsLoaded(false) {}
55  QList<QString> elementIdTable;
56  QMap<QString, QString> authorproperties;
57 
58  KMahjonggTilesetMetricsData originaldata;
59  KMahjonggTilesetMetricsData scaleddata;
60  QString filename; // cache the last file loaded to save reloading it
61  QString graphicspath;
62 
63  QSvgRenderer svg;
64  bool isSVG;
65  bool graphicsLoaded;
66 };
67 
68 // ---------------------------------------------------------
69 
70 KMahjonggTileset::KMahjonggTileset()
71  : d(new KMahjonggTilesetPrivate)
72 {
73  buildElementIdTable();
74 
75  static bool _inited = false;
76  if (_inited)
77  return;
78  KGlobal::dirs()->addResourceType("kmahjonggtileset", "data", QString::fromLatin1("kmahjongglib/tilesets/"));
79 
80  KGlobal::locale()->insertCatalog( QLatin1String( "libkmahjongglib" ));
81  _inited = true;
82 }
83 
84 // ---------------------------------------------------------
85 
86 KMahjonggTileset::~KMahjonggTileset() {
87  delete d;
88 }
89 
90 void KMahjonggTileset::updateScaleInfo(short tilew, short tileh)
91 {
92  d->scaleddata.w = tilew;
93  d->scaleddata.h = tileh;
94  double ratio = ((qreal) d->scaleddata.w) / ((qreal) d->originaldata.w);
95  d->scaleddata.lvloffx = (short) (d->originaldata.lvloffx * ratio);
96  d->scaleddata.lvloffy = (short) (d->originaldata.lvloffy * ratio);
97  d->scaleddata.fw = (short) (d->originaldata.fw * ratio);
98  d->scaleddata.fh = (short) (d->originaldata.fh * ratio);
99 }
100 
101 QSize KMahjonggTileset::preferredTileSize(const QSize & boardsize, int horizontalCells, int verticalCells)
102 {
103  //calculate our best tile size to fit the boardsize passed to us
104  qreal newtilew, newtileh, aspectratio;
105  qreal bw = boardsize.width();
106  qreal bh = boardsize.height();
107 
108  //use tileface for calculation, with one complete tile in the sum for extra margin
109  qreal fullh = (d->originaldata.fh * verticalCells) + d->originaldata.h;
110  qreal fullw = (d->originaldata.fw * horizontalCells) + d->originaldata.w;
111  qreal floatw = d->originaldata.w;
112  qreal floath = d->originaldata.h;
113 
114  if ((fullw/fullh)>(bw/bh)) {
115  //space will be left on height, use width as limit
116  aspectratio = bw/fullw;
117  } else {
118  aspectratio = bh/fullh;
119  }
120  newtilew = aspectratio * floatw;
121  newtileh = aspectratio * floath;
122  return QSize((short)newtilew, (short)newtileh);
123 }
124 
125 bool KMahjonggTileset::loadDefault()
126 {
127  QString idx = QLatin1String( "default.desktop" );
128 
129  QString tilesetPath = KStandardDirs::locate("kmahjonggtileset", idx);
130  kDebug() << "Inside LoadDefault(), located path at" << tilesetPath;
131  if (tilesetPath.isEmpty()) {
132  return false;
133  }
134  return loadTileset(tilesetPath);
135 }
136 
137 QString KMahjonggTileset::authorProperty(const QString &key) const
138 {
139  return d->authorproperties[key];
140 }
141 
142 short KMahjonggTileset::width() const
143 {
144  return d->scaleddata.w;
145 }
146 
147 short KMahjonggTileset::height() const
148 {
149  return d->scaleddata.h;
150 }
151 
152 short KMahjonggTileset::levelOffsetX() const
153 {
154  return d->scaleddata.lvloffx;
155 }
156 
157 short KMahjonggTileset::levelOffsetY() const
158 {
159  return d->scaleddata.lvloffy;
160 }
161 
162 short KMahjonggTileset::qWidth() const
163 {
164  return (short) (d->scaleddata.fw / 2.0);
165 }
166 
167 short KMahjonggTileset::qHeight() const
168 {
169  return (short) (d->scaleddata.fh / 2.0);
170 }
171 
172 QString KMahjonggTileset::path() const
173 {
174  return d->filename;
175 }
176 
177 #define kTilesetVersionFormat 1
178 
179 // ---------------------------------------------------------
180 bool KMahjonggTileset::loadTileset( const QString & tilesetPath)
181 {
182 
183  QImage qiTiles;
184  kDebug() << "Attempting to load .desktop at" << tilesetPath;
185 
186  //clear our properties map
187  d->authorproperties.clear();
188 
189  // verify if it is a valid file first and if we can open it
190  QFile tilesetfile(tilesetPath);
191  if (!tilesetfile.open(QIODevice::ReadOnly)) {
192  return (false);
193  }
194  tilesetfile.close();
195 
196  KConfig tileconfig(tilesetPath, KConfig::SimpleConfig);
197  KConfigGroup group = tileconfig.group("KMahjonggTileset");
198 
199  d->authorproperties.insert(QLatin1String( "Name" ), group.readEntry("Name"));// Returns translated data
200  d->authorproperties.insert(QLatin1String( "Author" ), group.readEntry("Author"));
201  d->authorproperties.insert(QLatin1String( "Description" ), group.readEntry("Description"));
202  d->authorproperties.insert(QLatin1String( "AuthorEmail" ), group.readEntry("AuthorEmail"));
203 
204  //Version control
205  int tileversion = group.readEntry("VersionFormat",0);
206  //Format is increased when we have incompatible changes, meaning that older clients are not able to use the remaining information safely
207  if (tileversion > kTilesetVersionFormat) {
208  return false;
209  }
210 
211  QString graphName = group.readEntry("FileName");
212 
213  d->graphicspath = KStandardDirs::locate("kmahjonggtileset", graphName);
214  kDebug() << "Using tileset at" << d->graphicspath;
215  //d->filename = graphicsPath;
216 
217  //only SVG for now
218  d->isSVG = true;
219  if (d->graphicspath.isEmpty()) return (false);
220 
221  d->originaldata.w = group.readEntry("TileWidth", 30);
222  d->originaldata.h = group.readEntry("TileHeight", 50);
223  d->originaldata.fw = group.readEntry("TileFaceWidth", 30);
224  d->originaldata.fh = group.readEntry("TileFaceHeight", 50);
225  d->originaldata.lvloffx = group.readEntry("LevelOffsetX", 10);
226  d->originaldata.lvloffy = group.readEntry("LevelOffsetY", 10);
227 
228  //client application needs to call loadGraphics()
229  d->graphicsLoaded = false;
230  d->filename = tilesetPath;
231 
232  /* if (d->isSVG) {
233  //really?
234  d->svg.load(graphicsPath);
235  if (d->svg.isValid()) {
236  d->filename = tilesetPath;
237  //invalidate our global cache
238  QPixmapCache::clear();
239 
240  d->isSVG = true;
241  reloadTileset(QSize(d->originaldata.w, d->originaldata.h));
242  } else {
243  return( false );
244  }
245  } else {
246  //TODO add support for png??
247  return false;
248  }*/
249 
250  return( true );
251 }
252 
253 // ---------------------------------------------------------
254 bool KMahjonggTileset::loadGraphics()
255 {
256  if (d->graphicsLoaded == true) return (true) ;
257  if (d->isSVG) {
258  //really?
259  d->svg.load(d->graphicspath);
260  if (d->svg.isValid()) {
261  //invalidate our global cache
262  QPixmapCache::clear();
263  d->graphicsLoaded = true;
264  reloadTileset(QSize(d->originaldata.w, d->originaldata.h));
265  } else {
266  return( false );
267  }
268  } else {
269  //TODO add support for png??
270  return false;
271  }
272 
273  return( true );
274 }
275 
276 // ---------------------------------------------------------
277 bool KMahjonggTileset::reloadTileset( const QSize & newTilesize)
278 {
279  QString tilesetPath = d->filename;
280 
281  if (QSize(d->scaleddata.w, d->scaleddata.h) == newTilesize) return false;
282 
283  if (d->isSVG) {
284  if (d->svg.isValid()) {
285  updateScaleInfo(newTilesize.width(), newTilesize.height());
286  //rendering will be done when needed, automatically using the global cache
287  } else {
288  return( false );
289  }
290  } else {
291  //TODO add support for png???
292  return false;
293  }
294 
295  return( true );
296 }
297 
298 void KMahjonggTileset::buildElementIdTable() {
299  //Build a list for faster lookup of element ids, mapped to the enumeration used by GameData and BoardWidget
300  //Unselected tiles
301  for (short idx=1; idx<=4; idx++) {
302  d->elementIdTable.append(QString::fromLatin1( "TILE_%1").arg(idx));
303  }
304  //Selected tiles
305  for (short idx=1; idx<=4; idx++) {
306  d->elementIdTable.append(QString::fromLatin1( "TILE_%1_SEL").arg(idx));
307  }
308  //now faces
309  for (short idx=1; idx<=9; idx++) {
310  d->elementIdTable.append(QString::fromLatin1( "CHARACTER_%1").arg(idx));
311  }
312  for (short idx=1; idx<=9; idx++) {
313  d->elementIdTable.append(QString::fromLatin1( "BAMBOO_%1").arg(idx));
314  }
315  for (short idx=1; idx<=9; idx++) {
316  d->elementIdTable.append(QString::fromLatin1( "ROD_%1").arg(idx));
317  }
318  for (short idx=1; idx<=4; idx++) {
319  d->elementIdTable.append(QString::fromLatin1( "SEASON_%1").arg(idx));
320  }
321  for (short idx=1; idx<=4; idx++) {
322  d->elementIdTable.append(QString::fromLatin1( "WIND_%1").arg(idx));
323  }
324  for (short idx=1; idx<=3; idx++) {
325  d->elementIdTable.append(QString::fromLatin1( "DRAGON_%1").arg(idx));
326  }
327  for (short idx=1; idx<=4; idx++) {
328  d->elementIdTable.append(QString::fromLatin1( "FLOWER_%1").arg(idx));
329  }
330 }
331 
332 QString KMahjonggTileset::pixmapCacheNameFromElementId(const QString & elementid) {
333  return authorProperty(QLatin1String( "Name" ))+ elementid + QString::fromLatin1( "W%1H%2").arg(d->scaleddata.w).arg(d->scaleddata.h);
334 }
335 
336 QPixmap KMahjonggTileset::renderElement(short width, short height, const QString & elementid) {
337  //kDebug() << "render element" << elementid << width << height;
338  QImage qiRend(QSize(width, height),QImage::Format_ARGB32_Premultiplied);
339  qiRend.fill(0);
340 
341  if (d->svg.isValid()) {
342  QPainter p(&qiRend);
343  d->svg.render(&p, elementid);
344  }
345  return QPixmap::fromImage(qiRend);
346 }
347 
348 QPixmap KMahjonggTileset::selectedTile(int num) {
349  QPixmap pm;
350  QString elemId = d->elementIdTable.at(num+4);//selected offset in our idtable;
351  if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), &pm)) {
352  //use tile size
353  pm = renderElement(d->scaleddata.w, d->scaleddata.h, elemId);
354  QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
355  }
356  return pm;
357 }
358 
359 QPixmap KMahjonggTileset::unselectedTile(int num) {
360  QPixmap pm;
361  QString elemId = d->elementIdTable.at(num);
362  if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), &pm)) {
363  //use tile size
364  pm = renderElement(d->scaleddata.w, d->scaleddata.h, elemId);
365  QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
366  }
367  return pm;
368 }
369 
370 QPixmap KMahjonggTileset::tileface(int num) {
371  QPixmap pm;
372  if ((num + 8) >= d->elementIdTable.count()) {
373  kDebug() << "Client asked for invalid tileface id";
374  return pm;
375  }
376 
377  QString elemId = d->elementIdTable.at(num + 8);//tileface offset in our idtable;
378  if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), &pm)) {
379  //use face size
380  pm = renderElement(d->scaleddata.fw, d->scaleddata.fh, elemId);
381  QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
382  }
383  return pm;
384 }
385 
KMahjonggTileset::unselectedTile
QPixmap unselectedTile(int num)
Definition: kmahjonggtileset.cpp:359
QSize::width
int width() const
KMahjonggTileset::buildElementIdTable
void buildElementIdTable(void)
Definition: kmahjonggtileset.cpp:298
KMahjonggTileset::qHeight
short qHeight() const
Definition: kmahjonggtileset.cpp:167
KMahjonggTileset::preferredTileSize
QSize preferredTileSize(const QSize &boardsize, int horizontalCells, int verticalCells)
Definition: kmahjonggtileset.cpp:101
KMahjonggTileset::selectedTile
QPixmap selectedTile(int num)
Definition: kmahjonggtileset.cpp:348
KMahjonggTileset::levelOffsetX
short levelOffsetX() const
Definition: kmahjonggtileset.cpp:152
KMahjonggTileset::KMahjonggTileset
KMahjonggTileset()
Definition: kmahjonggtileset.cpp:70
QMap< QString, QString >
QSvgRenderer
QPixmap::fromImage
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
KMahjonggTileset::loadDefault
bool loadDefault()
Definition: kmahjonggtileset.cpp:125
KMahjonggTileset::~KMahjonggTileset
~KMahjonggTileset()
Definition: kmahjonggtileset.cpp:86
QFile
KMahjonggTileset::path
QString path() const
Definition: kmahjonggtileset.cpp:172
KMahjonggTileset::tileface
QPixmap tileface(int num)
Definition: kmahjonggtileset.cpp:370
QImage::fill
void fill(uint pixelValue)
kTilesetVersionFormat
#define kTilesetVersionFormat
Definition: kmahjonggtileset.cpp:177
KMahjonggTileset::levelOffsetY
short levelOffsetY() const
Definition: kmahjonggtileset.cpp:157
KMahjonggTileset::loadGraphics
bool loadGraphics()
Definition: kmahjonggtileset.cpp:254
KMahjonggTileset::width
short width() const
Definition: kmahjonggtileset.cpp:142
QPainter
QString::isEmpty
bool isEmpty() const
KMahjonggTileset::reloadTileset
bool reloadTileset(const QSize &newTilesize)
Definition: kmahjonggtileset.cpp:277
QPixmapCache::clear
void clear()
KMahjonggTileset::updateScaleInfo
void updateScaleInfo(short tilew, short tileh)
Definition: kmahjonggtileset.cpp:90
QString
QList< QString >
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QPixmap
KMahjonggTileset::qWidth
short qWidth() const
Definition: kmahjonggtileset.cpp:162
QSize
KMahjonggTileset::loadTileset
bool loadTileset(const QString &tilesetPath)
Definition: kmahjonggtileset.cpp:180
QFile::close
virtual void close()
QImage
KMahjonggTileset::authorProperty
QString authorProperty(const QString &key) const
Definition: kmahjonggtileset.cpp:137
QLatin1String
QPixmapCache::find
QPixmap * find(const QString &key)
QSize::height
int height() const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QPixmapCache::insert
bool insert(const QString &key, const QPixmap &pixmap)
KMahjonggTileset::pixmapCacheNameFromElementId
QString pixmapCacheNameFromElementId(const QString &elementid)
Definition: kmahjonggtileset.cpp:332
kmahjonggtileset.h
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KMahjonggTileset::height
short height() const
Definition: kmahjonggtileset.cpp:147
KMahjonggTileset::renderElement
QPixmap renderElement(short width, short height, const QString &elementid)
Definition: kmahjonggtileset.cpp:336
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkmahjongg

Skip menu "libkmahjongg"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal