From 708ba2e9e88b261d2620e1c8759e0f029e0b6a21 Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Tue, 8 Aug 2023 11:21:10 -0300 Subject: [PATCH] Fix overlapped shape padding between frame images on Packed sheet type (fix aseprite/aseprite#3993) Prior to this fix, the shape padding generated by 'Export Sprite Sheet' overlapped on some frame images when the following options were chosen: - Packed sheet type - Trim Cels = true - Spacing > 0 (shape padding > 0) --- gfx/packing_rects.cpp | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/gfx/packing_rects.cpp b/gfx/packing_rects.cpp index 9b24e894d..4a23a35fb 100644 --- a/gfx/packing_rects.cpp +++ b/gfx/packing_rects.cpp @@ -1,5 +1,5 @@ // LAF Gfx Library -// Copyright (C) 2019 Igara Studio S.A. +// Copyright (C) 2019-2023 Igara Studio S.A. // Copyright (C) 2001-2014 David Capello // // This file is released under the terms of the MIT license. @@ -52,9 +52,11 @@ Size PackingRects::bestFit(base::task_token& token, bool fit = false; while (!token.canceled()) { if (w*h >= neededArea) { - fit = pack(Size(w, h), token); + Size sizeCandidate = Size(w + 2 * m_borderPadding, + h + 2 * m_borderPadding); + fit = pack(sizeCandidate, token); if (fit) { - size = Size(w, h); + size = sizeCandidate; break; } } @@ -101,25 +103,33 @@ bool PackingRects::pack(const Size& size, gfx::Rect& rc = *rcPtr; - // The rectangles are treated as its original size during placement, - // but occupies an extra border of pixels once its - // position has been determined. - // This ensures that all rectangles are padded by pixels, - // and are still placed correctly near edges, e.g. when remaining - // horizontal space is between and +. + // The rectangles are treated as its original size + + // conditional extra border of during placement. for (int v=0; v<=m_bounds.h-rc.h; ++v) { for (int u=0; u<=m_bounds.w-rc.w; ++u) { if (token.canceled()) return false; - gfx::Rect possible(m_bounds.x + u, m_bounds.y + v, rc.w, rc.h); + // It's necessary to consider the as an + // integral part of the image size; otherwise, the region + // subtraction process may be incorrect, resulting in + // overlapping of shape padding between adjacent sprites. + // This fix resolves the special cases of exporting with + // sheet type 'Packed' + 'Trim Cels' true + + // 'Shape padding' > 0 + series of particular image sizes. + int wShapePadding = + ((u + rc.w) == m_bounds.w ? 0 : m_shapePadding); + int hShapePadding = + ((v + rc.h) == m_bounds.h ? 0 : m_shapePadding); + gfx::Rect possible(m_bounds.x + u, + m_bounds.y + v, + rc.w + wShapePadding, + rc.h + hShapePadding); + Region::Overlap overlap = rgn.contains(possible); if (overlap == Region::In) { - rc = possible; - rgn.createSubtraction( - rgn, - gfx::Region(Rect(rc).inflate(m_shapePadding)) - ); + rc = Rect(m_bounds.x + u, m_bounds.y + v, rc.w, rc.h); + rgn.createSubtraction(rgn, gfx::Region(Rect(possible))); goto next_rc; } }