Skip to content

Commit

Permalink
Merge branch 'ref-layer' into beta (fix #532)
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Nov 7, 2016
2 parents 54e60f0 + b5225d0 commit bc1ad97
Show file tree
Hide file tree
Showing 59 changed files with 1,379 additions and 494 deletions.
5 changes: 5 additions & 0 deletions data/gui.xml
Expand Up @@ -679,6 +679,11 @@
<item command="DuplicateLayer" text="&amp;Duplicate" />
<item command="MergeDownLayer" text="&amp;Merge Down" />
<item command="FlattenLayers" text="&amp;Flatten" />
<separator />
<item command="NewLayer" text="Add R&amp;eference Layer" >
<param name="reference" value="true" />
<param name="from-file" value="true" />
</item>
</menu>
<menu text="F&amp;rame">
<item command="FrameProperties" text="Frame &amp;Properties...">
Expand Down
4 changes: 4 additions & 0 deletions data/pref.xml
Expand Up @@ -55,6 +55,7 @@
<enum id="EyedropperSample">
<value id="ALL_LAYERS" value="0" />
<value id="CURRENT_LAYER" value="1" />
<value id="FIRST_REFERENCE_LAYER" value="2" />
</enum>
<enum id="SelectionMode">
<value id="DEFAULT" value="0" />
Expand Down Expand Up @@ -218,6 +219,9 @@
<section id="thumbnails">
<option id="cache_limit" type="int" default="5000" />
</section>
<section id="perf">
<option id="show_render_time" type="bool" default="false" />
</section>
</global>

<tool>
Expand Down
16 changes: 16 additions & 0 deletions docs/files/ase.txt
Expand Up @@ -19,6 +19,7 @@ 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
FIXED A 32-bit fixed point (16.16) value
BYTE[n] "n" bytes.
STRING length=WORD (how many characters to read next)
string=BYTE[length]
Expand Down Expand Up @@ -156,6 +157,7 @@ Layer Chunk (0x2004)
8 = Background
16 = Prefer linked cels
32 = The layer group should be displayed collapsed
64 = The layer is a reference layer
WORD Layer type
0 = Normal (image) layer
1 = Group
Expand Down Expand Up @@ -218,6 +220,20 @@ Cel Chunk (0x2005)
http://www.ietf.org/rfc/rfc1951.txt


Cel Extra Chunk (0x2006)
----------------------------------------

Adds extra information to the latest read cel.

DWORD Flags (set to zero)
1 - precise bounds are set
FIXED Precise X position
FIXED Precise Y position
FIXED Width of the cel in the sprite (scaled in real-time)
FIXED Height of the cel in the sprite
BYTE[16] For future use (set to zero)


Mask Chunk (0x2016) DEPRECATED
----------------------------------------

Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -134,6 +134,7 @@ add_library(app-lib
cmd/remove_palette.cpp
cmd/replace_image.cpp
cmd/reselect_mask.cpp
cmd/set_cel_bounds.cpp
cmd/set_cel_data.cpp
cmd/set_cel_frame.cpp
cmd/set_cel_opacity.cpp
Expand Down
3 changes: 2 additions & 1 deletion src/app/cmd/background_from_layer.cpp
@@ -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.
Expand Down Expand Up @@ -33,6 +33,7 @@ BackgroundFromLayer::BackgroundFromLayer(Layer* layer)
ASSERT(layer);
ASSERT(layer->isVisible());
ASSERT(layer->isEditable());
ASSERT(!layer->isReference());
ASSERT(layer->sprite() != NULL);
ASSERT(layer->sprite()->backgroundLayer() == NULL);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/cmd/copy_cel.cpp
Expand Up @@ -115,7 +115,7 @@ void CopyCel::onExecute()
dstCel->setFrame(m_dstFrame);
}
else
dstCel = create_cel_copy(srcCel, dstSprite, m_dstFrame);
dstCel = create_cel_copy(srcCel, dstSprite, dstLayer, m_dstFrame);

executeAndAdd(new cmd::AddCel(dstLayer, dstCel));
}
Expand Down
3 changes: 2 additions & 1 deletion src/app/cmd/layer_from_background.cpp
@@ -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.
Expand All @@ -24,6 +24,7 @@ LayerFromBackground::LayerFromBackground(Layer* layer)
ASSERT(layer->isVisible());
ASSERT(layer->isEditable());
ASSERT(layer->isBackground());
ASSERT(!layer->isReference());
ASSERT(layer->sprite() != NULL);
ASSERT(layer->sprite()->backgroundLayer() != NULL);

Expand Down
4 changes: 2 additions & 2 deletions src/app/cmd/move_cel.cpp
@@ -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.
Expand Down Expand Up @@ -119,7 +119,7 @@ void MoveCel::onExecute()
executeAndAdd(new cmd::SetCelFrame(srcCel, m_dstFrame));
}
else {
dstCel = create_cel_copy(srcCel, dstSprite, m_dstFrame);
dstCel = create_cel_copy(srcCel, dstSprite, dstLayer, m_dstFrame);

executeAndAdd(new cmd::AddCel(dstLayer, dstCel));
executeAndAdd(new cmd::ClearCel(srcCel));
Expand Down
51 changes: 51 additions & 0 deletions src/app/cmd/set_cel_bounds.cpp
@@ -0,0 +1,51 @@
// Aseprite
// Copyright (C) 2016 David Capello
//
// 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_cel_bounds.h"

#include "app/document.h"
#include "doc/cel.h"
#include "doc/document_event.h"

namespace app {
namespace cmd {

using namespace doc;

SetCelBoundsF::SetCelBoundsF(Cel* cel, const gfx::RectF& bounds)
: WithCel(cel)
, m_oldBounds(cel->boundsF())
, m_newBounds(bounds)
{
}

void SetCelBoundsF::onExecute()
{
cel()->setBoundsF(m_newBounds);
cel()->incrementVersion();
}

void SetCelBoundsF::onUndo()
{
cel()->setBoundsF(m_oldBounds);
cel()->incrementVersion();
}

void SetCelBoundsF::onFireNotifications()
{
Cel* cel = this->cel();
DocumentEvent ev(cel->document());
ev.sprite(cel->sprite());
ev.cel(cel);
cel->document()->notify_observers<DocumentEvent&>(&DocumentObserver::onCelPositionChanged, ev);
}

} // namespace cmd
} // namespace app
40 changes: 40 additions & 0 deletions src/app/cmd/set_cel_bounds.h
@@ -0,0 +1,40 @@
// Aseprite
// Copyright (C) 2016 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.

#ifndef APP_CMD_SET_CEL_BOUNDS_H_INCLUDED
#define APP_CMD_SET_CEL_BOUNDS_H_INCLUDED
#pragma once

#include "app/cmd.h"
#include "app/cmd/with_cel.h"
#include "gfx/rect.h"

namespace app {
namespace cmd {
using namespace doc;

class SetCelBoundsF : public Cmd
, public WithCel {
public:
SetCelBoundsF(Cel* cel, const gfx::RectF& bounds);

protected:
void onExecute() override;
void onUndo() override;
void onFireNotifications() override;
size_t onMemSize() const override {
return sizeof(*this);
}

private:
gfx::RectF m_oldBounds;
gfx::RectF m_newBounds;
};

} // namespace cmd
} // namespace app

#endif
122 changes: 92 additions & 30 deletions src/app/color_picker.cpp
@@ -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.
Expand All @@ -23,17 +23,50 @@

namespace app {

namespace {

bool get_cel_pixel(const Cel* cel,
const double x,
const double y,
const frame_t frame,
color_t& output)
{
gfx::RectF celBounds;
if (cel->layer()->isReference())
celBounds = cel->boundsF();
else
celBounds = cel->bounds();

const doc::Image* image = cel->image();
gfx::PointF pos(x, y);
if (!celBounds.contains(pos))
return false;

pos.x = (pos.x-celBounds.x)*image->width()/celBounds.w;
pos.y = (pos.y-celBounds.y)*image->height()/celBounds.h;
const gfx::Point ipos(pos);
if (!image->bounds().contains(ipos))
return false;

output = get_pixel(image, ipos.x, ipos.y);
return true;
}

}

ColorPicker::ColorPicker()
: m_alpha(0)
, m_layer(NULL)
{
}

void ColorPicker::pickColor(const doc::Site& site,
const gfx::Point& _pos, Mode mode)
const gfx::PointF& _pos,
const render::Projection& proj,
const Mode mode)
{
const doc::Sprite* sprite = site.sprite();
gfx::Point pos = _pos;
gfx::PointF pos = _pos;

m_alpha = 255;
m_color = app::Color::fromMask();
Expand All @@ -44,42 +77,71 @@ void ColorPicker::pickColor(const doc::Site& site,
DocumentPreferences& docPref = Preferences::instance().document(doc);

if (int(docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS))
pos.x = wrap_value(pos.x, site.sprite()->width());
pos.x = wrap_value<double>(pos.x, site.sprite()->width());

if (int(docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS))
pos.y = wrap_value(pos.y, site.sprite()->height());
pos.y = wrap_value<double>(pos.y, site.sprite()->height());
}

// Get the color from the image
if (mode == FromComposition) { // Pick from the composed image
m_color = app::Color::fromImage(
sprite->pixelFormat(),
render::get_sprite_pixel(sprite, pos.x, pos.y, site.frame()));

doc::CelList cels;
sprite->pickCels(pos.x, pos.y, site.frame(), 128, cels);
if (!cels.empty())
m_layer = cels.front()->layer();
}
else { // Pick from the current layer
int u, v;
doc::Image* image = site.image(&u, &v, NULL);
gfx::Point pt(pos.x-u, pos.y-v);
switch (mode) {

// Pick from the composed image
case FromComposition: {
m_color = app::Color::fromImage(
sprite->pixelFormat(),
render::get_sprite_pixel(sprite, pos.x, pos.y,
site.frame(), proj));

doc::CelList cels;
sprite->pickCels(pos.x, pos.y, site.frame(), 128,
sprite->allVisibleLayers(), cels);
if (!cels.empty())
m_layer = cels.front()->layer();
break;
}

if (image && image->bounds().contains(pt)) {
doc::color_t imageColor = get_pixel(image, pt.x, pt.y);
// Pick from the current layer
case FromActiveLayer: {
const Cel* cel = site.cel();
if (cel) {
doc::color_t imageColor;
if (!get_cel_pixel(cel, pos.x, pos.y,
site.frame(), imageColor))
return;

const doc::Image* image = cel->image();
switch (image->pixelFormat()) {
case IMAGE_RGB:
m_alpha = doc::rgba_geta(imageColor);
break;
case IMAGE_GRAYSCALE:
m_alpha = doc::graya_geta(imageColor);
break;
}

m_color = app::Color::fromImage(image->pixelFormat(), imageColor);
m_layer = const_cast<Layer*>(site.layer());
}
break;
}

switch (image->pixelFormat()) {
case IMAGE_RGB:
m_alpha = doc::rgba_geta(imageColor);
break;
case IMAGE_GRAYSCALE:
m_alpha = doc::graya_geta(imageColor);
case FromFirstReferenceLayer: {
doc::CelList cels;
sprite->pickCels(pos.x, pos.y, site.frame(), 128,
sprite->allVisibleReferenceLayers(), cels);

for (const Cel* cel : cels) {
doc::color_t imageColor;
if (get_cel_pixel(cel, pos.x, pos.y,
site.frame(), imageColor)) {
m_color = app::Color::fromImage(
cel->image()->pixelFormat(), imageColor);
m_layer = cel->layer();
break;
}
}

m_color = app::Color::fromImage(image->pixelFormat(), imageColor);
m_layer = const_cast<Layer*>(site.layer());
break;
}
}
}
Expand Down

0 comments on commit bc1ad97

Please sign in to comment.