Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tileset tile x/y draw offset. #3488

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
18 changes: 7 additions & 11 deletions src/libtiled/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

#include <QtMath>

#include "qtcompat_p.h"

using namespace Tiled;

Map::Map()
Expand Down Expand Up @@ -100,11 +102,10 @@ void Map::adjustBoundingRectForOffsetsAndImageLayers(QRect &boundingRect) const
// rect. More precise would be to take into account their
// contents.
const QPointF offset = layer->totalOffset();
offsetMargins = maxMargins(QMargins(qCeil(-offset.x()),
qCeil(-offset.y()),
qCeil(offset.x()),
qCeil(offset.y())),
offsetMargins);
offsetMargins = offsetMargins | QMargins(qCeil(-offset.x()),
qCeil(-offset.y()),
qCeil(offset.x()),
qCeil(offset.y()));
break;
}
case Layer::ImageLayerType: {
Expand Down Expand Up @@ -150,12 +151,7 @@ void Map::recomputeDrawMargins() const
maxTileSize = std::max(maxTileSize, std::max(tileSize.width(),
tileSize.height()));

const QPoint offset = tileset->tileOffset();
offsetMargins = maxMargins(QMargins(-offset.x(),
-offset.y(),
offset.x(),
offset.y()),
offsetMargins);
offsetMargins = offsetMargins | tileset->drawMargins();
}

// We subtract the tile size of the map, since that part does not
Expand Down
14 changes: 7 additions & 7 deletions src/libtiled/mapobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,16 +256,16 @@ Alignment MapObject::alignment(const Map *map) const
if (Tileset *tileset = mCell.tileset())
alignment = tileset->objectAlignment();

if (!map && mObjectGroup)
map = mObjectGroup->map();

if (alignment == Unspecified) {
if (!map && mObjectGroup)
map = mObjectGroup->map();

if (mCell.isEmpty())
return TopLeft;
alignment = TopLeft;
else if (map && map->orientation() == Map::Isometric)
return Bottom;

return BottomLeft;
alignment = Bottom;
else
alignment = BottomLeft;
}

return alignment;
Expand Down
5 changes: 5 additions & 0 deletions src/libtiled/mapreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,11 @@ void MapReaderPrivate::readTilesetTile(Tileset &tileset)
if (!probability.isEmpty())
tile->setProbability(probability.toDouble());

// Read local tile offset
const QPoint origin(atts.value(QLatin1String("originx")).toInt(),
atts.value(QLatin1String("originy")).toInt());
tile->setOrigin(origin);

while (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("properties")) {
tile->mergeProperties(readProperties());
Expand Down
7 changes: 7 additions & 0 deletions src/libtiled/mapwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ static bool includeTile(const Tile *tile)
return true;
if (tile->isAnimated())
return true;
if (!tile->origin().isNull())
return true;
if (tile->probability() != 1.0)
return true;

Expand Down Expand Up @@ -449,6 +451,11 @@ void MapWriterPrivate::writeTileset(QXmlStreamWriter &w, const Tileset &tileset,
w.writeAttribute(FileFormat::classPropertyNameForObject(), tile->className());
if (tile->probability() != 1.0)
w.writeAttribute(QStringLiteral("probability"), QString::number(tile->probability()));
const QPoint origin = tile->origin();
if (origin.x() != 0)
w.writeAttribute(QStringLiteral("originx"), QString::number(origin.x()));
if (origin.y() != 0)
w.writeAttribute(QStringLiteral("originy"), QString::number(origin.y()));
if (!tile->properties().isEmpty())
writeProperties(w, tile->properties());
if (isCollection) {
Expand Down
8 changes: 8 additions & 0 deletions src/libtiled/qtcompat_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ using ::endl;
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
using QStringRef = QStringView;
#endif

#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
constexpr inline QMargins operator|(const QMargins &m1, const QMargins &m2) noexcept
{
return QMargins(qMax(m1.left(), m2.left()), qMax(m1.top(), m2.top()),
qMax(m1.right(), m2.right()), qMax(m1.bottom(), m2.bottom()));
}
#endif
26 changes: 16 additions & 10 deletions src/libtiled/tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,15 @@ Tile::Tile(int id, Tileset *tileset):
Object(TileType),
mId(id),
mTileset(tileset),
mImageStatus(LoadingReady),
mProbability(1.0),
mCurrentFrameIndex(0),
mUnusedTime(0)
mImageStatus(LoadingReady)
{}

Tile::Tile(const QPixmap &image, int id, Tileset *tileset):
Object(TileType),
mId(id),
mTileset(tileset),
mImage(image),
mImageStatus(image.isNull() ? LoadingError : LoadingReady),
mProbability(1.0),
mCurrentFrameIndex(0),
mUnusedTime(0)
mImageStatus(image.isNull() ? LoadingError : LoadingReady)
{}

Tile::~Tile()
Expand Down Expand Up @@ -150,11 +144,22 @@ void Tile::setImageRect(const QRect &imageRect)
}

/**
* Returns the drawing offset of the tile (in pixels).
* Returns the total drawing offset of the tile (in pixels).
*/
QPoint Tile::offset() const
{
return mTileset->tileOffset();
return mTileset->tileOffset() - mOrigin;
}

/**
* Sets the origin of this tile (in pixels).
*/
void Tile::setOrigin(QPoint offset)
{
mOrigin = offset;

if (mTileset)
mTileset->invalidateDrawMargins();
}

/**
Expand Down Expand Up @@ -245,6 +250,7 @@ Tile *Tile::clone(Tileset *tileset) const

c->mImageSource = mImageSource;
c->mImageRect = mImageRect;
c->mOrigin = mOrigin;
c->mImageStatus = mImageStatus;
c->mProbability = mProbability;

Expand Down
20 changes: 16 additions & 4 deletions src/libtiled/tile.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,12 @@ class TILEDSHARED_EXPORT Tile : public Object

QPoint offset() const;

QPoint origin() const;
void setOrigin(QPoint offset);

// For Python API compatibility
const QString &type() const { return className(); }
void setType(const QString &type) { setClassName(type); };
void setType(const QString &type) { setClassName(type); }

qreal probability() const;
void setProbability(qreal probability);
Expand Down Expand Up @@ -121,13 +124,14 @@ class TILEDSHARED_EXPORT Tile : public Object
mutable std::optional<QPainterPath> mImageShape; // cache
QUrl mImageSource;
QRect mImageRect;
QPoint mOrigin;
LoadingStatus mImageStatus;
qreal mProbability;
qreal mProbability = 1.0;
std::unique_ptr<ObjectGroup> mObjectGroup;

QVector<Frame> mFrames;
int mCurrentFrameIndex;
int mUnusedTime;
int mCurrentFrameIndex = 0;
int mUnusedTime = 0;

friend class Tileset; // To allow changing the tile id
};
Expand Down Expand Up @@ -195,6 +199,14 @@ inline QSize Tile::size() const
return mImageRect.size();
}

/**
* Returns the origin of the tile (in pixels).
*/
inline QPoint Tile::origin() const
{
return mOrigin;
}

/**
* Returns the relative probability of this tile appearing while painting.
*/
Expand Down
13 changes: 0 additions & 13 deletions src/libtiled/tiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,6 @@ inline QString colorToString(const QColor &color)
return color.name();
}

inline QMargins maxMargins(const QMargins &a,
const QMargins &b)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
return QMargins(qMax(a.left(), b.left()),
qMax(a.top(), b.top()),
qMax(a.right(), b.right()),
qMax(a.bottom(), b.bottom()));
#else
return a | b;
#endif
}

TILEDSHARED_EXPORT QString alignmentToString(Alignment);
TILEDSHARED_EXPORT Alignment alignmentFromString(const QString &);

Expand Down
10 changes: 3 additions & 7 deletions src/libtiled/tilelayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

#include <QSet>

#include "qtcompat_p.h"

using namespace Tiled;

Cell Cell::empty;
Expand Down Expand Up @@ -147,19 +149,13 @@ static QMargins computeDrawMargins(const QSet<SharedTileset> &tilesets)
QMargins offsetMargins;

for (const SharedTileset &tileset : tilesets) {
const QPoint offset = tileset->tileOffset();

if (tileset->tileRenderSize() == Tileset::TileSize) {
const QSize tileSize = tileset->tileSize();
maxTileSize = std::max(maxTileSize, std::max(tileSize.width(),
tileSize.height()));
}

offsetMargins = maxMargins(QMargins(-offset.x(),
-offset.y(),
offset.x(),
offset.y()),
offsetMargins);
offsetMargins = offsetMargins | tileset->drawMargins();
}

// Adding maxTileSize to top-right of the margins assumes a bottom-left tile
Expand Down
32 changes: 32 additions & 0 deletions src/libtiled/tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

#include <QBitmap>

#include "qtcompat_p.h"

namespace Tiled {

Tileset::Tileset(QString name, int tileWidth, int tileHeight,
Expand Down Expand Up @@ -103,6 +105,36 @@ void Tileset::setMargin(int margin)
mMargin = margin;
}

/**
* @see tileOffset
*/
void Tileset::setTileOffset(QPoint offset)
{
if (mTileOffset == offset)
return;

mTileOffset = offset;
mDrawMarginsDirty = true;
}

QMargins Tileset::drawMargins() const
{
if (mDrawMarginsDirty) {
QMargins margins;

for (const Tile *tile : mTiles) {
const auto offset = mTileOffset - tile->origin();
margins = margins | QMargins(-offset.x(), -offset.y(),
offset.x(), offset.y());
}

mDrawMargins = margins;
mDrawMarginsDirty = false;
}

return mDrawMargins;
}

/**
* Returns the location of the tile with the given ID.
*/
Expand Down
13 changes: 8 additions & 5 deletions src/libtiled/tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ class TILEDSHARED_EXPORT Tileset : public Object, public QEnableSharedFromThis<T
QPoint tileOffset() const;
void setTileOffset(QPoint offset);

QMargins drawMargins() const;
void invalidateDrawMargins();

Orientation orientation() const;
void setOrientation(Orientation orientation);

Expand Down Expand Up @@ -324,6 +327,9 @@ class TILEDSHARED_EXPORT Tileset : public Object, public QEnableSharedFromThis<T
QString mFormat;
TransformationFlags mTransformationFlags;

mutable QMargins mDrawMargins;
mutable bool mDrawMarginsDirty = true;

QWeakPointer<Tileset> mOriginalTileset;
};

Expand Down Expand Up @@ -454,12 +460,9 @@ inline QPoint Tileset::tileOffset() const
return mTileOffset;
}

/**
* @see tileOffset
*/
inline void Tileset::setTileOffset(QPoint offset)
inline void Tileset::invalidateDrawMargins()
{
mTileOffset = offset;
mDrawMarginsDirty = true;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/libtiledquick/tilelayeritem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ QSGNode *TileLayerItem::updatePaintNode(QSGNode *node,
// return;
// }

const auto offset = tileset->tileOffset();
const auto tile = tileset->findTile(cell.tileId());
const auto offset = tile ? tile->offset() : tileset->tileOffset();
const QSize size = (tile && !tile->image().isNull()) ? tile->size() : mRenderer->map()->tileSize();

TileData data;
Expand Down Expand Up @@ -272,7 +272,7 @@ QSGNode *TileItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeDat
const int tileHeight = map->tileHeight();

const QSize size = tile->size();
const QPoint offset = tileset->tileOffset();
const QPoint offset = tile->offset();

QVector<TileData> data(1);
data[0].x = mPosition.x() * tileWidth + offset.x();
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/lua/luaplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ static bool includeTile(const Tile *tile)
return true;
if (tile->isAnimated())
return true;
if (!tile->origin().isNull())
return true;
if (tile->probability() != 1.0)
return true;

Expand Down Expand Up @@ -434,6 +436,14 @@ void LuaWriter::writeTileset(const Tileset &tileset,
}
}

const QPoint origin = tile->origin();
if (!origin.isNull()) {
mWriter.writeStartTable("origin");
mWriter.writeKeyAndValue("x", origin.x());
mWriter.writeKeyAndValue("y", origin.y());
mWriter.writeEndTable();
}

if (tile->probability() != 1.0)
mWriter.writeKeyAndValue("probability", tile->probability());

Expand Down
Loading
Loading