File indexing completed on 2024-05-19 09:43:14
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 ®ion) 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 }