File indexing completed on 2021-12-21 12:50:20
0001 /* 0002 * ksokoban - a Sokoban game by KDE 0003 * Copyright (C) 1998 Anders Widell <awl@hem.passagen.se> 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program; if not, write to the Free Software 0017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0018 */ 0019 0020 #include <assert.h> 0021 #include <QPainter> 0022 #include <QPixmap> 0023 #include <QImage> 0024 #include <QColor> 0025 0026 #include "ImageData.h" 0027 0028 ImageData::ImageData() : floor_(10,10), indexSize_(0), size_(0), halfSize_(0) { 0029 random.seed(QRandomGenerator::global()->generate()); 0030 QPainter paint(&floor_); 0031 paint.fillRect(0,0,10,10, QColor(0x66,0x66,0x66, 255)); 0032 } 0033 0034 ImageData::~ImageData() { 0035 } 0036 0037 void 0038 ImageData::expandIndex(int size) { 0039 size++; 0040 assert(size < 2500); 0041 0042 upperLargeIndex_.resize(size); 0043 lowerLargeIndex_.resize(size); 0044 leftSmallIndex_.resize(size); 0045 rightSmallIndex_.resize(size); 0046 0047 for (int i=indexSize_; i<size; i++) { 0048 upperLargeIndex_[i] = random.bounded(LARGE_STONES); 0049 lowerLargeIndex_[i] = random.bounded(LARGE_STONES); 0050 leftSmallIndex_[i] = random.bounded(SMALL_STONES); 0051 rightSmallIndex_[i] = random.bounded(SMALL_STONES); 0052 } 0053 0054 indexSize_ = size; 0055 } 0056 0057 const QPixmap & 0058 ImageData::upperLarge(int index) { 0059 assert(index >= 0); 0060 if (indexSize_ <= index) expandIndex(index); 0061 return largeStone_xpm_[(unsigned char)upperLargeIndex_[index]]; 0062 } 0063 0064 const QPixmap & 0065 ImageData::lowerLarge(int index) { 0066 assert(index >= 0); 0067 if (indexSize_ <= index) expandIndex(index); 0068 return largeStone_xpm_[(unsigned char)lowerLargeIndex_[index]]; 0069 } 0070 0071 const QPixmap & 0072 ImageData::leftSmall(int index) { 0073 assert(index >= 0); 0074 if (indexSize_ <= index) expandIndex(index); 0075 return smallStone_xpm_[(unsigned char)leftSmallIndex_[index]]; 0076 } 0077 0078 const QPixmap & 0079 ImageData::rightSmall(int index) { 0080 assert(index >= 0); 0081 if (indexSize_ <= index) expandIndex(index); 0082 return smallStone_xpm_[(unsigned char)rightSmallIndex_[index]]; 0083 } 0084 0085 int 0086 ImageData::resize(int size) { 0087 assert(size > 0); 0088 size &= ~1u; 0089 if (size == size_) return size; 0090 0091 size_ = size; 0092 halfSize_ = size/2; 0093 0094 for (int i=0; i<SMALL_STONES; i++) { 0095 image2pixmap(images_[i].scaled(halfSize_, halfSize_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), smallStone_xpm_[i]); 0096 // smallStone_xpm_[i].convertFromImage(images_[i].smoothScale(halfSize_, halfSize_), QPixmap::ColorOnly|QPixmap::DiffuseDither|QPixmap::DiffuseAlphaDither|QPixmap::AvoidDither); 0097 } 0098 0099 for (int i=0; i<LARGE_STONES; i++) { 0100 image2pixmap(images_[SMALL_STONES+i].scaled(size_, halfSize_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), largeStone_xpm_[i]); 0101 // largeStone_xpm_[i].convertFromImage(images_[SMALL_STONES+i].smoothScale(size_, halfSize_) , QPixmap::ColorOnly|QPixmap::DiffuseDither|QPixmap::DiffuseAlphaDither|QPixmap::AvoidDither); 0102 } 0103 0104 objectImg_ = images_[SMALL_STONES+LARGE_STONES].scaled(size_, size_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 0105 0106 // Use copy() because if the size is not changed, smoothScale is not 0107 // really a copy 0108 // Use {[Geometry] height=753 width=781} to test 0109 0110 if (objectImg_.width() == size_) objectImg_ = objectImg_.copy(); 0111 0112 image2pixmap(objectImg_, otherPixmaps_[0], false); 0113 brighten(objectImg_); 0114 image2pixmap(objectImg_, brightObject_, false); 0115 0116 QImage img = images_[SMALL_STONES+LARGE_STONES+1].scaled(size_, size_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 0117 if (img.width() == size_) img = img.copy(); 0118 0119 image2pixmap(img, otherPixmaps_[1], false); 0120 brighten(img); 0121 image2pixmap(img, brightTreasure_, false); 0122 0123 for (int i=2; i<OTHER_IMAGES; i++) { 0124 image2pixmap(images_[SMALL_STONES+LARGE_STONES+i].scaled(size_, size_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), otherPixmaps_[i]); 0125 // otherPixmaps_[i].convertFromImage(images_[SMALL_STONES+LARGE_STONES+i].smoothScale(size_, size_), QPixmap::ColorOnly|QPixmap::OrderedDither|QPixmap::OrderedAlphaDither|QPixmap::AvoidDither); 0126 } 0127 floor_ = floor_.scaled(size_, size_); 0128 return size_; 0129 } 0130 0131 // Don't use DiffuseDither for the objects on the "floor" since 0132 // it gives spurious dots on the floor around them 0133 0134 void 0135 ImageData::image2pixmap(const QImage &img, QPixmap& xpm, bool diffuse) { 0136 xpm = QPixmap::fromImage(img, 0137 (diffuse ? 0138 (Qt::DiffuseDither|Qt::DiffuseAlphaDither) : 0139 (Qt::OrderedDither|Qt::OrderedAlphaDither))| 0140 Qt::ColorOnly|Qt::AvoidDither); 0141 } 0142 0143 void 0144 ImageData::brighten(QImage& img) { 0145 assert(img.depth() == 32); 0146 0147 for (int y=0; y<img.height(); y++) { 0148 for (int x=0; x<img.width(); x++) { 0149 QRgb rgb = img.pixel(x, y); 0150 int r = qRed(rgb); 0151 int g = qGreen(rgb); 0152 int b = qBlue(rgb); 0153 0154 if (r > g && r > b) { 0155 // only modify redish pixels 0156 0157 QColor col(r, g, b); 0158 QColor lcol = col.lighter(130); 0159 0160 img.setPixel(x, y, lcol.rgb()); 0161 } 0162 } 0163 } 0164 } 0165 0166 void 0167 ImageData::wall(QPainter &p, int x, int y, int index, bool left, bool right) { 0168 if (left) p.drawPixmap(x, y, upperLarge(index-1), halfSize_, 0, -1, -1); 0169 else p.drawPixmap(x, y, leftSmall(index)); 0170 0171 if (right) p.drawPixmap(x+halfSize_, y, upperLarge(index), 0, 0, halfSize_, -1); 0172 else p.drawPixmap(x+halfSize_, y, rightSmall(index)); 0173 0174 p.drawPixmap(x, y+halfSize_, lowerLarge(index)); 0175 } 0176 0177 void 0178 ImageData::floor(QPainter &p, int x, int y) { 0179 //p.eraseRect(x, y, size_, size_); 0180 p.drawPixmap(x, y, floor_); 0181 } 0182 0183 void 0184 ImageData::goal(QPainter &p, int x, int y) { 0185 p.drawPixmap(x, y, otherPixmaps_[2]); 0186 } 0187 0188 void 0189 ImageData::man(QPainter &p, int x, int y) { 0190 p.drawPixmap(x, y, otherPixmaps_[3]); 0191 } 0192 0193 void 0194 ImageData::object(QPainter &p, int x, int y) { 0195 p.drawPixmap(x, y, otherPixmaps_[0]); 0196 } 0197 0198 void 0199 ImageData::saveman(QPainter &p, int x, int y) { 0200 p.drawPixmap(x, y, otherPixmaps_[4]); 0201 } 0202 0203 void 0204 ImageData::treasure(QPainter &p, int x, int y) { 0205 p.drawPixmap(x, y, otherPixmaps_[1]); 0206 } 0207 0208 void 0209 ImageData::brightObject(QPainter &p, int x, int y) { 0210 p.drawPixmap(x, y, brightObject_); 0211 } 0212 0213 void 0214 ImageData::brightTreasure(QPainter &p, int x, int y) { 0215 p.drawPixmap(x, y, brightTreasure_); 0216 }