Fix rotSprite for normal layers (and keep the tile replication Ok on tilemap layers during a "transform action")

This commit is contained in:
Gaspar Capello 2021-01-29 16:34:06 -03:00 committed by David Capello
parent 289a6ab864
commit a1e013f4a7
7 changed files with 34 additions and 17 deletions

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2020 Igara Studio S.A.
// Copyright (C) 2018-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -403,7 +403,7 @@ void Doc::setTransformation(const Transformation& transform)
void Doc::resetTransformation()
{
m_transformation = Transformation(gfx::RectF(m_mask->bounds()));
m_transformation = Transformation(gfx::RectF(m_mask->bounds()), m_transformation.cornerThick());
}
//////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2020 Igara Studio S.A.
// Copyright (C) 2018-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -13,6 +13,7 @@
#include "app/doc.h"
#include "app/doc_undo.h"
#include "app/tools/pick_ink.h"
#include "app/transformation.h"
#include "doc/mask.h"
#include "doc/tile.h"
#include "gfx/region.h"
@ -518,8 +519,11 @@ public:
m_mask.unfreeze();
loop->setMask(&m_mask);
double cornerThick = (loop->isTilemapMode()) ?
CORNER_THICK_FOR_TILEMAP_MODE :
CORNER_THICK_FOR_PIXELS_MODE;
loop->getDocument()->setTransformation(
Transformation(RectF(m_mask.bounds())));
Transformation(RectF(m_mask.bounds()), cornerThick));
m_mask.clear();
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A.
// Copyright (C) 2019-2021 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@ -88,6 +88,9 @@ namespace app {
// Returns the layer that will be modified if the tool paints
virtual Layer* getLayer() = 0;
// Returns true if the current mode is TileMap (false = Pixels)
virtual bool isTilemapMode() = 0;
// Returns the frame where we're paiting
virtual frame_t getFrame() = 0;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2020-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -24,8 +24,9 @@ Transformation::Transformation()
{
}
Transformation::Transformation(const RectF& bounds)
Transformation::Transformation(const RectF& bounds, double cornerThick)
: m_bounds(bounds)
, m_cornerThick(cornerThick)
{
m_pivot.x = bounds.x + bounds.w/2;
m_pivot.y = bounds.y + bounds.h/2;
@ -86,7 +87,7 @@ RectF Transformation::transformedBounds() const
// Create a union of all corners
RectF bounds;
for (int i=0; i<Corners::NUM_OF_CORNERS; ++i)
bounds = bounds.createUnion(RectF(corners[i].x, corners[i].y, 0.001, 0.001));
bounds = bounds.createUnion(RectF(corners[i].x, corners[i].y, m_cornerThick, m_cornerThick));
return bounds;
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2020-2021 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
@ -13,6 +13,9 @@
#include "gfx/rect.h"
#include <vector>
#define CORNER_THICK_FOR_TILEMAP_MODE 0.001
#define CORNER_THICK_FOR_PIXELS_MODE 1.0
namespace app {
// Represents a transformation that can be done by the user in the
@ -56,10 +59,10 @@ public:
void rightBottom(const gfx::PointF& pt) { m_corners[RIGHT_BOTTOM] = pt; }
void leftBottom(const gfx::PointF& pt) { m_corners[LEFT_BOTTOM] = pt; }
gfx::RectF bounds() const {
gfx::RectF bounds(double cornerThick) const {
gfx::RectF bounds;
for (int i=0; i<Corners::NUM_OF_CORNERS; ++i)
bounds |= gfx::RectF(m_corners[i].x, m_corners[i].y, 0.001, 0.001);
bounds |= gfx::RectF(m_corners[i].x, m_corners[i].y, cornerThick, cornerThick);
return bounds;
}
@ -68,12 +71,13 @@ public:
};
Transformation();
Transformation(const gfx::RectF& bounds);
Transformation(const gfx::RectF& bounds, double cornerThick);
// Simple getters and setters. The angle is in radians.
const gfx::RectF& bounds() const { return m_bounds; }
const gfx::PointF& pivot() const { return m_pivot; }
double cornerThick() const { return m_cornerThick; }
double angle() const { return m_angle; }
double skew() const { return m_skew; }
@ -103,6 +107,7 @@ private:
gfx::PointF m_pivot = gfx::PointF(0.0, 0.0);
double m_angle = 0.0;
double m_skew = 0.0;
double m_cornerThick = CORNER_THICK_FOR_PIXELS_MODE;
};
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A.
// Copyright (C) 2019-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -130,7 +130,10 @@ PixelsMovement::PixelsMovement(
, m_fastMode(false)
, m_needsRotSpriteRedraw(false)
{
Transformation transform(mask->bounds());
double cornerThick = (m_site.tilemapMode() == TilemapMode::Tiles) ?
CORNER_THICK_FOR_TILEMAP_MODE :
CORNER_THICK_FOR_PIXELS_MODE;
Transformation transform(mask->bounds(), cornerThick);
set_pivot_from_preferences(transform);
m_initialData = transform;
@ -770,7 +773,7 @@ void PixelsMovement::stampImage(bool finalStamp)
if (currentCel && currentCel->layer() &&
currentCel->layer()->isImage() &&
!currentCel->layer()->isEditableHierarchy()) {
Transformation initialCelPos(gfx::Rect(m_initialMask0->bounds()));
Transformation initialCelPos(gfx::Rect(m_initialMask0->bounds()), m_currentData.cornerThick());
redrawExtraImage(&initialCelPos);
stampExtraCelImage();
}
@ -1023,7 +1026,7 @@ void PixelsMovement::drawImage(
ASSERT(dst);
auto corners = transformation.transformedCorners();
gfx::Rect bounds = corners.bounds();
gfx::Rect bounds = corners.bounds(transformation.cornerThick());
if (m_site.tilemapMode() == TilemapMode::Tiles) {
dst->setMaskColor(doc::notile);
@ -1071,7 +1074,7 @@ void PixelsMovement::drawImage(
void PixelsMovement::drawMask(doc::Mask* mask, bool shrink)
{
auto corners = m_currentData.transformedCorners();
gfx::Rect bounds = corners.bounds();
gfx::Rect bounds = corners.bounds(m_currentData.cornerThick());
if (bounds.isEmpty()) {
mask->clear();

View File

@ -282,6 +282,7 @@ public:
Doc* getDocument() override { return m_document; }
Sprite* sprite() override { return m_sprite; }
Layer* getLayer() override { return m_layer; }
bool isTilemapMode() override { return m_tilesMode; };
frame_t getFrame() override { return m_frame; }
RgbMap* getRgbMap() override {
if (!m_rgbMap) {