• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkmahjongg

kmahjonggtileset.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 1997 Mathias Mueller   <in5y158@public.uni-hamburg.de>
00003     Copyright (C) 2006 Mauricio Piacentini  <mauricio@tabuleiro.com>
00004 
00005     Libkmahjongg is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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;   // used for 3D indentation, x value
00040     short lvloffy;   // used for 3D indentation, y value
00041     short w;    // tile width ( +border +shadow)
00042     short h;    // tile height ( +border +shadow)
00043     short fw;   // face width
00044     short fh;   // face height
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;  // cache the last file loaded to save reloading it
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     //calculate our best tile size to fit the boardsize passed to us
00104     qreal newtilew, newtileh, aspectratio;
00105     qreal bw = boardsize.width();
00106     qreal bh = boardsize.height();
00107 
00108     //use tileface for calculation, with one complete tile in the sum for extra margin
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         //space will be left on height, use width as limit
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     //clear our properties map
00188     d->authorproperties.clear();
00189 
00190     // verify if it is a valid file first and if we can open it
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"));// Returns translated data
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     //Version control
00206     int tileversion = group.readEntry("VersionFormat",0);
00207     //Format is increased when we have incompatible changes, meaning that older clients are not able to use the remaining information safely
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     //d->filename = graphicsPath;
00217 
00218     //only SVG for now
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     //client application needs to call loadGraphics()
00230     d->graphicsLoaded = false;
00231     d->filename = tilesetPath;
00232 
00233  /*   if (d->isSVG) {
00234     //really?
00235     d->svg.load(graphicsPath);
00236     if (d->svg.isValid()) {
00237         d->filename = tilesetPath;
00238         //invalidate our global cache
00239         QPixmapCache::clear();
00240 
00241         d->isSVG = true;
00242         reloadTileset(QSize(d->originaldata.w, d->originaldata.h));
00243         } else {
00244             return( false );
00245         }
00246     } else {
00247     //TODO add support for png??
00248     return false;
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     //really?
00260     d->svg.load(d->graphicspath);
00261     if (d->svg.isValid()) {
00262       //invalidate our global cache
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     //TODO add support for png??
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         //rendering will be done when needed, automatically using the global cache
00288         } else {
00289             return( false );
00290     }
00291     } else {
00292     //TODO add support for png???
00293     return false;
00294     }
00295 
00296     return( true );
00297 }
00298 
00299 void KMahjonggTileset::buildElementIdTable() {
00300     //Build a list for faster lookup of element ids, mapped to the enumeration used by GameData and BoardWidget
00301     //Unselected tiles
00302     for (short idx=1; idx<=4; idx++) {
00303         d->elementIdTable.append(QString("TILE_%1").arg(idx));
00304     }
00305     //Selected tiles
00306     for (short idx=1; idx<=4; idx++) {
00307         d->elementIdTable.append(QString("TILE_%1_SEL").arg(idx));
00308     }
00309     //now faces
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 //kDebug() << "render element" << elementid << width << height;
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);//selected offset in our idtable;
00352     if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), pm)) {
00353         //use tile size
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         //use tile size
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);//tileface offset in our idtable;
00374     if (!QPixmapCache::find(pixmapCacheNameFromElementId(elemId), pm)) {
00375         //use face size
00376             pm = renderElement(d->scaleddata.fw, d->scaleddata.fh, elemId);
00377             QPixmapCache::insert(pixmapCacheNameFromElementId(elemId), pm);
00378     }
00379     return pm;
00380 }
00381 
00382 

libkmahjongg

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

API Reference

Skip menu "API Reference"
  • kblackbox
  • kgoldrunner
  • kmahjongg
  • ksquares
  • libkdegames
  •   highscore
  •   kgame
  •   kggzgames
  •   kggzmod
  •   kggznet
  • libkmahjongg
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal