You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
7.0 KiB
175 lines
7.0 KiB
/* |
|
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> |
|
* |
|
* SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
#include "breezetileset.h" |
|
|
|
#include <QPainter> |
|
|
|
namespace Breeze |
|
{ |
|
|
|
//___________________________________________________________ |
|
inline bool bits(TileSet::Tiles flags, TileSet::Tiles testFlags) |
|
{ return (flags & testFlags) == testFlags; } |
|
|
|
//______________________________________________________________________________________ |
|
inline qreal devicePixelRatio( const QPixmap& pixmap ) |
|
{ |
|
return pixmap.devicePixelRatio(); |
|
} |
|
|
|
//______________________________________________________________________________________ |
|
inline void setDevicePixelRatio( QPixmap& pixmap, qreal value ) |
|
{ |
|
return pixmap.setDevicePixelRatio( value ); |
|
} |
|
|
|
//______________________________________________________________ |
|
void TileSet::initPixmap( PixmapList& pixmaps, const QPixmap &source, int width, int height, const QRect &rect) |
|
{ |
|
QSize size( width, height ); |
|
if( !( size.isValid() && rect.isValid() ) ) |
|
{ |
|
pixmaps.append( QPixmap() ); |
|
|
|
} else if( size != rect.size() ) { |
|
|
|
const qreal dpiRatio( devicePixelRatio( source ) ); |
|
const QRect scaledRect( rect.topLeft()*dpiRatio, rect.size()*dpiRatio ); |
|
const QSize scaledSize( size*dpiRatio ); |
|
const QPixmap tile( source.copy(scaledRect) ); |
|
QPixmap pixmap( scaledSize ); |
|
|
|
pixmap.fill(Qt::transparent); |
|
QPainter painter(&pixmap); |
|
painter.drawTiledPixmap(0, 0, scaledSize.width(), scaledSize.height(), tile); |
|
setDevicePixelRatio( pixmap, dpiRatio ); |
|
pixmaps.append( pixmap ); |
|
|
|
} else { |
|
|
|
const qreal dpiRatio( devicePixelRatio( source ) ); |
|
const QRect scaledRect( rect.topLeft()*dpiRatio, rect.size()*dpiRatio ); |
|
QPixmap pixmap( source.copy( scaledRect ) ); |
|
setDevicePixelRatio( pixmap, dpiRatio ); |
|
pixmaps.append( pixmap ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
TileSet::TileSet(): |
|
_w1(0), |
|
_h1(0), |
|
_w3(0), |
|
_h3(0) |
|
{ _pixmaps.reserve(9); } |
|
|
|
//______________________________________________________________ |
|
TileSet::TileSet(const QPixmap &source, int w1, int h1, int w2, int h2 ): |
|
_w1(w1), |
|
_h1(h1), |
|
_w3(0), |
|
_h3(0) |
|
{ |
|
_pixmaps.reserve(9); |
|
if( source.isNull() ) return; |
|
|
|
_w3 = source.width()/devicePixelRatio( source ) - (w1 + w2); |
|
_h3 = source.height()/devicePixelRatio( source ) - (h1 + h2); |
|
int w = w2; |
|
int h = h2; |
|
|
|
// initialise pixmap array |
|
initPixmap( _pixmaps, source, _w1, _h1, QRect(0, 0, _w1, _h1) ); |
|
initPixmap( _pixmaps, source, w, _h1, QRect(_w1, 0, w2, _h1) ); |
|
initPixmap( _pixmaps, source, _w3, _h1, QRect(_w1+w2, 0, _w3, _h1) ); |
|
initPixmap( _pixmaps, source, _w1, h, QRect(0, _h1, _w1, h2) ); |
|
initPixmap( _pixmaps, source, w, h, QRect(_w1, _h1, w2, h2) ); |
|
initPixmap( _pixmaps, source, _w3, h, QRect(_w1+w2, _h1, _w3, h2) ); |
|
initPixmap( _pixmaps, source, _w1, _h3, QRect(0, _h1+h2, _w1, _h3) ); |
|
initPixmap( _pixmaps, source, w, _h3, QRect(_w1, _h1+h2, w2, _h3) ); |
|
initPixmap( _pixmaps, source, _w3, _h3, QRect(_w1+w2, _h1+h2, _w3, _h3) ); |
|
} |
|
|
|
//___________________________________________________________ |
|
void TileSet::render(const QRect &constRect, QPainter *painter, Tiles tiles) const |
|
{ |
|
|
|
const bool oldHint( painter->testRenderHint( QPainter::SmoothPixmapTransform ) ); |
|
painter->setRenderHint( QPainter::SmoothPixmapTransform, true ); |
|
|
|
// check initialization |
|
if( _pixmaps.size() < 9 ) return; |
|
|
|
// copy source rect |
|
QRect rect( constRect ); |
|
|
|
// get rect dimensions |
|
int x0, y0, w, h; |
|
rect.getRect(&x0, &y0, &w, &h); |
|
|
|
// calculate pixmaps widths |
|
int wLeft(0); |
|
int wRight(0); |
|
if( _w1+_w3 > 0 ) |
|
{ |
|
qreal wRatio( qreal( _w1 )/qreal( _w1 + _w3 ) ); |
|
wLeft = (tiles&Right) ? qMin( _w1, int(w*wRatio) ):_w1; |
|
wRight = (tiles&Left) ? qMin( _w3, int(w*(1.0-wRatio)) ):_w3; |
|
} |
|
|
|
// calculate pixmap heights |
|
int hTop(0); |
|
int hBottom(0); |
|
if( _h1+_h3 > 0 ) |
|
{ |
|
qreal hRatio( qreal( _h1 )/qreal( _h1 + _h3 ) ); |
|
hTop = (tiles&Bottom) ? qMin( _h1, int(h*hRatio) ):_h1; |
|
hBottom = (tiles&Top) ? qMin( _h3, int(h*(1.0-hRatio)) ):_h3; |
|
} |
|
|
|
// calculate corner locations |
|
w -= wLeft + wRight; |
|
h -= hTop + hBottom; |
|
const int x1 = x0 + wLeft; |
|
const int x2 = x1 + w; |
|
const int y1 = y0 + hTop; |
|
const int y2 = y1 + h; |
|
|
|
const int w2 = _pixmaps.at(7).width()/devicePixelRatio( _pixmaps.at(7) ); |
|
const int h2 = _pixmaps.at(5).height()/devicePixelRatio( _pixmaps.at(5) ); |
|
|
|
// corner |
|
if( bits( tiles, Top|Left) ) painter->drawPixmap(x0, y0, _pixmaps.at(0), 0, 0, wLeft*devicePixelRatio( _pixmaps.at(0) ), hTop*devicePixelRatio( _pixmaps.at(0) )); |
|
if( bits( tiles, Top|Right) ) painter->drawPixmap(x2, y0, _pixmaps.at(2), (_w3-wRight)*devicePixelRatio( _pixmaps.at(2) ), 0, wRight*devicePixelRatio( _pixmaps.at(2) ), hTop*devicePixelRatio( _pixmaps.at(2) ) ); |
|
if( bits( tiles, Bottom|Left) ) painter->drawPixmap(x0, y2, _pixmaps.at(6), 0, (_h3-hBottom)*devicePixelRatio( _pixmaps.at(6) ), wLeft*devicePixelRatio( _pixmaps.at(6) ), hBottom*devicePixelRatio( _pixmaps.at(6) )); |
|
if( bits( tiles, Bottom|Right) ) painter->drawPixmap(x2, y2, _pixmaps.at(8), (_w3-wRight)*devicePixelRatio( _pixmaps.at(8) ), (_h3-hBottom)*devicePixelRatio( _pixmaps.at(8) ), wRight*devicePixelRatio( _pixmaps.at(8) ), hBottom*devicePixelRatio( _pixmaps.at(8) ) ); |
|
|
|
// top and bottom |
|
if( w > 0 ) |
|
{ |
|
if( tiles&Top ) painter->drawPixmap(x1, y0, w, hTop, _pixmaps.at(1), 0, 0, w2*devicePixelRatio( _pixmaps.at(1) ), hTop*devicePixelRatio( _pixmaps.at(1) ) ); |
|
if( tiles&Bottom ) painter->drawPixmap(x1, y2, w, hBottom, _pixmaps.at(7), 0, (_h3-hBottom)*devicePixelRatio( _pixmaps.at(7) ), w2*devicePixelRatio( _pixmaps.at(7) ), hBottom*devicePixelRatio( _pixmaps.at(7) ) ); |
|
} |
|
|
|
// left and right |
|
if( h > 0 ) |
|
{ |
|
if( tiles&Left ) painter->drawPixmap(x0, y1, wLeft, h, _pixmaps.at(3), 0, 0, wLeft*devicePixelRatio( _pixmaps.at(3) ), h2*devicePixelRatio( _pixmaps.at(3) ) ); |
|
if( tiles&Right ) painter->drawPixmap(x2, y1, wRight, h, _pixmaps.at(5), (_w3-wRight)*devicePixelRatio( _pixmaps.at(5) ), 0, wRight*devicePixelRatio( _pixmaps.at(5) ), h2*devicePixelRatio( _pixmaps.at(5) ) ); |
|
} |
|
|
|
// center |
|
if( (tiles&Center) && h > 0 && w > 0 ) painter->drawPixmap(x1, y1, w, h, _pixmaps.at(4)); |
|
|
|
// restore |
|
painter->setRenderHint( QPainter::SmoothPixmapTransform, oldHint ); |
|
|
|
} |
|
|
|
}
|
|
|