[aseprite] 124/134: Add --trim command line option
Tobias Hansen
thansen at moszumanska.debian.org
Sat Mar 14 17:10:17 UTC 2015
This is an automated email from the git hooks/post-receive script.
thansen pushed a commit to branch master
in repository aseprite.
commit 9546c0a5e3bcbc8e707a08ed83d9545a30c3c568
Author: David Capello <davidcapello at gmail.com>
Date: Mon Feb 2 10:42:07 2015 -0300
Add --trim command line option
---
src/app/app.cpp | 38 ++++++++++--
src/app/app_options.cpp | 1 +
src/app/app_options.h | 2 +
src/app/commands/cmd_undo.cpp | 12 ++--
src/app/document_exporter.cpp | 106 +++++++++++++++++++---------------
src/app/document_exporter.h | 13 ++++-
src/app/settings/ui_settings_impl.cpp | 6 +-
7 files changed, 117 insertions(+), 61 deletions(-)
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 9119a06..7425a6b 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -1,5 +1,5 @@
/* Aseprite
- * Copyright (C) 2001-2014 David Capello
+ * Copyright (C) 2001-2015 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -213,6 +213,7 @@ void App::initialize(const AppOptions& options)
PRINTF("Processing options...\n");
bool ignoreEmpty = false;
+ bool trim = false;
// Open file specified in the command line
if (!options.values().empty()) {
@@ -267,6 +268,10 @@ void App::initialize(const AppOptions& options)
else if (opt == &options.ignoreEmpty()) {
ignoreEmpty = true;
}
+ // --trim
+ else if (opt == &options.trim()) {
+ trim = true;
+ }
// --filename-format
else if (opt == &options.filenameFormat()) {
filenameFormat = value.value();
@@ -285,7 +290,10 @@ void App::initialize(const AppOptions& options)
std::string format = filenameFormat;
- Command* command = CommandsModule::instance()->getCommandByName(CommandId::SaveFileCopyAs);
+ Command* saveAsCommand = CommandsModule::instance()->getCommandByName(CommandId::SaveFileCopyAs);
+ Command* trimCommand = CommandsModule::instance()->getCommandByName(CommandId::AutocropSprite);
+ Command* undoCommand = CommandsModule::instance()->getCommandByName(CommandId::Undo);
+
if (splitLayersSaveAs) {
std::vector<Layer*> layers;
doc->sprite()->getLayersList(layers);
@@ -308,10 +316,21 @@ void App::initialize(const AppOptions& options)
fmt = filename_formatter(format,
value.value(), show->name(), -1, false);
+ // TODO --trim command with --save-as doesn't make too
+ // much sense as we lost the trim rectangle
+ // information (e.g. we don't have sheet .json) Also,
+ // we should trim each frame individually (a process
+ // that can be done only in fop_operate()).
+ if (trim)
+ ctx->executeCommand(trimCommand);
+
Params params;
params.set("filename", fn.c_str());
params.set("filename-format", fmt.c_str());
- ctx->executeCommand(command, ¶ms);
+ ctx->executeCommand(saveAsCommand, ¶ms);
+
+ if (trim) // Undo trim command
+ ctx->executeCommand(undoCommand);
}
}
else {
@@ -324,10 +343,16 @@ void App::initialize(const AppOptions& options)
layer->setReadable(layer->name() == importLayerSaveAs);
}
+ if (trim)
+ ctx->executeCommand(trimCommand);
+
Params params;
params.set("filename", value.value().c_str());
params.set("filename-format", format.c_str());
- ctx->executeCommand(command, ¶ms);
+ ctx->executeCommand(saveAsCommand, ¶ms);
+
+ if (trim) // Undo trim command
+ ctx->executeCommand(undoCommand);
}
}
}
@@ -400,12 +425,15 @@ void App::initialize(const AppOptions& options)
}
// Export
- if (m_exporter != NULL) {
+ if (m_exporter) {
PRINTF("Exporting sheet...\n");
if (ignoreEmpty)
m_exporter->setIgnoreEmptyCels(true);
+ if (trim)
+ m_exporter->setTrimCels(true);
+
m_exporter->exportSheet();
m_exporter.reset(NULL);
}
diff --git a/src/app/app_options.cpp b/src/app/app_options.cpp
index 0557450..6438015 100644
--- a/src/app/app_options.cpp
+++ b/src/app/app_options.cpp
@@ -49,6 +49,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_splitLayers(m_po.add("split-layers").description("Import each layer of the next given sprite as\na separated image in the sheet"))
, m_importLayer(m_po.add("import-layer").requiresValue("<name>").description("Import just one layer of the next given sprite"))
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
+ , m_trim(m_po.add("trim").description("Trim all images before exporting"))
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
, m_verbose(m_po.add("verbose").description("Explain what is being done"))
, m_help(m_po.add("help").mnemonic('?').description("Display this help and exits"))
diff --git a/src/app/app_options.h b/src/app/app_options.h
index a9c5b8b..4a4d54b 100644
--- a/src/app/app_options.h
+++ b/src/app/app_options.h
@@ -57,6 +57,7 @@ public:
const Option& splitLayers() const { return m_splitLayers; }
const Option& importLayer() const { return m_importLayer; }
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
+ const Option& trim() const { return m_trim; }
const Option& filenameFormat() const { return m_filenameFormat; }
bool hasExporterParams() const;
@@ -85,6 +86,7 @@ private:
Option& m_splitLayers;
Option& m_importLayer;
Option& m_ignoreEmpty;
+ Option& m_trim;
Option& m_filenameFormat;
Option& m_verbose;
diff --git a/src/app/commands/cmd_undo.cpp b/src/app/commands/cmd_undo.cpp
index 47b030f..954d000 100644
--- a/src/app/commands/cmd_undo.cpp
+++ b/src/app/commands/cmd_undo.cpp
@@ -103,11 +103,13 @@ void UndoCommand::onExecute(Context* context)
}
}
- StatusBar::instance()
- ->showTip(1000, "%s %s",
- (m_type == Undo ? "Undid": "Redid"),
- (m_type == Undo ? undo->getNextUndoLabel():
- undo->getNextRedoLabel()));
+ StatusBar* statusbar = StatusBar::instance();
+ if (statusbar)
+ statusbar->showTip(1000, "%s %s",
+ (m_type == Undo ? "Undid": "Redid"),
+ (m_type == Undo ?
+ undo->getNextUndoLabel():
+ undo->getNextRedoLabel()));
// Effectively undo/redo.
if (m_type == Undo)
diff --git a/src/app/document_exporter.cpp b/src/app/document_exporter.cpp
index dcbfd20..6b8ca01 100644
--- a/src/app/document_exporter.cpp
+++ b/src/app/document_exporter.cpp
@@ -1,5 +1,5 @@
/* Aseprite
- * Copyright (C) 2001-2013 David Capello
+ * Copyright (C) 2001-2015 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,7 +59,10 @@ public:
m_sprite(sprite),
m_layer(layer),
m_frame(frame),
- m_filename(filename) {
+ m_filename(filename),
+ m_originalSize(sprite->width(), sprite->height()),
+ m_trimmedBounds(0, 0, sprite->width(), sprite->height()),
+ m_inTextureBounds(0, 0, sprite->width(), sprite->height()) {
}
Document* document() const { return m_document; }
@@ -128,37 +131,39 @@ public:
const Layer* oldLayer = NULL;
gfx::Point framePt(0, 0);
+ gfx::Size rowSize(0, 0);
+
for (auto& sample : samples) {
const Sprite* sprite = sample.sprite();
const Layer* layer = sample.layer();
- gfx::Size size(sprite->width(), sprite->height());
+ gfx::Size size = sample.trimmedBounds().getSize();
if (oldSprite) {
- // If the user didn't specified a width for the texture, we put
- // each sprite/layer in a different row.
- if (width == 0) {
- // New sprite or layer, go to next row.
- if (oldSprite != sprite || oldLayer != layer) {
- framePt.x = 0;
- framePt.y += oldSprite->height(); // We're skipping the previous sprite height
- }
- }
- // When a texture width is specified, we can put different
- // sprites/layers in each row until we reach the texture
- // right-border.
- else if (framePt.x+size.w > width) {
- framePt.x = 0;
- framePt.y += oldSprite->height();
- // TODO framePt.y+size.h > height ?
+ // If the user didn't specify a width for the texture, we put
+ // each sprite/layer in a different row.
+ if (width == 0) {
+ // New sprite or layer, go to next row.
+ if (oldSprite != sprite || oldLayer != layer) {
+ framePt.x = 0;
+ framePt.y += rowSize.h;
+ rowSize = size;
}
+ }
+ // When a texture width is specified, we can put different
+ // sprites/layers in each row until we reach the texture
+ // right-border.
+ else if (framePt.x+size.w > width) {
+ framePt.x = 0;
+ framePt.y += rowSize.h;
+ rowSize = size;
+ }
}
- sample.setOriginalSize(size);
- sample.setTrimmedBounds(gfx::Rect(gfx::Point(0, 0), size));
sample.setInTextureBounds(gfx::Rect(framePt, size));
// Next frame position.
framePt.x += size.w;
+ rowSize = rowSize.createUnion(size);
oldSprite = sprite;
oldLayer = layer;
@@ -172,15 +177,8 @@ public:
void layoutSamples(Samples& samples, int& width, int& height) override {
gfx::PackingRects pr;
- for (auto& sample : samples) {
- const Sprite* sprite = sample.sprite();
- gfx::Size size(sprite->width(), sprite->height());
-
- sample.setOriginalSize(size);
- sample.setTrimmedBounds(gfx::Rect(gfx::Point(0, 0), size));
-
- pr.add(size);
- }
+ for (auto& sample : samples)
+ pr.add(sample.trimmedBounds().getSize());
if (width == 0 || height == 0) {
gfx::Size sz = pr.bestFit();
@@ -208,6 +206,7 @@ DocumentExporter::DocumentExporter()
, m_scale(1.0)
, m_scaleMode(DefaultScaleMode)
, m_ignoreEmptyCels(false)
+ , m_trimCels(false)
{
}
@@ -267,7 +266,6 @@ void DocumentExporter::exportSheet()
void DocumentExporter::captureSamples(Samples& samples)
{
- ImageBufferPtr checkEmptyImageBuf;
std::vector<char> buf(32);
for (auto& item : m_documents) {
@@ -299,30 +297,39 @@ void DocumentExporter::captureSamples(Samples& samples)
Sample sample(doc, sprite, layer, frame, filename);
- if (m_ignoreEmptyCels) {
+ if (m_ignoreEmptyCels || m_trimCels) {
if (layer && layer->isImage() &&
!static_cast<LayerImage*>(layer)->getCel(frame)) {
// Empty cel this sample completely
continue;
}
- base::UniquePtr<Image> checkEmptyImage(
+ base::UniquePtr<Image> sampleRender(
Image::create(sprite->pixelFormat(),
sprite->width(),
sprite->height(),
- checkEmptyImageBuf));
+ m_sampleRenderBuf));
- checkEmptyImage->setMaskColor(sprite->transparentColor());
- clear_image(checkEmptyImage, sprite->transparentColor());
- renderSample(sample, checkEmptyImage, 0, 0);
+ sampleRender->setMaskColor(sprite->transparentColor());
+ clear_image(sampleRender, sprite->transparentColor());
+ renderSample(sample, sampleRender);
gfx::Rect frameBounds;
- if (!algorithm::shrink_bounds(checkEmptyImage, frameBounds,
- sprite->transparentColor())) {
+ raster::color_t refColor;
+
+ if (m_trimCels)
+ refColor = get_pixel(sampleRender, 0, 0);
+ else if (m_ignoreEmptyCels)
+ refColor = sprite->transparentColor();
+
+ if (!algorithm::shrink_bounds(sampleRender, frameBounds, refColor)) {
// If shrink_bounds returns false, it's because the whole
// image is transparent (equal to the mask color).
continue;
}
+
+ if (m_trimCels)
+ sample.setTrimmedBounds(frameBounds);
}
samples.addSample(sample);
@@ -388,10 +395,7 @@ void DocumentExporter::renderTexture(const Samples& samples, Image* textureImage
DITHERING_NONE);
}
- int x = sample.inTextureBounds().x - sample.trimmedBounds().x;
- int y = sample.inTextureBounds().y - sample.trimmedBounds().y;
-
- renderSample(sample, textureImage, x, y);
+ renderSample(sample, textureImage);
}
}
@@ -446,14 +450,24 @@ void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os,
<< "}\n";
}
-void DocumentExporter::renderSample(const Sample& sample, raster::Image* dst, int x, int y)
+void DocumentExporter::renderSample(const Sample& sample, raster::Image* dst)
{
+ gfx::Rect trimmed = sample.trimmedBounds();
+ base::UniquePtr<Image> tmp(
+ Image::create(sample.sprite()->pixelFormat(),
+ trimmed.w, trimmed.h,
+ m_sampleRenderBuf));
+
if (sample.layer()) {
- layer_render(sample.layer(), dst, x, y, sample.frame());
+ layer_render(sample.layer(), tmp, -trimmed.x, -trimmed.y, sample.frame());
}
else {
- sample.sprite()->render(dst, x, y, sample.frame());
+ sample.sprite()->render(tmp, -trimmed.x, -trimmed.y, sample.frame());
}
+
+ copy_image(dst, tmp,
+ sample.inTextureBounds().x,
+ sample.inTextureBounds().y);
}
} // namespace app
diff --git a/src/app/document_exporter.h b/src/app/document_exporter.h
index 7fce95a..007a36a 100644
--- a/src/app/document_exporter.h
+++ b/src/app/document_exporter.h
@@ -1,5 +1,5 @@
/* Aseprite
- * Copyright (C) 2001-2014 David Capello
+ * Copyright (C) 2001-2015 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,10 +22,11 @@
#include "base/disable_copying.h"
#include "gfx/fwd.h"
+#include "raster/image_buffer.h"
#include <iosfwd>
-#include <vector>
#include <string>
+#include <vector>
namespace raster {
class Image;
@@ -93,6 +94,10 @@ namespace app {
m_ignoreEmptyCels = ignore;
}
+ void setTrimCels(bool trim) {
+ m_trimCels = trim;
+ }
+
void setFilenameFormat(const std::string& format) {
m_filenameFormat = format;
}
@@ -114,7 +119,7 @@ namespace app {
Document* createEmptyTexture(const Samples& samples);
void renderTexture(const Samples& samples, raster::Image* textureImage);
void createDataFile(const Samples& samples, std::ostream& os, raster::Image* textureImage);
- void renderSample(const Sample& sample, raster::Image* dst, int x, int y);
+ void renderSample(const Sample& sample, raster::Image* dst);
class Item {
public:
@@ -136,8 +141,10 @@ namespace app {
double m_scale;
ScaleMode m_scaleMode;
bool m_ignoreEmptyCels;
+ bool m_trimCels;
Items m_documents;
std::string m_filenameFormat;
+ raster::ImageBufferPtr m_sampleRenderBuf;
DISABLE_COPYING(DocumentExporter);
};
diff --git a/src/app/settings/ui_settings_impl.cpp b/src/app/settings/ui_settings_impl.cpp
index 066298b..ea28029 100644
--- a/src/app/settings/ui_settings_impl.cpp
+++ b/src/app/settings/ui_settings_impl.cpp
@@ -382,12 +382,14 @@ bool UISettingsImpl::getAutoSelectLayer()
app::Color UISettingsImpl::getFgColor()
{
- return ColorBar::instance()->getFgColor();
+ ColorBar* colorbar = ColorBar::instance();
+ return colorbar ? colorbar->getFgColor(): app::Color::fromMask();
}
app::Color UISettingsImpl::getBgColor()
{
- return ColorBar::instance()->getBgColor();
+ ColorBar* colorbar = ColorBar::instance();
+ return colorbar ? colorbar->getBgColor(): app::Color::fromMask();
}
tools::Tool* UISettingsImpl::getCurrentTool()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git
More information about the Pkg-games-commits
mailing list