~ubuntu-branches/ubuntu/raring/tiled-qt/raring

« back to all changes in this revision

Viewing changes to src/tiled/orthogonalrenderer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ying-Chun Liu (PaulLiu)
  • Date: 2010-07-05 21:35:45 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100705213545-ol5zjn85kun26ywx
Tags: 0.5.0-1
* New upstream release
* debian/patches/addrpath.patch: Modify library install path.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * orthogonalrenderer.cpp
 
3
 * Copyright 2009-2010, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
 
4
 *
 
5
 * This file is part of Tiled.
 
6
 *
 
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)
 
10
 * any later version.
 
11
 *
 
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
 
15
 * more details.
 
16
 *
 
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/>.
 
19
 */
 
20
 
 
21
#include "orthogonalrenderer.h"
 
22
 
 
23
#include "map.h"
 
24
#include "mapobject.h"
 
25
#include "tile.h"
 
26
#include "tilelayer.h"
 
27
 
 
28
#include <cmath>
 
29
 
 
30
using namespace Tiled::Internal;
 
31
 
 
32
QSize OrthogonalRenderer::mapSize() const
 
33
{
 
34
    return QSize(map()->width() * map()->tileWidth(),
 
35
                 map()->height() * map()->tileHeight());
 
36
}
 
37
 
 
38
QRect OrthogonalRenderer::boundingRect(const QRect &rect) const
 
39
{
 
40
    const int tileWidth = map()->tileWidth();
 
41
    const int tileHeight = map()->tileHeight();
 
42
 
 
43
    return QRect(rect.x() * tileWidth,
 
44
                 rect.y() * tileHeight,
 
45
                 rect.width() * tileWidth,
 
46
                 rect.height() * tileHeight);
 
47
}
 
48
 
 
49
QRectF OrthogonalRenderer::boundingRect(const MapObject *object) const
 
50
{
 
51
    const QRectF bounds = object->bounds();
 
52
    const QRectF rect(tileToPixelCoords(bounds.topLeft()),
 
53
                      tileToPixelCoords(bounds.bottomRight()));
 
54
 
 
55
    // The -2 and +3 are to account for the pen width and shadow
 
56
    if (rect.isNull())
 
57
        return rect.adjusted(-15 - 2, -25 - 2, 10 + 3, 10 + 3);
 
58
    else
 
59
        return rect.adjusted(-2, -15 - 2, 3, 3);
 
60
}
 
61
 
 
62
QPainterPath OrthogonalRenderer::shape(const MapObject *object) const
 
63
{
 
64
    const QRectF bounds = object->bounds();
 
65
    const QRectF rect(tileToPixelCoords(bounds.topLeft()),
 
66
                      tileToPixelCoords(bounds.bottomRight()));
 
67
 
 
68
    QPainterPath path;
 
69
    if (rect.isNull())
 
70
        path.addEllipse(rect.topLeft(), 20, 20);
 
71
    else
 
72
        path.addRoundedRect(rect, 10, 10);
 
73
    return path;
 
74
}
 
75
 
 
76
void OrthogonalRenderer::drawGrid(QPainter *painter, const QRectF &rect) const
 
77
{
 
78
    const int tileWidth = map()->tileWidth();
 
79
    const int tileHeight = map()->tileHeight();
 
80
 
 
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);
 
87
 
 
88
    QColor gridColor(Qt::black);
 
89
    gridColor.setAlpha(128);
 
90
 
 
91
    QPen gridPen(gridColor);
 
92
    gridPen.setDashPattern(QVector<qreal>() << 2 << 2);
 
93
 
 
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);
 
99
    }
 
100
 
 
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);
 
106
    }
 
107
}
 
108
 
 
109
void OrthogonalRenderer::drawTileLayer(QPainter *painter,
 
110
                                       const TileLayer *layer,
 
111
                                       const QRectF &exposed) const
 
112
{
 
113
    const int tileWidth = map()->tileWidth();
 
114
    const int tileHeight = map()->tileHeight();
 
115
    const QPointF layerPos(layer->x() * tileWidth,
 
116
                           layer->y() * tileHeight);
 
117
 
 
118
    painter->translate(layerPos);
 
119
 
 
120
    int startX = 0;
 
121
    int startY = 0;
 
122
    int endX = layer->width();
 
123
    int endY = layer->height();
 
124
 
 
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);
 
131
 
 
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);
 
136
    }
 
137
 
 
138
    for (int y = startY; y < endY; ++y) {
 
139
        for (int x = startX; x < endX; ++x) {
 
140
            const Tile *tile = layer->tileAt(x, y);
 
141
            if (!tile)
 
142
                continue;
 
143
 
 
144
            const QPixmap &img = tile->image();
 
145
            painter->drawPixmap(x * tileWidth,
 
146
                                (y + 1) * tileHeight - img.height(),
 
147
                                img);
 
148
        }
 
149
    }
 
150
 
 
151
    painter->translate(-layerPos);
 
152
}
 
153
 
 
154
void OrthogonalRenderer::drawTileSelection(QPainter *painter,
 
155
                                           const QRegion &region,
 
156
                                           const QColor &color,
 
157
                                           const QRectF &exposed) const
 
158
{
 
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);
 
163
    }
 
164
}
 
165
 
 
166
void OrthogonalRenderer::drawMapObject(QPainter *painter,
 
167
                                       const MapObject *object,
 
168
                                       const QColor &color) const
 
169
{
 
170
    painter->save();
 
171
 
 
172
    QColor brushColor = color;
 
173
    brushColor.setAlpha(50);
 
174
    QBrush brush(brushColor);
 
175
 
 
176
    QPen pen(Qt::black);
 
177
    pen.setWidth(3);
 
178
    pen.setJoinStyle(Qt::RoundJoin);
 
179
 
 
180
    // Make sure the line aligns nicely on the pixels
 
181
    if (pen.width() % 2)
 
182
        painter->translate(0.5, 0.5);
 
183
 
 
184
    painter->setPen(pen);
 
185
    painter->setRenderHint(QPainter::Antialiasing);
 
186
    const QFontMetrics fm = painter->fontMetrics();
 
187
 
 
188
    const QRectF bounds = object->bounds();
 
189
    const QRectF rect(tileToPixelCoords(bounds.topLeft()),
 
190
                      tileToPixelCoords(bounds.bottomRight()));
 
191
    painter->translate(rect.topLeft());
 
192
 
 
193
    if (rect.isNull())
 
194
    {
 
195
        QString name = fm.elidedText(object->name(), Qt::ElideRight, 30);
 
196
 
 
197
        // Draw the shadow
 
198
        painter->drawEllipse(QRect(- 10 + 1, - 10 + 1, 20, 20));
 
199
        painter->drawText(QPoint(-15 + 1, -15 + 1), name);
 
200
 
 
201
        pen.setColor(color);
 
202
        painter->setPen(pen);
 
203
        painter->setBrush(brush);
 
204
        painter->drawEllipse(QRect(-10, -10, 20, 20));
 
205
        painter->drawText(QPoint(-15, -15), name);
 
206
    }
 
207
    else
 
208
    {
 
209
        QString name = fm.elidedText(object->name(), Qt::ElideRight,
 
210
                                     rect.width() + 2);
 
211
 
 
212
        // Draw the shadow
 
213
        painter->drawRoundedRect(QRectF(QPointF(1, 1), rect.size()),
 
214
                                 10.0, 10.0);
 
215
        painter->drawText(QPoint(1, -5 + 1), name);
 
216
 
 
217
        pen.setColor(color);
 
218
        painter->setPen(pen);
 
219
        painter->setBrush(brush);
 
220
        painter->drawRoundedRect(QRectF(QPointF(0, 0), rect.size()),
 
221
                                 10.0, 10.0);
 
222
        painter->drawText(QPoint(0, -5), name);
 
223
    }
 
224
 
 
225
    painter->restore();
 
226
}
 
227
 
 
228
QPointF OrthogonalRenderer::pixelToTileCoords(qreal x, qreal y) const
 
229
{
 
230
    return QPointF(x / map()->tileWidth(),
 
231
                   y / map()->tileHeight());
 
232
}
 
233
 
 
234
QPointF OrthogonalRenderer::tileToPixelCoords(qreal x, qreal y) const
 
235
{
 
236
    return QPointF(x * map()->tileWidth(),
 
237
                   y * map()->tileHeight());
 
238
}