mirror of
https://gitgud.io/wackyideas/aerothemeplasma.git
synced 2024-08-15 00:43:43 +00:00
224 lines
7.6 KiB
C++
224 lines
7.6 KiB
C++
|
/*
|
||
|
* 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);
|
||
|
}
|
||
|
|
||
|
}
|