Merge branch 'master' into beta

This commit is contained in:
David Capello 2016-09-06 12:46:37 -03:00
commit a9f3702ba4
5 changed files with 68 additions and 24 deletions

View File

@ -6,8 +6,8 @@
## Introduction
**Aseprite** is an open source program to create animated sprites.
Its main features are:
**Aseprite** is a program to create animated sprites. Its main
features are:
* Sprites are composed by [**layers** & **frames**](http://www.aseprite.org/docs/timeline/) (as separated concepts).
* Supported [color modes](http://www.aseprite.org/docs/color/): **RGBA**, **Indexed** (palettes up to 256

View File

@ -17,10 +17,9 @@ ASE files use Intel (little-endian) byte order.
BYTE An 8-bit unsigned integer value
WORD A 16-bit unsigned integer value
SIGNED WORD A 16-bit signed integer value
DWORD A 32-bit unsigned integer value
LONG A 32-bit signed integer value
BYTE[n] "n" bytes.
RECT Four LONGs (in the order: x-pos, y-pos, width, heigth)
STRING length=WORD (how many characters to read next)
string=BYTE[length]
The \0 character isn't included.
@ -191,8 +190,8 @@ Cel Chunk (0x2005)
layer/frame.
WORD Layer index (see NOTE.2)
WORD X position
WORD Y position
SIGNED WORD X position
SIGNED WORD Y position
BYTE Opacity level
WORD Cel type
BYTE[7] For future (set to zero)
@ -220,8 +219,8 @@ Cel Chunk (0x2005)
Mask Chunk (0x2016) DEPRECATED
----------------------------------------
WORD X position
WORD Y position
SIGNED WORD X position
SIGNED WORD Y position
WORD Width
WORD Height
BYTE[8] For future (set to zero)

View File

@ -170,6 +170,7 @@ public:
void setInTextureBounds(const gfx::Rect& bounds) { m_bounds->setInTextureBounds(bounds); }
bool isDuplicated() const { return m_isDuplicated; }
bool isEmpty() const { return m_bounds->trimmedBounds().isEmpty(); }
SampleBoundsPtr sharedBounds() const { return m_bounds; }
void setSharedBounds(const SampleBoundsPtr& bounds) {
@ -235,6 +236,11 @@ public:
if (sample.isDuplicated())
continue;
if (sample.isEmpty()) {
sample.setInTextureBounds(gfx::Rect(0, 0, 0, 0));
continue;
}
const Sprite* sprite = sample.sprite();
const Layer* layer = sample.layer();
gfx::Size size = sample.requiredSize();
@ -312,7 +318,8 @@ public:
// TODO Add support for shape paddings
for (auto& sample : samples) {
if (sample.isDuplicated())
if (sample.isDuplicated() ||
sample.isEmpty())
continue;
pr.add(sample.requiredSize());
@ -423,7 +430,7 @@ gfx::Size DocumentExporter::calculateSheetSize()
return calculateSheetSize(samples);
}
void DocumentExporter::captureSamples(Samples& samples) const
void DocumentExporter::captureSamples(Samples& samples)
{
for (auto& item : m_documents) {
Document* doc = item.doc;
@ -521,7 +528,22 @@ void DocumentExporter::captureSamples(Samples& samples) const
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;
// Should we ignore this empty frame? (i.e. don't include
// the frame in the sprite sheet)
if (m_ignoreEmptyCels) {
for (FrameTag* tag : sprite->frameTags()) {
auto& delta = m_tagDelta[tag->id()];
if (frame < tag->fromFrame()) --delta.first;
if (frame <= tag->toFrame()) --delta.second;
}
continue;
}
// Create an empty entry for this completely trimmed frame
// anyway to get its duration in the list of frames.
sample.setTrimmedBounds(frameBounds = gfx::Rect(0, 0, 0, 0));
}
if (m_trimCels)
@ -558,6 +580,10 @@ gfx::Size DocumentExporter::calculateSheetSize(const Samples& samples) const
gfx::Rect fullTextureBounds(0, 0, m_textureWidth, m_textureHeight);
for (const auto& sample : samples) {
if (sample.isDuplicated() ||
sample.isEmpty())
continue;
gfx::Rect sampleBounds = sample.inTextureBounds();
// If the user specified a fixed sprite sheet size, we add the
@ -587,6 +613,10 @@ Document* DocumentExporter::createEmptyTexture(const Samples& samples) const
int maxColors = 256;
for (const auto& sample : samples) {
if (sample.isDuplicated() ||
sample.isEmpty())
continue;
// We try to render an indexed image. But if we find a sprite with
// two or more palettes, or two of the sprites have different
// palettes, we've to use RGB format.
@ -626,7 +656,8 @@ void DocumentExporter::renderTexture(const Samples& samples, Image* textureImage
textureImage->clear(0);
for (const auto& sample : samples) {
if (sample.isDuplicated())
if (sample.isDuplicated() ||
sample.isEmpty())
continue;
// Make the sprite compatible with the texture so the render()
@ -644,7 +675,7 @@ void DocumentExporter::renderTexture(const Samples& samples, Image* textureImage
}
}
void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os, Image* textureImage) const
void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os, Image* textureImage)
{
std::string frames_begin;
std::string frames_end;
@ -738,9 +769,13 @@ void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os,
else
os << ",";
std::pair<int, int> delta(0, 0);
if (!m_tagDelta.empty())
delta = m_tagDelta[tag->id()];
os << "\n { \"name\": \"" << escape_for_json(tag->name()) << "\","
<< " \"from\": " << tag->fromFrame() << ","
<< " \"to\": " << tag->toFrame() << ","
<< " \"from\": " << (tag->fromFrame()+delta.first) << ","
<< " \"to\": " << (tag->toFrame()+delta.second) << ","
<< " \"direction\": \"" << escape_for_json(convert_to_string(tag->aniDir())) << "\" }";
}
}

View File

@ -11,10 +11,13 @@
#include "app/sprite_sheet_type.h"
#include "base/disable_copying.h"
#include "doc/image_buffer.h"
#include "doc/object_id.h"
#include "gfx/fwd.h"
#include <iosfwd>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace doc {
@ -84,12 +87,12 @@ namespace app {
class SimpleLayoutSamples;
class BestFitLayoutSamples;
void captureSamples(Samples& samples) const;
void captureSamples(Samples& samples);
void layoutSamples(Samples& samples);
gfx::Size calculateSheetSize(const Samples& samples) const;
Document* createEmptyTexture(const Samples& samples) const;
void renderTexture(const Samples& samples, doc::Image* textureImage) const;
void createDataFile(const Samples& samples, std::ostream& os, doc::Image* textureImage) const;
void createDataFile(const Samples& samples, std::ostream& os, doc::Image* textureImage);
void renderSample(const Sample& sample, doc::Image* dst, int x, int y) const;
class Item {
@ -130,6 +133,11 @@ namespace app {
bool m_listFrameTags;
bool m_listLayers;
// Displacement for each tag from/to frames in case we export
// them. It's used in case we trim frames outside tags and they
// will not be exported at all in the final result.
std::map<doc::ObjectId, std::pair<int, int> > m_tagDelta;
DISABLE_COPYING(DocumentExporter);
};

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -205,8 +205,7 @@ void ResourcesListBox::onTick()
insertChild(getItemsCount()-1, listItem);
layout();
View* view = View::getView(this);
if (view)
if (View* view = View::getView(this))
view->updateView();
resource.release();
@ -215,15 +214,18 @@ void ResourcesListBox::onTick()
void ResourcesListBox::stop()
{
m_resourcesTimer.stop();
if (m_loadingItem) {
removeChild(m_loadingItem);
layout();
delete m_loadingItem;
m_loadingItem = NULL;
m_loadingItem = nullptr;
invalidate();
if (View* view = View::getView(this))
view->updateView();
}
m_resourcesTimer.stop();
}
} // namespace app