mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 15:32:38 +00:00
Save grid bounds inside .aseprite files and doc::Sprite (fix #688)
This commit is contained in:
parent
86ef6979e2
commit
30b2585037
@ -394,7 +394,7 @@
|
|||||||
</section>
|
</section>
|
||||||
<section id="grid">
|
<section id="grid">
|
||||||
<option id="snap" type="bool" default="false" />
|
<option id="snap" type="bool" default="false" />
|
||||||
<option id="bounds" type="gfx::Rect" default="gfx::Rect(0, 0, 16, 16)" />
|
<option id="bounds" type="gfx::Rect" default="doc::Sprite::DefaultGridBounds()" />
|
||||||
<option id="color" type="app::Color" default="app::Color::fromRgb(0, 0, 255)" />
|
<option id="color" type="app::Color" default="app::Color::fromRgb(0, 0, 255)" />
|
||||||
<option id="opacity" type="int" default="160" />
|
<option id="opacity" type="int" default="160" />
|
||||||
<option id="auto_opacity" type="bool" default="true" />
|
<option id="auto_opacity" type="bool" default="true" />
|
||||||
|
@ -71,7 +71,12 @@ A 128-byte header (same as FLC/FLI header, but with other magic number):
|
|||||||
BYTE Pixel width (pixel ratio is "pixel width/pixel height").
|
BYTE Pixel width (pixel ratio is "pixel width/pixel height").
|
||||||
If this or pixel height field is zero, pixel ratio is 1:1
|
If this or pixel height field is zero, pixel ratio is 1:1
|
||||||
BYTE Pixel height
|
BYTE Pixel height
|
||||||
BYTE[92] For future (set to zero)
|
SHORT X position of the grid
|
||||||
|
SHORT Y position of the grid
|
||||||
|
WORD Grid width (zero if there is no grid, grid size
|
||||||
|
is 16x16 on Aseprite by default)
|
||||||
|
WORD Grid height (zero if there is no grid)
|
||||||
|
BYTE[84] For future (set to zero)
|
||||||
|
|
||||||
## Frames
|
## Frames
|
||||||
|
|
||||||
|
@ -452,6 +452,7 @@ add_library(app-lib
|
|||||||
cmd/set_cel_opacity.cpp
|
cmd/set_cel_opacity.cpp
|
||||||
cmd/set_cel_position.cpp
|
cmd/set_cel_position.cpp
|
||||||
cmd/set_frame_duration.cpp
|
cmd/set_frame_duration.cpp
|
||||||
|
cmd/set_grid_bounds.cpp
|
||||||
cmd/set_last_point.cpp
|
cmd/set_last_point.cpp
|
||||||
cmd/set_layer_blend_mode.cpp
|
cmd/set_layer_blend_mode.cpp
|
||||||
cmd/set_layer_flags.cpp
|
cmd/set_layer_flags.cpp
|
||||||
|
54
src/app/cmd/set_grid_bounds.cpp
Normal file
54
src/app/cmd/set_grid_bounds.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/cmd/set_grid_bounds.h"
|
||||||
|
|
||||||
|
#include "app/doc.h"
|
||||||
|
#include "app/doc_event.h"
|
||||||
|
#include "app/doc_observer.h"
|
||||||
|
#include "doc/sprite.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace cmd {
|
||||||
|
|
||||||
|
using namespace doc;
|
||||||
|
|
||||||
|
SetGridBounds::SetGridBounds(Sprite* sprite, const gfx::Rect& bounds)
|
||||||
|
: WithSprite(sprite)
|
||||||
|
, m_oldBounds(sprite->gridBounds())
|
||||||
|
, m_newBounds(bounds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetGridBounds::onExecute()
|
||||||
|
{
|
||||||
|
Sprite* spr = sprite();
|
||||||
|
spr->setGridBounds(m_newBounds);
|
||||||
|
spr->incrementVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetGridBounds::onUndo()
|
||||||
|
{
|
||||||
|
Sprite* spr = sprite();
|
||||||
|
spr->setGridBounds(m_oldBounds);
|
||||||
|
spr->incrementVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetGridBounds::onFireNotifications()
|
||||||
|
{
|
||||||
|
Sprite* sprite = this->sprite();
|
||||||
|
Doc* doc = static_cast<Doc*>(sprite->document());
|
||||||
|
DocEvent ev(doc);
|
||||||
|
ev.sprite(sprite);
|
||||||
|
doc->notify_observers<DocEvent&>(&DocObserver::onSpriteGridBoundsChanged, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cmd
|
||||||
|
} // namespace app
|
43
src/app/cmd/set_grid_bounds.h
Normal file
43
src/app/cmd/set_grid_bounds.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifndef APP_CMD_SET_GRID_BOUNDS_H_INCLUDED
|
||||||
|
#define APP_CMD_SET_GRID_BOUNDS_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "app/cmd.h"
|
||||||
|
#include "app/cmd/with_sprite.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
|
||||||
|
namespace doc {
|
||||||
|
class Sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace cmd {
|
||||||
|
|
||||||
|
class SetGridBounds : public Cmd
|
||||||
|
, public WithSprite {
|
||||||
|
public:
|
||||||
|
SetGridBounds(doc::Sprite* sprite, const gfx::Rect& bounds);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onExecute() override;
|
||||||
|
void onUndo() override;
|
||||||
|
void onFireNotifications() override;
|
||||||
|
size_t onMemSize() const override {
|
||||||
|
return sizeof(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
gfx::Rect m_oldBounds;
|
||||||
|
gfx::Rect m_newBounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cmd
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -9,6 +10,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
|
#include "app/cmd/set_grid_bounds.h"
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/context.h"
|
#include "app/context.h"
|
||||||
#include "app/context_access.h"
|
#include "app/context_access.h"
|
||||||
@ -17,6 +19,7 @@
|
|||||||
#include "app/load_widget.h"
|
#include "app/load_widget.h"
|
||||||
#include "app/modules/editors.h"
|
#include "app/modules/editors.h"
|
||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/tx.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "doc/document.h"
|
#include "doc/document.h"
|
||||||
@ -25,6 +28,8 @@
|
|||||||
|
|
||||||
#include "grid_settings.xml.h"
|
#include "grid_settings.xml.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
@ -38,12 +43,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onChecked(Context* ctx) override {
|
bool onChecked(Context* ctx) override {
|
||||||
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
|
auto& docPref = Preferences::instance().document(ctx->activeDocument());
|
||||||
return docPref.grid.snap();
|
return docPref.grid.snap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onExecute(Context* ctx) override {
|
void onExecute(Context* ctx) override {
|
||||||
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
|
auto& docPref = Preferences::instance().document(ctx->activeDocument());
|
||||||
bool newValue = !docPref.grid.snap();
|
bool newValue = !docPref.grid.snap();
|
||||||
docPref.grid.snap(newValue);
|
docPref.grid.snap(newValue);
|
||||||
|
|
||||||
@ -59,21 +64,23 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onEnabled(Context* ctx) override {
|
bool onEnabled(Context* ctx) override {
|
||||||
return (ctx->activeDocument() &&
|
return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||||
ctx->activeDocument()->isMaskVisible());
|
ContextFlags::HasVisibleMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onExecute(Context* ctx) override {
|
void onExecute(Context* ctx) override {
|
||||||
const ContextReader reader(ctx);
|
ContextWriter writer(ctx, 500);
|
||||||
const Doc* document = reader.document();
|
Doc* doc = writer.document();
|
||||||
const Mask* mask(document->mask());
|
const Mask* mask = doc->mask();
|
||||||
DocumentPreferences& docPref =
|
gfx::Rect newGrid = mask->bounds();
|
||||||
Preferences::instance().document(ctx->activeDocument());
|
|
||||||
|
|
||||||
docPref.grid.bounds(mask->bounds());
|
Tx tx(writer.context(), friendlyName(), ModifyDocument);
|
||||||
|
tx(new cmd::SetGridBounds(writer.sprite(), newGrid));
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
// Make grid visible
|
auto& docPref = Preferences::instance().document(doc);
|
||||||
if (!docPref.show.grid())
|
docPref.grid.bounds(newGrid);
|
||||||
|
if (!docPref.show.grid()) // Make grid visible
|
||||||
docPref.show.grid(true);
|
docPref.show.grid(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -101,8 +108,8 @@ void GridSettingsCommand::onExecute(Context* context)
|
|||||||
{
|
{
|
||||||
gen::GridSettings window;
|
gen::GridSettings window;
|
||||||
|
|
||||||
DocumentPreferences& docPref = Preferences::instance().document(context->activeDocument());
|
Site site = context->activeSite();
|
||||||
Rect bounds = docPref.grid.bounds();
|
Rect bounds = site.gridBounds();
|
||||||
|
|
||||||
window.gridX()->setTextf("%d", bounds.x);
|
window.gridX()->setTextf("%d", bounds.x);
|
||||||
window.gridY()->setTextf("%d", bounds.y);
|
window.gridY()->setTextf("%d", bounds.y);
|
||||||
@ -115,13 +122,17 @@ void GridSettingsCommand::onExecute(Context* context)
|
|||||||
bounds.y = window.gridY()->textInt();
|
bounds.y = window.gridY()->textInt();
|
||||||
bounds.w = window.gridW()->textInt();
|
bounds.w = window.gridW()->textInt();
|
||||||
bounds.h = window.gridH()->textInt();
|
bounds.h = window.gridH()->textInt();
|
||||||
bounds.w = MAX(bounds.w, 1);
|
bounds.w = std::max(bounds.w, 1);
|
||||||
bounds.h = MAX(bounds.h, 1);
|
bounds.h = std::max(bounds.h, 1);
|
||||||
|
|
||||||
|
ContextWriter writer(context, 500);
|
||||||
|
Tx tx(context, friendlyName(), ModifyDocument);
|
||||||
|
tx(new cmd::SetGridBounds(site.sprite(), bounds));
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
|
auto& docPref = Preferences::instance().document(site.document());
|
||||||
docPref.grid.bounds(bounds);
|
docPref.grid.bounds(bounds);
|
||||||
|
if (!docPref.show.grid()) // Make grid visible
|
||||||
// Make grid visible
|
|
||||||
if (!docPref.show.grid())
|
|
||||||
docPref.show.grid(true);
|
docPref.show.grid(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ private:
|
|||||||
|
|
||||||
gfx::Rect defBounds = m_docPref->importSpriteSheet.bounds();
|
gfx::Rect defBounds = m_docPref->importSpriteSheet.bounds();
|
||||||
if (defBounds.isEmpty())
|
if (defBounds.isEmpty())
|
||||||
defBounds = m_docPref->grid.bounds();
|
defBounds = m_document->sprite()->gridBounds();
|
||||||
onChangeRectangle(defBounds);
|
onChangeRectangle(defBounds);
|
||||||
|
|
||||||
gfx::Size defPaddingBounds = m_docPref->importSpriteSheet.paddingBounds();
|
gfx::Size defPaddingBounds = m_docPref->importSpriteSheet.paddingBounds();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -20,6 +21,7 @@
|
|||||||
#include "app/job.h"
|
#include "app/job.h"
|
||||||
#include "app/modules/editors.h"
|
#include "app/modules/editors.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
#include "app/recent_files.h"
|
#include "app/recent_files.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
@ -191,12 +193,27 @@ void OpenFileCommand::onExecute(Context* context)
|
|||||||
if (fop->hasError() && !fop->isStop())
|
if (fop->hasError() && !fop->isStop())
|
||||||
console.printf(fop->error().c_str());
|
console.printf(fop->error().c_str());
|
||||||
|
|
||||||
Doc* document = fop->document();
|
Doc* doc = fop->document();
|
||||||
if (document) {
|
if (doc) {
|
||||||
if (context->isUIAvailable())
|
if (context->isUIAvailable()) {
|
||||||
App::instance()->recentFiles()->addRecentFile(fop->filename().c_str());
|
App::instance()->recentFiles()->addRecentFile(fop->filename().c_str());
|
||||||
|
auto& docPref = Preferences::instance().document(doc);
|
||||||
|
|
||||||
document->setContext(context);
|
if (fop->hasEmbeddedGridBounds() &&
|
||||||
|
!doc->sprite()->gridBounds().isEmpty()) {
|
||||||
|
// If the sprite contains the grid bounds inside, we put
|
||||||
|
// those grid bounds into the settings (e.g. useful to
|
||||||
|
// interact with old versions of Aseprite saving the grid
|
||||||
|
// bounds in the aseprite.ini file)
|
||||||
|
docPref.grid.bounds(doc->sprite()->gridBounds());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Get grid bounds from preferences
|
||||||
|
doc->sprite()->setGridBounds(docPref.grid.bounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc->setContext(context);
|
||||||
}
|
}
|
||||||
else if (!fop->isStop())
|
else if (!fop->isStop())
|
||||||
unrecent = true;
|
unrecent = true;
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
|
#include "app/cmd/set_grid_bounds.h"
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/console.h"
|
#include "app/console.h"
|
||||||
#include "app/context.h"
|
#include "app/context.h"
|
||||||
|
#include "app/context_access.h"
|
||||||
#include "app/extensions.h"
|
#include "app/extensions.h"
|
||||||
#include "app/file/file.h"
|
#include "app/file/file.h"
|
||||||
#include "app/file_selector.h"
|
#include "app/file_selector.h"
|
||||||
@ -23,6 +25,7 @@
|
|||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
#include "app/recent_files.h"
|
#include "app/recent_files.h"
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
|
#include "app/tx.h"
|
||||||
#include "app/ui/color_button.h"
|
#include "app/ui/color_button.h"
|
||||||
#include "app/ui/pref_widget.h"
|
#include "app/ui/pref_widget.h"
|
||||||
#include "app/ui/separator_in_view.h"
|
#include "app/ui/separator_in_view.h"
|
||||||
@ -163,7 +166,8 @@ class OptionsWindow : public app::gen::Options {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
OptionsWindow(Context* context, int& curSection)
|
OptionsWindow(Context* context, int& curSection)
|
||||||
: m_pref(Preferences::instance())
|
: m_context(context)
|
||||||
|
, m_pref(Preferences::instance())
|
||||||
, m_globPref(m_pref.document(nullptr))
|
, m_globPref(m_pref.document(nullptr))
|
||||||
, m_docPref(m_pref.document(context->activeDocument()))
|
, m_docPref(m_pref.document(context->activeDocument()))
|
||||||
, m_curPref(&m_docPref)
|
, m_curPref(&m_docPref)
|
||||||
@ -586,6 +590,14 @@ public:
|
|||||||
}
|
}
|
||||||
update_displays_color_profile_from_preferences();
|
update_displays_color_profile_from_preferences();
|
||||||
|
|
||||||
|
// Change sprite grid bounds
|
||||||
|
if (m_context && m_context->activeDocument()) {
|
||||||
|
ContextWriter writer(m_context, 500);
|
||||||
|
Tx tx(m_context, Strings::commands_GridSettings(), ModifyDocument);
|
||||||
|
tx(new cmd::SetGridBounds(writer.sprite(), gridBounds()));
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
m_curPref->show.grid(gridVisible()->isSelected());
|
m_curPref->show.grid(gridVisible()->isSelected());
|
||||||
m_curPref->grid.bounds(gridBounds());
|
m_curPref->grid.bounds(gridBounds());
|
||||||
m_curPref->grid.color(gridColor()->getColor());
|
m_curPref->grid.color(gridColor()->getColor());
|
||||||
@ -1390,6 +1402,7 @@ private:
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Context* m_context;
|
||||||
Preferences& m_pref;
|
Preferences& m_pref;
|
||||||
DocumentPreferences& m_globPref;
|
DocumentPreferences& m_globPref;
|
||||||
DocumentPreferences& m_docPref;
|
DocumentPreferences& m_docPref;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
#include "app/modules/editors.h"
|
#include "app/modules/editors.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/pref/preferences.h"
|
|
||||||
#include "app/snap_to_grid.h"
|
#include "app/snap_to_grid.h"
|
||||||
#include "app/tx.h"
|
#include "app/tx.h"
|
||||||
#include "app/ui/editor/editor.h"
|
#include "app/ui/editor/editor.h"
|
||||||
@ -75,7 +74,6 @@ void SelectTileCommand::onExecute(Context* ctx)
|
|||||||
// Lock sprite
|
// Lock sprite
|
||||||
ContextWriter writer(ctx);
|
ContextWriter writer(ctx);
|
||||||
Doc* doc(writer.document());
|
Doc* doc(writer.document());
|
||||||
auto& docPref = Preferences::instance().document(doc);
|
|
||||||
|
|
||||||
std::unique_ptr<Mask> mask(new Mask());
|
std::unique_ptr<Mask> mask(new Mask());
|
||||||
|
|
||||||
@ -83,7 +81,7 @@ void SelectTileCommand::onExecute(Context* ctx)
|
|||||||
mask->copyFrom(doc->mask());
|
mask->copyFrom(doc->mask());
|
||||||
|
|
||||||
{
|
{
|
||||||
gfx::Rect gridBounds = docPref.grid.bounds();
|
gfx::Rect gridBounds = doc->sprite()->gridBounds();
|
||||||
gfx::Point pos = current_editor->screenToEditor(ui::get_mouse_position());
|
gfx::Point pos = current_editor->screenToEditor(ui::get_mouse_position());
|
||||||
pos = snap_to_grid(gridBounds, pos, PreferSnapTo::BoxOrigin);
|
pos = snap_to_grid(gridBounds, pos, PreferSnapTo::BoxOrigin);
|
||||||
gridBounds.setOrigin(pos);
|
gridBounds.setOrigin(pos);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
// Copyright (C) 2017 David Capello
|
// Copyright (C) 2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -12,7 +13,6 @@
|
|||||||
|
|
||||||
#include "app/commands/params.h"
|
#include "app/commands/params.h"
|
||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
#include "app/pref/preferences.h"
|
|
||||||
#include "app/ui/doc_view.h"
|
#include "app/ui/doc_view.h"
|
||||||
#include "app/ui/editor/editor.h"
|
#include "app/ui/editor/editor.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
@ -78,10 +78,9 @@ gfx::Point MoveThing::getDelta(Context* context) const
|
|||||||
if (!view)
|
if (!view)
|
||||||
return delta;
|
return delta;
|
||||||
|
|
||||||
DocumentPreferences& docPref = Preferences::instance().document(view->document());
|
|
||||||
Editor* editor = view->editor();
|
Editor* editor = view->editor();
|
||||||
gfx::Rect vp = view->viewWidget()->viewportBounds();
|
gfx::Rect vp = view->viewWidget()->viewportBounds();
|
||||||
gfx::Rect gridBounds = docPref.grid.bounds();
|
gfx::Rect gridBounds = view->document()->sprite()->gridBounds();
|
||||||
int pixels = 0;
|
int pixels = 0;
|
||||||
|
|
||||||
switch (units) {
|
switch (units) {
|
||||||
|
@ -183,16 +183,17 @@ bool BackupObserver::saveDocData(Doc* doc)
|
|||||||
m_session->restoreBackupDocById(doc->id(), nullptr));
|
m_session->restoreBackupDocById(doc->id(), nullptr));
|
||||||
DocDiff diff = compare_docs(doc, copy.get());
|
DocDiff diff = compare_docs(doc, copy.get());
|
||||||
if (diff.anything) {
|
if (diff.anything) {
|
||||||
TRACE("RECO: Differences (%s/%s/%s/%s/%s/%s/%s)\n",
|
TRACEARGS("RECO: Differences:",
|
||||||
diff.canvas ? "canvas": "",
|
diff.canvas ? "canvas": "",
|
||||||
diff.totalFrames ? "totalFrames": "",
|
diff.totalFrames ? "totalFrames": "",
|
||||||
diff.frameDuration ? "frameDuration": "",
|
diff.frameDuration ? "frameDuration": "",
|
||||||
diff.frameTags ? "frameTags": "",
|
diff.tags ? "tags": "",
|
||||||
diff.palettes ? "palettes": "",
|
diff.palettes ? "palettes": "",
|
||||||
diff.layers ? "layers": "",
|
diff.layers ? "layers": "",
|
||||||
diff.cels ? "cels": "",
|
diff.cels ? "cels": "",
|
||||||
diff.images ? "images": "",
|
diff.images ? "images": "",
|
||||||
diff.colorProfiles ? "colorProfiles": "");
|
diff.colorProfiles ? "colorProfiles": "",
|
||||||
|
diff.gridBounds ? "gridBounds": "");
|
||||||
|
|
||||||
Doc* copyDoc = copy.release();
|
Doc* copyDoc = copy.release();
|
||||||
ui::execute_from_ui_thread(
|
ui::execute_from_ui_thread(
|
||||||
|
@ -345,6 +345,11 @@ private:
|
|||||||
if (colorSpace)
|
if (colorSpace)
|
||||||
spr->setColorSpace(colorSpace);
|
spr->setColorSpace(colorSpace);
|
||||||
|
|
||||||
|
// Read grid bounds
|
||||||
|
gfx::Rect gridBounds = readGridBounds(s);
|
||||||
|
if (!gridBounds.isEmpty())
|
||||||
|
spr->setGridBounds(gridBounds);
|
||||||
|
|
||||||
return spr.release();
|
return spr.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +369,15 @@ private:
|
|||||||
return colorSpace;
|
return colorSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::Rect readGridBounds(std::ifstream& s) {
|
||||||
|
gfx::Rect grid;
|
||||||
|
grid.x = (int16_t)read16(s);
|
||||||
|
grid.y = (int16_t)read16(s);
|
||||||
|
grid.w = read16(s);
|
||||||
|
grid.h = read16(s);
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO could we use doc::read_layer() here?
|
// TODO could we use doc::read_layer() here?
|
||||||
Layer* readLayer(std::ifstream& s) {
|
Layer* readLayer(std::ifstream& s) {
|
||||||
LayerFlags flags = (LayerFlags)read32(s);
|
LayerFlags flags = (LayerFlags)read32(s);
|
||||||
|
@ -170,6 +170,17 @@ private:
|
|||||||
// Color Space
|
// Color Space
|
||||||
writeColorSpace(s, spr->colorSpace());
|
writeColorSpace(s, spr->colorSpace());
|
||||||
|
|
||||||
|
// Grid bounds
|
||||||
|
writeGridBounds(s, spr->gridBounds());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool writeGridBounds(std::ofstream& s, const gfx::Rect& grid) {
|
||||||
|
write16(s, (int16_t)grid.x);
|
||||||
|
write16(s, (int16_t)grid.y);
|
||||||
|
write16(s, grid.w);
|
||||||
|
write16(s, grid.h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,13 +334,13 @@ void DocApi::trimSprite(Sprite* sprite, const bool byGrid)
|
|||||||
// TODO merge this code with the code in DocExporter::captureSamples()
|
// TODO merge this code with the code in DocExporter::captureSamples()
|
||||||
if (byGrid) {
|
if (byGrid) {
|
||||||
Doc* doc = m_document;
|
Doc* doc = m_document;
|
||||||
auto& docPref = Preferences::instance().document(doc);
|
const gfx::Rect& gridBounds = doc->sprite()->gridBounds();
|
||||||
gfx::Point posTopLeft =
|
gfx::Point posTopLeft =
|
||||||
snap_to_grid(docPref.grid.bounds(),
|
snap_to_grid(gridBounds,
|
||||||
bounds.origin(),
|
bounds.origin(),
|
||||||
PreferSnapTo::FloorGrid);
|
PreferSnapTo::FloorGrid);
|
||||||
gfx::Point posBottomRight =
|
gfx::Point posBottomRight =
|
||||||
snap_to_grid(docPref.grid.bounds(),
|
snap_to_grid(gridBounds,
|
||||||
bounds.point2(),
|
bounds.point2(),
|
||||||
PreferSnapTo::CeilGrid);
|
PreferSnapTo::CeilGrid);
|
||||||
bounds = gfx::Rect(posTopLeft, posBottomRight);
|
bounds = gfx::Rect(posTopLeft, posBottomRight);
|
||||||
|
@ -144,6 +144,11 @@ DocDiff compare_docs(const Doc* a,
|
|||||||
diff.anything = diff.colorProfiles = true;
|
diff.anything = diff.colorProfiles = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare grid bounds
|
||||||
|
if (a->sprite()->gridBounds() != b->sprite()->gridBounds()) {
|
||||||
|
diff.anything = diff.gridBounds = true;
|
||||||
|
}
|
||||||
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
// Copyright (C) 2018 David Capello
|
// Copyright (C) 2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -22,6 +23,7 @@ namespace app {
|
|||||||
bool cels : 1;
|
bool cels : 1;
|
||||||
bool images : 1;
|
bool images : 1;
|
||||||
bool colorProfiles : 1;
|
bool colorProfiles : 1;
|
||||||
|
bool gridBounds : 1;
|
||||||
|
|
||||||
DocDiff() :
|
DocDiff() :
|
||||||
anything(false),
|
anything(false),
|
||||||
@ -33,7 +35,8 @@ namespace app {
|
|||||||
layers(false),
|
layers(false),
|
||||||
cels(false),
|
cels(false),
|
||||||
images(false),
|
images(false),
|
||||||
colorProfiles(false) {
|
colorProfiles(false),
|
||||||
|
gridBounds(false) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -698,13 +698,13 @@ void DocExporter::captureSamples(Samples& samples)
|
|||||||
if (m_trimCels) {
|
if (m_trimCels) {
|
||||||
// TODO merge this code with the code in DocApi::trimSprite()
|
// TODO merge this code with the code in DocApi::trimSprite()
|
||||||
if (m_trimByGrid) {
|
if (m_trimByGrid) {
|
||||||
auto& docPref = Preferences::instance().document(doc);
|
const gfx::Rect& gridBounds = doc->sprite()->gridBounds();
|
||||||
gfx::Point posTopLeft =
|
gfx::Point posTopLeft =
|
||||||
snap_to_grid(docPref.grid.bounds(),
|
snap_to_grid(gridBounds,
|
||||||
frameBounds.origin(),
|
frameBounds.origin(),
|
||||||
PreferSnapTo::FloorGrid);
|
PreferSnapTo::FloorGrid);
|
||||||
gfx::Point posBottomRight =
|
gfx::Point posBottomRight =
|
||||||
snap_to_grid(docPref.grid.bounds(),
|
snap_to_grid(gridBounds,
|
||||||
frameBounds.point2(),
|
frameBounds.point2(),
|
||||||
PreferSnapTo::CeilGrid);
|
PreferSnapTo::CeilGrid);
|
||||||
frameBounds = gfx::Rect(posTopLeft, posBottomRight);
|
frameBounds = gfx::Rect(posTopLeft, posBottomRight);
|
||||||
|
@ -46,6 +46,7 @@ namespace app {
|
|||||||
virtual void onSpriteSizeChanged(DocEvent& ev) { }
|
virtual void onSpriteSizeChanged(DocEvent& ev) { }
|
||||||
virtual void onSpriteTransparentColorChanged(DocEvent& ev) { }
|
virtual void onSpriteTransparentColorChanged(DocEvent& ev) { }
|
||||||
virtual void onSpritePixelRatioChanged(DocEvent& ev) { }
|
virtual void onSpritePixelRatioChanged(DocEvent& ev) { }
|
||||||
|
virtual void onSpriteGridBoundsChanged(DocEvent& ev) { }
|
||||||
|
|
||||||
virtual void onLayerNameChange(DocEvent& ev) { }
|
virtual void onLayerNameChange(DocEvent& ev) { }
|
||||||
virtual void onLayerOpacityChange(DocEvent& ev) { }
|
virtual void onLayerOpacityChange(DocEvent& ev) { }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018 Igara Studio S.A.
|
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -208,6 +208,12 @@ bool AseFormat::onLoad(FileOp* fop)
|
|||||||
fop->setEmbeddedColorProfile();
|
fop->setEmbeddedColorProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sprite grid bounds will be set to empty (instead of
|
||||||
|
// doc::Sprite::DefaultGridBounds()) if the file doesn't contain an
|
||||||
|
// embedded grid bounds.
|
||||||
|
if (!sprite->gridBounds().isEmpty())
|
||||||
|
fop->setEmbeddedGridBounds();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,6 +377,10 @@ static void ase_file_prepare_header(FILE* f, dio::AsepriteHeader* header, const
|
|||||||
header->ncolors = sprite->palette(firstFrame)->size();
|
header->ncolors = sprite->palette(firstFrame)->size();
|
||||||
header->pixel_width = sprite->pixelRatio().w;
|
header->pixel_width = sprite->pixelRatio().w;
|
||||||
header->pixel_height = sprite->pixelRatio().h;
|
header->pixel_height = sprite->pixelRatio().h;
|
||||||
|
header->grid_x = sprite->gridBounds().x;
|
||||||
|
header->grid_y = sprite->gridBounds().y;
|
||||||
|
header->grid_width = sprite->gridBounds().w;
|
||||||
|
header->grid_height = sprite->gridBounds().h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ase_file_write_header(FILE* f, dio::AsepriteHeader* header)
|
static void ase_file_write_header(FILE* f, dio::AsepriteHeader* header)
|
||||||
@ -394,6 +404,10 @@ static void ase_file_write_header(FILE* f, dio::AsepriteHeader* header)
|
|||||||
fputw(header->ncolors, f);
|
fputw(header->ncolors, f);
|
||||||
fputc(header->pixel_width, f);
|
fputc(header->pixel_width, f);
|
||||||
fputc(header->pixel_height, f);
|
fputc(header->pixel_height, f);
|
||||||
|
fputw(header->grid_x, f);
|
||||||
|
fputw(header->grid_y, f);
|
||||||
|
fputw(header->grid_width, f);
|
||||||
|
fputw(header->grid_height, f);
|
||||||
|
|
||||||
fseek(f, header->pos+128, SEEK_SET);
|
fseek(f, header->pos+128, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
@ -1190,6 +1190,7 @@ FileOp::FileOp(FileOpType type,
|
|||||||
, m_createPaletteFromRgba(false)
|
, m_createPaletteFromRgba(false)
|
||||||
, m_ignoreEmpty(false)
|
, m_ignoreEmpty(false)
|
||||||
, m_embeddedColorProfile(false)
|
, m_embeddedColorProfile(false)
|
||||||
|
, m_embeddedGridBounds(false)
|
||||||
{
|
{
|
||||||
if (config)
|
if (config)
|
||||||
m_config = *config;
|
m_config = *config;
|
||||||
|
@ -209,6 +209,9 @@ namespace app {
|
|||||||
void setEmbeddedColorProfile() { m_embeddedColorProfile = true; }
|
void setEmbeddedColorProfile() { m_embeddedColorProfile = true; }
|
||||||
bool hasEmbeddedColorProfile() const { return m_embeddedColorProfile; }
|
bool hasEmbeddedColorProfile() const { return m_embeddedColorProfile; }
|
||||||
|
|
||||||
|
void setEmbeddedGridBounds() { m_embeddedGridBounds = true; }
|
||||||
|
bool hasEmbeddedGridBounds() const { return m_embeddedGridBounds; }
|
||||||
|
|
||||||
bool newBlend() const { return m_config.newBlend; }
|
bool newBlend() const { return m_config.newBlend; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -243,6 +246,9 @@ namespace app {
|
|||||||
// True if the file contained a color profile when it was loaded.
|
// True if the file contained a color profile when it was loaded.
|
||||||
bool m_embeddedColorProfile;
|
bool m_embeddedColorProfile;
|
||||||
|
|
||||||
|
// True if the file contained a the grid bounds inside.
|
||||||
|
bool m_embeddedGridBounds;
|
||||||
|
|
||||||
FileOpConfig m_config;
|
FileOpConfig m_config;
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "doc/color_mode.h"
|
#include "doc/color_mode.h"
|
||||||
#include "doc/frame.h"
|
#include "doc/frame.h"
|
||||||
#include "doc/layer_list.h"
|
#include "doc/layer_list.h"
|
||||||
|
#include "doc/sprite.h"
|
||||||
#include "filters/tiled_mode.h"
|
#include "filters/tiled_mode.h"
|
||||||
#include "gfx/rect.h"
|
#include "gfx/rect.h"
|
||||||
#include "render/onionskin_position.h"
|
#include "render/onionskin_position.h"
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
|
|
||||||
// Increment this value if the scripting API is modified between two
|
// Increment this value if the scripting API is modified between two
|
||||||
// released Aseprite versions.
|
// released Aseprite versions.
|
||||||
#define API_VERSION 6
|
#define API_VERSION 7
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "app/cmd/remove_layer.h"
|
#include "app/cmd/remove_layer.h"
|
||||||
#include "app/cmd/remove_slice.h"
|
#include "app/cmd/remove_slice.h"
|
||||||
#include "app/cmd/remove_tag.h"
|
#include "app/cmd/remove_tag.h"
|
||||||
|
#include "app/cmd/set_grid_bounds.h"
|
||||||
#include "app/cmd/set_mask.h"
|
#include "app/cmd/set_mask.h"
|
||||||
#include "app/cmd/set_sprite_size.h"
|
#include "app/cmd/set_sprite_size.h"
|
||||||
#include "app/cmd/set_transparent_color.h"
|
#include "app/cmd/set_transparent_color.h"
|
||||||
@ -735,6 +736,23 @@ int Sprite_get_bounds(lua_State* L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Sprite_get_gridBounds(lua_State* L)
|
||||||
|
{
|
||||||
|
const auto sprite = get_docobj<Sprite>(L, 1);
|
||||||
|
push_obj<gfx::Rect>(L, sprite->gridBounds());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Sprite_set_gridBounds(lua_State* L)
|
||||||
|
{
|
||||||
|
auto sprite = get_docobj<Sprite>(L, 1);
|
||||||
|
const gfx::Rect bounds = convert_args_into_rect(L, 2);
|
||||||
|
Tx tx;
|
||||||
|
tx(new cmd::SetGridBounds(sprite, bounds));
|
||||||
|
tx.commit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg Sprite_methods[] = {
|
const luaL_Reg Sprite_methods[] = {
|
||||||
{ "__eq", Sprite_eq },
|
{ "__eq", Sprite_eq },
|
||||||
{ "resize", Sprite_resize },
|
{ "resize", Sprite_resize },
|
||||||
@ -784,6 +802,7 @@ const Property Sprite_properties[] = {
|
|||||||
{ "backgroundLayer", Sprite_get_backgroundLayer, nullptr },
|
{ "backgroundLayer", Sprite_get_backgroundLayer, nullptr },
|
||||||
{ "transparentColor", Sprite_get_transparentColor, Sprite_set_transparentColor },
|
{ "transparentColor", Sprite_get_transparentColor, Sprite_set_transparentColor },
|
||||||
{ "bounds", Sprite_get_bounds, nullptr },
|
{ "bounds", Sprite_get_bounds, nullptr },
|
||||||
|
{ "gridBounds", Sprite_get_gridBounds, Sprite_set_gridBounds },
|
||||||
{ nullptr, nullptr, nullptr }
|
{ nullptr, nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,10 +11,12 @@
|
|||||||
|
|
||||||
#include "app/site.h"
|
#include "app/site.h"
|
||||||
|
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
#include "base/base.h"
|
#include "base/base.h"
|
||||||
#include "doc/cel.h"
|
#include "doc/cel.h"
|
||||||
#include "doc/layer.h"
|
#include "doc/layer.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
|
#include "ui/system.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
@ -77,4 +79,20 @@ void Site::range(const DocRange& range)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::Rect Site::gridBounds() const
|
||||||
|
{
|
||||||
|
gfx::Rect bounds;
|
||||||
|
if (m_sprite) {
|
||||||
|
bounds = m_sprite->gridBounds();
|
||||||
|
if (!bounds.isEmpty())
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
if (ui::is_ui_thread()) {
|
||||||
|
bounds = Preferences::instance().document(m_document).grid.bounds();
|
||||||
|
if (!bounds.isEmpty())
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
return doc::Sprite::DefaultGridBounds();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "doc/frame.h"
|
#include "doc/frame.h"
|
||||||
#include "doc/palette_picks.h"
|
#include "doc/palette_picks.h"
|
||||||
#include "doc/selected_objects.h"
|
#include "doc/selected_objects.h"
|
||||||
|
#include "gfx/fwd.h"
|
||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
class Cel;
|
class Cel;
|
||||||
@ -98,6 +99,8 @@ namespace app {
|
|||||||
doc::Palette* palette() const;
|
doc::Palette* palette() const;
|
||||||
doc::RgbMap* rgbMap() const;
|
doc::RgbMap* rgbMap() const;
|
||||||
|
|
||||||
|
gfx::Rect gridBounds() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Focus m_focus;
|
Focus m_focus;
|
||||||
Doc* m_document;
|
Doc* m_document;
|
||||||
|
@ -728,7 +728,7 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
|||||||
|
|
||||||
// Draw the grid
|
// Draw the grid
|
||||||
if (m_docPref.show.grid()) {
|
if (m_docPref.show.grid()) {
|
||||||
gfx::Rect gridrc = m_docPref.grid.bounds();
|
gfx::Rect gridrc = m_sprite->gridBounds();
|
||||||
if (m_proj.applyX(gridrc.w) > 2 &&
|
if (m_proj.applyX(gridrc.w) > 2 &&
|
||||||
m_proj.applyY(gridrc.h) > 2) {
|
m_proj.applyY(gridrc.h) > 2) {
|
||||||
int alpha = m_docPref.grid.opacity();
|
int alpha = m_docPref.grid.opacity();
|
||||||
@ -740,9 +740,10 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
|||||||
alpha = MID(0, alpha, 255);
|
alpha = MID(0, alpha, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alpha > 8)
|
if (alpha > 8) {
|
||||||
drawGrid(g, enclosingRect, m_docPref.grid.bounds(),
|
drawGrid(g, enclosingRect, gridrc,
|
||||||
m_docPref.grid.color(), alpha);
|
m_docPref.grid.color(), alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,8 +343,7 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
|
|||||||
|
|
||||||
if ((moveModifier & SnapToGridMovement) == SnapToGridMovement) {
|
if ((moveModifier & SnapToGridMovement) == SnapToGridMovement) {
|
||||||
// Snap the x1,y1 point to the grid.
|
// Snap the x1,y1 point to the grid.
|
||||||
gfx::Rect gridBounds = App::instance()
|
gfx::Rect gridBounds = m_document->sprite()->gridBounds();
|
||||||
->preferences().document(m_document).grid.bounds();
|
|
||||||
gfx::PointF gridOffset(
|
gfx::PointF gridOffset(
|
||||||
snap_to_grid(
|
snap_to_grid(
|
||||||
gridBounds,
|
gridBounds,
|
||||||
|
@ -596,7 +596,7 @@ bool StandbyState::onUpdateStatusBar(Editor* editor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (editor->docPref().show.grid()) {
|
if (editor->docPref().show.grid()) {
|
||||||
auto gb = editor->docPref().grid.bounds();
|
auto gb = sprite->gridBounds();
|
||||||
if (!gb.isEmpty()) {
|
if (!gb.isEmpty()) {
|
||||||
int col = int((std::floor(spritePos.x) - (gb.x % gb.w)) / gb.w);
|
int col = int((std::floor(spritePos.x) - (gb.x % gb.w)) / gb.w);
|
||||||
int row = int((std::floor(spritePos.y) - (gb.y % gb.h)) / gb.h);
|
int row = int((std::floor(spritePos.y) - (gb.y % gb.h)) / gb.h);
|
||||||
|
@ -80,6 +80,7 @@ protected:
|
|||||||
int m_opacity;
|
int m_opacity;
|
||||||
int m_tolerance;
|
int m_tolerance;
|
||||||
bool m_contiguous;
|
bool m_contiguous;
|
||||||
|
gfx::Rect m_gridBounds;
|
||||||
gfx::Point m_celOrigin;
|
gfx::Point m_celOrigin;
|
||||||
gfx::Point m_speed;
|
gfx::Point m_speed;
|
||||||
tools::ToolLoop::Button m_button;
|
tools::ToolLoop::Button m_button;
|
||||||
@ -118,6 +119,7 @@ public:
|
|||||||
, m_opacity(m_toolPref.opacity())
|
, m_opacity(m_toolPref.opacity())
|
||||||
, m_tolerance(m_toolPref.tolerance())
|
, m_tolerance(m_toolPref.tolerance())
|
||||||
, m_contiguous(m_toolPref.contiguous())
|
, m_contiguous(m_toolPref.contiguous())
|
||||||
|
, m_gridBounds(site.gridBounds())
|
||||||
, m_button(button)
|
, m_button(button)
|
||||||
, m_ink(ink->clone())
|
, m_ink(ink->clone())
|
||||||
, m_controller(controller)
|
, m_controller(controller)
|
||||||
@ -252,7 +254,7 @@ public:
|
|||||||
== app::gen::PixelConnectivity::EIGHT_CONNECTED);
|
== app::gen::PixelConnectivity::EIGHT_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Rect getGridBounds() override { return m_docPref.grid.bounds(); }
|
gfx::Rect getGridBounds() override { return m_gridBounds; }
|
||||||
gfx::Point getCelOrigin() override { return m_celOrigin; }
|
gfx::Point getCelOrigin() override { return m_celOrigin; }
|
||||||
void setSpeed(const gfx::Point& speed) override { m_speed = speed; }
|
void setSpeed(const gfx::Point& speed) override { m_speed = speed; }
|
||||||
gfx::Point getSpeed() override { return m_speed; }
|
gfx::Point getSpeed() override { return m_speed; }
|
||||||
|
@ -72,6 +72,10 @@ struct AsepriteHeader {
|
|||||||
uint16_t ncolors;
|
uint16_t ncolors;
|
||||||
uint8_t pixel_width;
|
uint8_t pixel_width;
|
||||||
uint8_t pixel_height;
|
uint8_t pixel_height;
|
||||||
|
int16_t grid_x;
|
||||||
|
int16_t grid_y;
|
||||||
|
uint16_t grid_width;
|
||||||
|
uint16_t grid_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AsepriteFrameHeader {
|
struct AsepriteFrameHeader {
|
||||||
|
@ -58,6 +58,10 @@ bool AsepriteDecoder::decode()
|
|||||||
// Set pixel ratio
|
// Set pixel ratio
|
||||||
sprite->setPixelRatio(doc::PixelRatio(header.pixel_width, header.pixel_height));
|
sprite->setPixelRatio(doc::PixelRatio(header.pixel_width, header.pixel_height));
|
||||||
|
|
||||||
|
// Set grid bounds
|
||||||
|
sprite->setGridBounds(gfx::Rect(header.grid_x, header.grid_y,
|
||||||
|
header.grid_width, header.grid_height));
|
||||||
|
|
||||||
// Prepare variables for layer chunks
|
// Prepare variables for layer chunks
|
||||||
doc::Layer* last_layer = sprite->root();
|
doc::Layer* last_layer = sprite->root();
|
||||||
doc::WithUserData* last_object_with_user_data = nullptr;
|
doc::WithUserData* last_object_with_user_data = nullptr;
|
||||||
@ -252,6 +256,10 @@ bool AsepriteDecoder::readHeader(AsepriteHeader* header)
|
|||||||
header->ncolors = read16();
|
header->ncolors = read16();
|
||||||
header->pixel_width = read8();
|
header->pixel_width = read8();
|
||||||
header->pixel_height = read8();
|
header->pixel_height = read8();
|
||||||
|
header->grid_x = (int16_t)read16();
|
||||||
|
header->grid_y = (int16_t)read16();
|
||||||
|
header->grid_width = read16();
|
||||||
|
header->grid_height = read16();
|
||||||
|
|
||||||
if (header->ncolors == 0) // 0 means 256 (old .ase files)
|
if (header->ncolors == 0) // 0 means 256 (old .ase files)
|
||||||
header->ncolors = 256;
|
header->ncolors = 256;
|
||||||
@ -588,8 +596,8 @@ doc::Cel* AsepriteDecoder::readCelChunk(doc::Sprite* sprite,
|
|||||||
{
|
{
|
||||||
// Read chunk data
|
// Read chunk data
|
||||||
doc::layer_t layer_index = read16();
|
doc::layer_t layer_index = read16();
|
||||||
int x = ((short)read16());
|
int x = ((int16_t)read16());
|
||||||
int y = ((short)read16());
|
int y = ((int16_t)read16());
|
||||||
int opacity = read8();
|
int opacity = read8();
|
||||||
int cel_type = read16();
|
int cel_type = read16();
|
||||||
readPadding(7);
|
readPadding(7);
|
||||||
|
@ -34,6 +34,9 @@ namespace doc {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Constructors/Destructor
|
// Constructors/Destructor
|
||||||
|
|
||||||
|
// static
|
||||||
|
gfx::Rect Sprite::DefaultGridBounds() { return gfx::Rect(0, 0, 16, 16); }
|
||||||
|
|
||||||
Sprite::Sprite(const ImageSpec& spec,
|
Sprite::Sprite(const ImageSpec& spec,
|
||||||
int ncolors)
|
int ncolors)
|
||||||
: Object(ObjectType::Sprite)
|
: Object(ObjectType::Sprite)
|
||||||
@ -43,6 +46,7 @@ Sprite::Sprite(const ImageSpec& spec,
|
|||||||
, m_frames(1)
|
, m_frames(1)
|
||||||
, m_frlens(1, 100) // First frame with 100 msecs of duration
|
, m_frlens(1, 100) // First frame with 100 msecs of duration
|
||||||
, m_root(new LayerGroup(this))
|
, m_root(new LayerGroup(this))
|
||||||
|
, m_gridBounds(Sprite::DefaultGridBounds())
|
||||||
, m_rgbMap(nullptr) // Initial RGB map
|
, m_rgbMap(nullptr) // Initial RGB map
|
||||||
, m_tags(this)
|
, m_tags(this)
|
||||||
, m_slices(this)
|
, m_slices(this)
|
||||||
|
@ -98,6 +98,10 @@ namespace doc {
|
|||||||
color_t transparentColor() const { return m_spec.maskColor(); }
|
color_t transparentColor() const { return m_spec.maskColor(); }
|
||||||
void setTransparentColor(color_t color);
|
void setTransparentColor(color_t color);
|
||||||
|
|
||||||
|
static gfx::Rect DefaultGridBounds();
|
||||||
|
const gfx::Rect& gridBounds() const { return m_gridBounds; }
|
||||||
|
void setGridBounds(const gfx::Rect& rc) { m_gridBounds = rc; }
|
||||||
|
|
||||||
virtual int getMemSize() const override;
|
virtual int getMemSize() const override;
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
@ -188,6 +192,7 @@ namespace doc {
|
|||||||
std::vector<int> m_frlens; // duration per frame
|
std::vector<int> m_frlens; // duration per frame
|
||||||
PalettesList m_palettes; // list of palettes
|
PalettesList m_palettes; // list of palettes
|
||||||
LayerGroup* m_root; // main group of layers
|
LayerGroup* m_root; // main group of layers
|
||||||
|
gfx::Rect m_gridBounds; // grid settings
|
||||||
|
|
||||||
// Current rgb map
|
// Current rgb map
|
||||||
mutable RgbMap* m_rgbMap;
|
mutable RgbMap* m_rgbMap;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user