2
* orthogonalrenderer.cpp
3
* Copyright 2009-2010, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
5
* This file is part of Tiled.
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the Free
9
* Software Foundation; either version 2 of the License, or (at your option)
12
* This program is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17
* You should have received a copy of the GNU General Public License along with
18
* this program. If not, see <http://www.gnu.org/licenses/>.
21
#include "orthogonalrenderer.h"
24
#include "mapobject.h"
26
#include "tilelayer.h"
30
using namespace Tiled::Internal;
32
QSize OrthogonalRenderer::mapSize() const
34
return QSize(map()->width() * map()->tileWidth(),
35
map()->height() * map()->tileHeight());
38
QRect OrthogonalRenderer::boundingRect(const QRect &rect) const
40
const int tileWidth = map()->tileWidth();
41
const int tileHeight = map()->tileHeight();
43
return QRect(rect.x() * tileWidth,
44
rect.y() * tileHeight,
45
rect.width() * tileWidth,
46
rect.height() * tileHeight);
49
QRectF OrthogonalRenderer::boundingRect(const MapObject *object) const
51
const QRectF bounds = object->bounds();
52
const QRectF rect(tileToPixelCoords(bounds.topLeft()),
53
tileToPixelCoords(bounds.bottomRight()));
55
// The -2 and +3 are to account for the pen width and shadow
57
return rect.adjusted(-15 - 2, -25 - 2, 10 + 3, 10 + 3);
59
return rect.adjusted(-2, -15 - 2, 3, 3);
62
QPainterPath OrthogonalRenderer::shape(const MapObject *object) const
64
const QRectF bounds = object->bounds();
65
const QRectF rect(tileToPixelCoords(bounds.topLeft()),
66
tileToPixelCoords(bounds.bottomRight()));
70
path.addEllipse(rect.topLeft(), 20, 20);
72
path.addRoundedRect(rect, 10, 10);
76
void OrthogonalRenderer::drawGrid(QPainter *painter, const QRectF &rect) const
78
const int tileWidth = map()->tileWidth();
79
const int tileHeight = map()->tileHeight();
81
const int startX = (int) (rect.x() / tileWidth) * tileWidth;
82
const int startY = (int) (rect.y() / tileHeight) * tileHeight;
83
const int endX = qMin((int) std::ceil(rect.right()),
84
map()->width() * tileWidth + 1);
85
const int endY = qMin((int) std::ceil(rect.bottom()),
86
map()->height() * tileHeight + 1);
88
QColor gridColor(Qt::black);
89
gridColor.setAlpha(128);
91
QPen gridPen(gridColor);
92
gridPen.setDashPattern(QVector<qreal>() << 2 << 2);
94
if ((int) rect.top() < endY) {
95
gridPen.setDashOffset(rect.top());
96
painter->setPen(gridPen);
97
for (int x = startX; x < endX; x += tileWidth)
98
painter->drawLine(x, (int) rect.top(), x, endY - 1);
101
if ((int) rect.left() < endX) {
102
gridPen.setDashOffset(rect.left());
103
painter->setPen(gridPen);
104
for (int y = startY; y < endY; y += tileHeight)
105
painter->drawLine((int) rect.left(), y, endX - 1, y);
109
void OrthogonalRenderer::drawTileLayer(QPainter *painter,
110
const TileLayer *layer,
111
const QRectF &exposed) const
113
const int tileWidth = map()->tileWidth();
114
const int tileHeight = map()->tileHeight();
115
const QPointF layerPos(layer->x() * tileWidth,
116
layer->y() * tileHeight);
118
painter->translate(layerPos);
122
int endX = layer->width();
123
int endY = layer->height();
125
if (!exposed.isNull()) {
126
const QSize maxTileSize = layer->maxTileSize();
127
const int extraWidth = maxTileSize.width() - tileWidth;
128
const int extraHeight = maxTileSize.height() - tileHeight;
129
QRectF rect = exposed.adjusted(-extraWidth, 0, 0, extraHeight);
130
rect.translate(-layerPos);
132
startX = qMax((int) rect.x() / tileWidth, 0);
133
startY = qMax((int) rect.y() / tileHeight, 0);
134
endX = qMin((int) std::ceil(rect.right()) / tileWidth + 1, endX);
135
endY = qMin((int) std::ceil(rect.bottom()) / tileHeight + 1, endY);
138
for (int y = startY; y < endY; ++y) {
139
for (int x = startX; x < endX; ++x) {
140
const Tile *tile = layer->tileAt(x, y);
144
const QPixmap &img = tile->image();
145
painter->drawPixmap(x * tileWidth,
146
(y + 1) * tileHeight - img.height(),
151
painter->translate(-layerPos);
154
void OrthogonalRenderer::drawTileSelection(QPainter *painter,
155
const QRegion ®ion,
157
const QRectF &exposed) const
159
foreach (const QRect &r, region.rects()) {
160
const QRectF toFill = QRectF(boundingRect(r)).intersected(exposed);
161
if (!toFill.isEmpty())
162
painter->fillRect(toFill, color);
166
void OrthogonalRenderer::drawMapObject(QPainter *painter,
167
const MapObject *object,
168
const QColor &color) const
172
QColor brushColor = color;
173
brushColor.setAlpha(50);
174
QBrush brush(brushColor);
178
pen.setJoinStyle(Qt::RoundJoin);
180
// Make sure the line aligns nicely on the pixels
182
painter->translate(0.5, 0.5);
184
painter->setPen(pen);
185
painter->setRenderHint(QPainter::Antialiasing);
186
const QFontMetrics fm = painter->fontMetrics();
188
const QRectF bounds = object->bounds();
189
const QRectF rect(tileToPixelCoords(bounds.topLeft()),
190
tileToPixelCoords(bounds.bottomRight()));
191
painter->translate(rect.topLeft());
195
QString name = fm.elidedText(object->name(), Qt::ElideRight, 30);
198
painter->drawEllipse(QRect(- 10 + 1, - 10 + 1, 20, 20));
199
painter->drawText(QPoint(-15 + 1, -15 + 1), name);
202
painter->setPen(pen);
203
painter->setBrush(brush);
204
painter->drawEllipse(QRect(-10, -10, 20, 20));
205
painter->drawText(QPoint(-15, -15), name);
209
QString name = fm.elidedText(object->name(), Qt::ElideRight,
213
painter->drawRoundedRect(QRectF(QPointF(1, 1), rect.size()),
215
painter->drawText(QPoint(1, -5 + 1), name);
218
painter->setPen(pen);
219
painter->setBrush(brush);
220
painter->drawRoundedRect(QRectF(QPointF(0, 0), rect.size()),
222
painter->drawText(QPoint(0, -5), name);
228
QPointF OrthogonalRenderer::pixelToTileCoords(qreal x, qreal y) const
230
return QPointF(x / map()->tileWidth(),
231
y / map()->tileHeight());
234
QPointF OrthogonalRenderer::tileToPixelCoords(qreal x, qreal y) const
236
return QPointF(x * map()->tileWidth(),
237
y * map()->tileHeight());