00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kmahjonggtileset.h"
00021
00022 #include <klocale.h>
00023 #include <kconfig.h>
00024 #include <kconfiggroup.h>
00025 #include <qimage.h>
00026 #include <kstandarddirs.h>
00027 #include <ksvgrenderer.h>
00028 #include <QPainter>
00029 #include <QPixmapCache>
00030 #include <QFile>
00031 #include <KDebug>
00032 #include <QMap>
00033
00034 #include <stdlib.h>
00035
00036 class KMahjonggTilesetMetricsData
00037 {
00038 public:
00039 short lvloffx;
00040 short lvloffy;
00041 short w;
00042 short h;
00043 short fw;
00044 short fh;
00045
00046 KMahjonggTilesetMetricsData()
00047 : lvloffx(0), lvloffy(0), w(0), h(0), fw(0), fh(0)
00048 {}
00049 };
00050
00051 class KMahjonggTilesetPrivate
00052 {
00053 public:
00054 KMahjonggTilesetPrivate() : isSVG(false), graphicsLoaded(false) {}
00055 QList<QString> elementIdTable;
00056 QMap<QString, QString> authorproperties;
00057
00058 KMahjonggTilesetMetricsData originaldata;
00059 KMahjonggTilesetMetricsData scaleddata;
00060 QString filename;
00061 QString graphicspath;
00062
00063 KSvgRenderer svg;
00064 bool isSVG;
00065 bool graphicsLoaded;
00066 };
00067
00068
00069
00070 KMahjonggTileset::KMahjonggTileset()
00071 : d(new KMahjonggTilesetPrivate)
00072 {
00073 buildElementIdTable();
00074
00075 static bool _inited = false;
00076 if (_inited)
00077 return;
00078 KGlobal::dirs()->addResourceType("kmahjonggtileset", "data", QString::fromLatin1("kmahjongglib/tilesets/"));
00079
00080 KGlobal::locale()->insertCatalog("libkmahjongglib");
00081 _inited = true;
00082 }
00083
00084
00085
00086 KMahjonggTileset::~KMahjonggTileset() {
00087 delete d;
00088 }
00089
00090 void KMahjonggTileset::updateScaleInfo(short tilew, short tileh)
00091 {
00092 d->scaleddata.w = tilew;
00093 d->scaleddata.h = tileh;
00094 double ratio = ((qreal) d->scaleddata.w) / ((qreal) d->originaldata.w);
00095 d->scaleddata.lvloffx = (short) (d->originaldata.lvloffx * ratio);
00096 d->scaleddata.lvloffy = (short) (d->originaldata.lvloffy * ratio);
00097 d->scaleddata.fw = (short) (d->originaldata.fw * ratio);
00098 d->scaleddata.fh = (short) (d->originaldata.fh * ratio);
00099 }
00100
00101 QSize KMahjonggTileset::preferredTileSize(const QSize & boardsize, int horizontalCells, int verticalCells)
00102 {
00103
00104 qreal newtilew, newtileh, aspectratio;
00105 qreal bw = boardsize.width();
00106 qreal bh = boardsize.height();
00107
00108
00109 qreal fullh = (d->originaldata.fh * verticalCells) + d->originaldata.h;
00110 qreal fullw = (d->originaldata.fw * horizontalCells) + d->originaldata.w;
00111 qreal floatw = d->originaldata.w;
00112 qreal floath = d->originaldata.h;
00113
00114 if ((fullw/fullh)>(bw/bh)) {
00115
00116 aspectratio = bw/fullw;
00117 } else {
00118 aspectratio = bh/fullh;
00119 }
00120 newtilew = aspectratio * floatw;
00121 newtileh = aspectratio * floath;
00122 return QSize((short)newtilew, (short)newtileh);
00123 }
00124
00125 bool KMahjonggTileset::loadDefault()
00126 {
00127 QString idx = "default.desktop";
00128
00129 QString tilesetPath = KStandardDirs::locate("kmahjonggtileset", idx);
00130 kDebug() << "Inside LoadDefault(), located path at" << tilesetPath;
00131 if (tilesetPath.isEmpty()) {
00132 return false;
00133 }
00134 return loadTileset(tilesetPath);
00135 }
00136
00137 QString KMahjonggTileset::authorProperty(const QString &key) const
00138 {
00139 return d->authorproperties[key];
00140 }
00141
00142 short KMahjonggTileset::width() const
00143 {
00144 return d->scaleddata.w;
00145 }
00146
00147 short KMahjonggTileset::height() const
00148 {
00149 return d->scaleddata.h;
00150 }
00151
00152 short KMahjonggTileset::levelOffsetX() const
00153 {
00154 return d->scaleddata.lvloffx;
00155 }
00156
00157 short KMahjonggTileset::levelOffsetY() const
00158 {
00159 return d->scaleddata.lvloffy;
00160 }
00161
00162
00163 short KMahjonggTileset::qWidth() const
00164 {
00165 return (short) (d->scaleddata.fw / 2.0);
00166 }
00167
00168 short KMahjonggTileset::qHeight() const
00169 {
00170 return (short) (d->scaleddata.fh / 2.0);
00171 }
00172
00173 QString KMahjonggTileset::path() const
00174 {
00175 return d->filename;
00176 }
00177
00178 #define kTilesetVersionFormat 1
00179
00180
00181 bool KMahjonggTileset::loadTileset( const QString & tilesetPath)
00182 {
00183
00184 QImage qiTiles;
00185 kDebug() << "Attempting to load .desktop at" << tilesetPath;
00186
00187
00188 d->authorproperties.clear();
00189
00190
00191 QFile tilesetfile(tilesetPath);
00192 if (!tilesetfile.open(QIODevice::ReadOnly)) {
00193 return (false);
00194 }
00195 tilesetfile.close();
00196
00197 KConfig tileconfig(tilesetPath, KConfig::SimpleConfig);
00198 KConfigGroup group = tileconfig.group("KMahjonggTileset");
00199
00200 d->authorproperties.insert("Name", group.readEntry("Name"));
00201 d->authorproperties.insert("Author", group.readEntry("Author"));
00202 d->authorproperties.insert("Description", group.readEntry("Description"));
00203 d->authorproperties.insert("AuthorEmail", group.readEntry("AuthorEmail"));
00204
00205
00206 int tileversion = group.readEntry("VersionFormat",0);
00207
00208 if (tileversion > kTilesetVersionFormat) {
00209 return false;
00210 }
00211
00212 QString graphName = group.readEntry("FileName");
00213
00214 d->graphicspath = KStandardDirs::locate("kmahjonggtileset", graphName);
00215 kDebug() << "Using tileset at" << d->graphicspath;
00216
00217
00218
00219 d->isSVG = true;
00220 if (d->graphicspath.isEmpty()) return (false);
00221
00222 d->originaldata.w = group.readEntry("TileWidth", 30);
00223 d->originaldata.h = group.readEntry("TileHeight", 50);
00224 d->originaldata.fw = group.readEntry("TileFaceWidth", 30);
00225 d->originaldata.fh = group.readEntry("TileFaceHeight", 50);
00226 d->originaldata.lvloffx = group.readEntry("LevelOffsetX", 10);
00227 d->originaldata.lvloffy = group.readEntry("LevelOffsetY", 10);
00228
00229
00230 d->graphicsLoaded = false;
00231 d->filename = tilesetPath;
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 return( true );
00252 }
00253
00254
00255 bool KMahjonggTileset::loadGraphics()
00256 {
00257 if (d->graphicsLoaded == true) return (true) ;
00258 if (d->isSVG) {
00259
00260 d->svg.load(d->graphicspath);
00261 if (d->svg.isValid()) {
00262
00263 QPixmapCache::clear();
00264 d->graphicsLoaded = true;
00265 reloadTileset(QSize(d->originaldata.w, d->originaldata.h));
00266 } else {
00267 return( false );
00268 }
00269 } else {
00270
00271 return false;
00272 }
00273
00274 return( true );
00275 }
00276
00277
00278 bool KMahjonggTileset::reloadTileset( const QSize & newTilesize)
00279 {
00280 QString tilesetPath = d->filename;
00281
00282 if (QSize(d->scaleddata.w, d->scaleddata.h) == newTilesize) return false;
00283
00284 if (d->isSVG) {
00285 if (d->svg.isValid()) {
00286 updateScaleInfo(newTilesize.width(), newTilesize.height());
00287
00288 } else {
00289 return( false );
00290 }
00291 } else {
00292
00293 return false;
00294 }
00295
00296 return( true );
00297 }
00298
00299 void KMahjonggTileset::buildElementIdTable() {
00300
00301
00302 for (short idx=1; idx<=4; idx++) {
00303 d->elementIdTable.append(QString("TILE_%1").arg(idx));
00304 }
00305
00306 for (short idx=1; idx<=4; idx++) {
00307 d->elementIdTable.append(QString("TILE_%1_SEL").arg(idx));
00308 }
00309
00310 for (short idx=1; idx<=9; idx++) {
00311 d->elementIdTable.append(QString("CHARACTER_%1").arg(idx));
00312 }
00313 for (short idx=1; idx<=9; idx++) {
00314 d->elementIdTable.append(QString("BAMBOO_%1").arg(idx));
00315 }
00316 for (short idx=1; idx<=9; idx++) {
00317 d->elementIdTable.append(QString("ROD_%1").arg(idx));
00318 }
00319 for (short idx=1; idx<=4; idx++) {
00320 d->elementIdTable.append(QString("SEASON_%1").arg(idx));
00321 }
00322 for (short idx=1; idx<=4; idx++) {
00323 d->elementIdTable.append(QString("WIND_%1").arg(idx));
00324 }
00325 for (short idx=1; idx<=3; idx++) {
00326 d->elementIdTable.append(QString("DRAGON_%1").arg(idx));
00327 }
00328 for (short idx=1; idx<=4; idx++) {
00329 d->elementIdTable.append(QString("FLOWER_%1").arg(idx));
00330 }
00331 }
00332
00333 QString KMahjonggTileset::pixmapCacheNameFromElementId(const QString & elementid) {
00334 return authorProperty("Name")+ elementid + QString("W%1H%2").arg(d->scaleddata.w).arg(d->scaleddata.h);
00335 }
00336
00337 QPixmap KMahjonggTileset::renderElement(short width, short height, const QString & elementid) {
00338
00339 QImage qiRend(QSize(width, height),QImage::Format_ARGB32_Premultiplied);
00340 qiRend.fill(0);
00341
00342 if (d->svg.isValid()) {
00343 QPainter p(&qiRend);
00344 d->svg.render(&p, elementid);
00345 }
00346 return QPixmap::fromImage(qiRend);
00347 }
00348
00349 QPixmap KMahjonggTileset::selectedTile(int num) {
00350 QPixmap pm;
00351 QString elemId = d->elementIdTable.at(num+4);
00352 if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), pm)) {
00353
00354 pm = renderElement(d->scaleddata.w, d->scaleddata.h, elemId);
00355 QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
00356 }
00357 return pm;
00358 }
00359
00360 QPixmap KMahjonggTileset::unselectedTile(int num) {
00361 QPixmap pm;
00362 QString elemId = d->elementIdTable.at(num);
00363 if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), pm)) {
00364
00365 pm = renderElement(d->scaleddata.w, d->scaleddata.h, elemId);
00366 QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
00367 }
00368 return pm;
00369 }
00370
00371 QPixmap KMahjonggTileset::tileface(int num) {
00372 QPixmap pm;
00373 QString elemId = d->elementIdTable.at(num + 8);
00374 if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), pm)) {
00375
00376 pm = renderElement(d->scaleddata.fw, d->scaleddata.fh, elemId);
00377 QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
00378 }
00379 return pm;
00380 }
00381
00382