File indexing completed on 2024-04-28 17:04:39

0001 /*****************************************************************************
0002  *   Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>         *
0003  *   Copyright 2008 Long Huynh Huu <long.upcase@gmail.com>                   *
0004  *   Copyright 2008 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0005  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0006  *                                                                           *
0007  *   This program is free software; you can redistribute it and/or modify    *
0008  *   it under the terms of the GNU Lesser General Public License as          *
0009  *   published by the Free Software Foundation; either version 2.1 of the    *
0010  *   License, or (at your option) version 3, or any later version accepted   *
0011  *   by the membership of KDE e.V. (or its successor approved by the         *
0012  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0013  *   Section 6 of version 3 of the license.                                  *
0014  *                                                                           *
0015  *   This program is distributed in the hope that it will be useful,         *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0018  *   Lesser General Public License for more details.                         *
0019  *                                                                           *
0020  *   You should have received a copy of the GNU Lesser General Public        *
0021  *   License along with this library. If not,                                *
0022  *   see <http://www.gnu.org/licenses/>.                                     *
0023  *****************************************************************************/
0024 
0025 #include "tileset.h"
0026 
0027 #include <kdeversion.h>
0028 
0029 #include <QPainter>
0030 
0031 void
0032 TileSet::initPixmap(int s, const QPixmap &pix, int w, int h,
0033                     const QRect &region)
0034 {
0035     if (w != region.width() || h != region.height()) {
0036         QPixmap tile = pix.copy(region);
0037         _pixmap[s] = QPixmap(w, h);
0038         _pixmap[s].fill(QColor(0, 0, 0, 0));
0039         QPainter p(&_pixmap[s]);
0040         p.drawTiledPixmap(0, 0, w, h, tile);
0041     } else {
0042         _pixmap[s] = pix.copy(region);
0043     }
0044 }
0045 
0046 TileSet::TileSet()
0047     : _w1(0), _h1(0), _w3(0), _h3(0)
0048 {
0049 }
0050 
0051 TileSet::TileSet(const QPixmap &pix, int w1, int h1, int w2, int h2)
0052     : _w1(w1), _h1(h1), _w3(0), _h3(0)
0053 {
0054     if (pix.isNull())
0055         return;
0056 
0057     _w3 = pix.width() - (w1 + w2);
0058     _h3 = pix.height() - (h1 + h2);
0059     int w = w2;
0060     while (w < 32 && w2 > 0)
0061         w += w2;
0062     int h = h2;
0063     while (h < 32 && h2 > 0)
0064         h += h2;
0065 
0066     // initialise pixmap array
0067     _pixmap.resize(9);
0068     initPixmap(0, pix, _w1, _h1, QRect(0, 0, _w1, _h1));
0069     initPixmap(1, pix, w, _h1, QRect(_w1, 0, w2, _h1));
0070     initPixmap(2, pix, _w3, _h1, QRect(_w1 + w2, 0, _w3, _h1));
0071     initPixmap(3, pix, _w1, h, QRect(0, _h1, _w1, h2));
0072     initPixmap(4, pix, w, h, QRect(_w1, _h1, w2, h2));
0073     initPixmap(5, pix, _w3, h, QRect(_w1 + w2, _h1, _w3, h2));
0074     initPixmap(6, pix, _w1, _h3, QRect(0, _h1 + h2, _w1, _h3));
0075     initPixmap(7, pix, w, _h3, QRect(_w1, _h1 + h2, w2, _h3));
0076     initPixmap(8, pix, _w3, _h3, QRect(_w1 + w2, _h1 + h2, _w3, _h3));
0077 }
0078 
0079 TileSet::TileSet(const QPixmap &pix, int w1, int h1, int w3, int h3,
0080                  int x1, int y1, int w2, int h2)
0081     : _w1(w1), _h1(h1), _w3(w3), _h3(h3)
0082 {
0083     if (pix.isNull())
0084         return;
0085 
0086     int x2 = pix.width() - _w3;
0087     int y2 = pix.height() - _h3;
0088     int w = w2;
0089     while (w < 32 && w2 > 0)
0090         w += w2;
0091     int h = h2;
0092     while (h < 32 && h2 > 0)
0093         h += h2;
0094 
0095     // initialise pixmap array
0096     _pixmap.resize(9);
0097     initPixmap(0, pix, _w1, _h1, QRect(0, 0, _w1, _h1));
0098     initPixmap(1, pix, w, _h1, QRect(x1, 0, w2, _h1));
0099     initPixmap(2, pix, _w3, _h1, QRect(x2, 0, _w3, _h1));
0100     initPixmap(3, pix, _w1, h, QRect(0, y1, _w1, h2));
0101     initPixmap(4, pix, w, h, QRect(x1, y1, w2, h2));
0102     initPixmap(5, pix, _w3, h, QRect(x2, y1, _w3, h2));
0103     initPixmap(6, pix, _w1, _h3, QRect(0, y2, _w1, _h3));
0104     initPixmap(7, pix, w, _h3, QRect(x1, y2, w2, _h3));
0105     initPixmap(8, pix, _w3, _h3, QRect(x2, y2, _w3, _h3));
0106 }
0107 
0108 inline bool
0109 bits(TileSet::Tiles flags, TileSet::Tiles testFlags)
0110 {
0111     return (flags & testFlags) == testFlags;
0112 }
0113 
0114 void
0115 TileSet::render(const QRect &r, QPainter *p, Tiles t) const
0116 {
0117     // check initialization
0118     if(_pixmap.size() < 9)
0119         return;
0120 
0121     int x0, y0, w, h;
0122     r.getRect(&x0, &y0, &w, &h);
0123 
0124     // calculate pixmaps widths
0125     qreal wRatio(qreal(_w1) / qreal(_w1 + _w3));
0126     int wLeft = (t&Right) ? qMin(_w1, int(w * wRatio)) : _w1;
0127     int wRight = (t&Left) ? qMin(_w3, int(w * (1.0 - wRatio))) : _w3;
0128 
0129     // calculate pixmap heights
0130     qreal hRatio(qreal(_h1) / qreal(_h1 + _h3));
0131     int hTop = (t & Bottom) ? qMin(_h1, int(h * hRatio)) : _h1;
0132     int hBottom = (t & Top) ? qMin(_h3, int(h * (1.0 - hRatio))) : _h3;
0133 
0134     // calculate corner locations
0135 
0136     // maybe one should make the following two lines depend on
0137     // what tilesets are selected. Would be more logical, but would
0138     // probably break code all over the place ...
0139     w -= wLeft + wRight;
0140     h -= hTop + hBottom;
0141     int x1 = x0 + wLeft;
0142     int x2 = x1 + w;
0143     int y1 = y0 + hTop;
0144     int y2 = y1 + h;
0145 
0146     // corner
0147     if (bits(t, Top | Left))
0148         p->drawPixmap(x0, y0, _pixmap.at(0), 0, 0, wLeft, hTop);
0149     if (bits(t, Top | Right))
0150         p->drawPixmap(x2, y0, _pixmap.at(2), _w3 - wRight, 0, wRight, hTop);
0151     if (bits(t, Bottom | Left))
0152         p->drawPixmap(x0, y2, _pixmap.at(6), 0, _h3 - hBottom, wLeft, hBottom);
0153     if (bits(t, Bottom | Right))
0154         p->drawPixmap(x2, y2, _pixmap.at(8), _w3 - wRight, _h3 - hBottom,
0155                       wRight, hBottom);
0156 
0157     // top and bottom
0158     if (w > 0) {
0159         if (t & Top)
0160             p->drawTiledPixmap(x1, y0, w, hTop, _pixmap.at(1));
0161         if (t & Bottom) {
0162             p->drawTiledPixmap(x1, y2, w, hBottom, _pixmap.at(7),
0163                                0, _h3 - hBottom);
0164         }
0165     }
0166 
0167     // left and right
0168     if (h > 0) {
0169         if (t & Left)
0170             p->drawTiledPixmap(x0, y1, wLeft, h, _pixmap.at(3));
0171         if (t & Right) {
0172             p->drawTiledPixmap(x2, y1, wRight, h, _pixmap.at(5),
0173                                _w3 - wRight, 0);
0174         }
0175     }
0176 
0177     // center
0178     if ((t & Center) && h > 0 && w > 0) {
0179         p->drawTiledPixmap(x1, y1, w, h, _pixmap.at(4));
0180     }
0181 }