mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
No more pimpl idiom for Sprite class (because the biggest dependencies
are now part of Document class).
This commit is contained in:
parent
82476db988
commit
a2e0f32987
@ -389,25 +389,6 @@ SpriteImpl* SpriteImpl::copyBase(Sprite* new_sprite, const SpriteImpl* src_sprit
|
||||
if (src_sprite->m_mask)
|
||||
dst_sprite->m_mask = mask_new_copy(src_sprite->m_mask);
|
||||
|
||||
/* copy repositories */
|
||||
{
|
||||
PathsList::const_iterator end = src_sprite->m_repository.paths.end();
|
||||
PathsList::const_iterator it = src_sprite->m_repository.paths.begin();
|
||||
for (; it != end; ++it) {
|
||||
Path* path_copy = new Path(*(*it));
|
||||
dst_sprite->addPath(path_copy);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MasksList::const_iterator end = src_sprite->m_repository.masks.end();
|
||||
MasksList::const_iterator it = src_sprite->m_repository.masks.begin();
|
||||
for (; it != end; ++it) {
|
||||
Mask* mask_copy = new Mask(*(*it));
|
||||
dst_sprite->addMask(mask_copy);
|
||||
}
|
||||
}
|
||||
|
||||
return dst_sprite;
|
||||
}
|
||||
|
||||
|
@ -18,238 +18,23 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "raster/sprite.h"
|
||||
|
||||
#include "base/memory.h"
|
||||
#include "base/remove_from_container.h"
|
||||
#include "file/format_options.h"
|
||||
#include "raster/raster.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4355)
|
||||
#endif
|
||||
|
||||
static Layer* index2layer(const Layer* layer, int index, int* index_count);
|
||||
static int layer2index(const Layer* layer, const Layer* find_layer, int* index_count);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SpriteImpl
|
||||
// Constructors/Destructor
|
||||
|
||||
class SpriteImpl
|
||||
{
|
||||
public:
|
||||
SpriteImpl(Sprite* sprite, int imgtype, int width, int height, int ncolors);
|
||||
~SpriteImpl();
|
||||
|
||||
int getImgType() const {
|
||||
return m_imgtype;
|
||||
}
|
||||
|
||||
void setImgType(int imgtype) {
|
||||
m_imgtype = imgtype;
|
||||
}
|
||||
|
||||
int getWidth() const {
|
||||
return m_width;
|
||||
}
|
||||
|
||||
int getHeight() const {
|
||||
return m_height;
|
||||
}
|
||||
|
||||
void setSize(int width, int height) {
|
||||
ASSERT(width > 0);
|
||||
ASSERT(height > 0);
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
bool needAlpha() const {
|
||||
switch (m_imgtype) {
|
||||
case IMAGE_RGB:
|
||||
case IMAGE_GRAYSCALE:
|
||||
return (getBackgroundLayer() == NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ase_uint32 getTransparentColor() const {
|
||||
return m_transparentColor;
|
||||
}
|
||||
|
||||
void setTransparentColor(ase_uint32 color) {
|
||||
m_transparentColor = color;
|
||||
}
|
||||
|
||||
int getMemSize() const;
|
||||
|
||||
LayerFolder* getFolder() const {
|
||||
return m_folder;
|
||||
}
|
||||
|
||||
LayerImage* getBackgroundLayer() const;
|
||||
|
||||
Layer* getCurrentLayer() const {
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
void setCurrentLayer(Layer* layer) {
|
||||
m_layer = layer;
|
||||
}
|
||||
|
||||
int countLayers() const {
|
||||
return getFolder()->get_layers_count();
|
||||
}
|
||||
|
||||
Layer* indexToLayer(int index) const {
|
||||
int index_count = -1;
|
||||
return index2layer(getFolder(), index, &index_count);
|
||||
}
|
||||
|
||||
int layerToIndex(const Layer* layer) const {
|
||||
int index_count = -1;
|
||||
return layer2index(getFolder(), layer, &index_count);
|
||||
}
|
||||
|
||||
Palette* getPalette(int frame) const;
|
||||
|
||||
PalettesList getPalettes() const {
|
||||
return m_palettes;
|
||||
}
|
||||
|
||||
void setPalette(Palette* pal, bool truncate);
|
||||
void resetPalettes();
|
||||
void deletePalette(Palette* pal);
|
||||
|
||||
Palette* getCurrentPalette() const {
|
||||
return getPalette(getCurrentFrame());
|
||||
}
|
||||
|
||||
RgbMap* getRgbMap(int frame) {
|
||||
if (m_rgbMap == NULL) {
|
||||
m_rgbMap = new RgbMap();
|
||||
m_rgbMap->regenerate(getPalette(frame));
|
||||
}
|
||||
else if (!m_rgbMap->match(getPalette(frame))) {
|
||||
m_rgbMap->regenerate(getPalette(frame));
|
||||
}
|
||||
return m_rgbMap;
|
||||
}
|
||||
|
||||
int getTotalFrames() const {
|
||||
return m_frames;
|
||||
}
|
||||
|
||||
void setTotalFrames(int frames);
|
||||
|
||||
int getFrameDuration(int frame) const {
|
||||
if (frame >= 0 && frame < m_frames)
|
||||
return m_frlens[frame];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setFrameDuration(int frame, int msecs) {
|
||||
if (frame >= 0 && frame < m_frames)
|
||||
m_frlens[frame] = MID(1, msecs, 65535);
|
||||
}
|
||||
|
||||
void setDurationForAllFrames(int msecs) {
|
||||
std::fill(m_frlens.begin(), m_frlens.end(), MID(1, msecs, 65535));
|
||||
}
|
||||
|
||||
int getCurrentFrame() const {
|
||||
return m_frame;
|
||||
}
|
||||
|
||||
void setCurrentFrame(int frame) {
|
||||
m_frame = frame;
|
||||
}
|
||||
|
||||
Stock* getStock() const {
|
||||
return m_stock;
|
||||
}
|
||||
|
||||
Image* getCurrentImage(int* x, int* y, int* opacity) const {
|
||||
Image* image = NULL;
|
||||
|
||||
if (getCurrentLayer() != NULL &&
|
||||
getCurrentLayer()->is_image()) {
|
||||
const Cel* cel = static_cast<const LayerImage*>(getCurrentLayer())->getCel(getCurrentFrame());
|
||||
if (cel) {
|
||||
ASSERT((cel->image >= 0) &&
|
||||
(cel->image < getStock()->size()));
|
||||
|
||||
image = getStock()->getImage(cel->image);
|
||||
|
||||
if (x) *x = cel->x;
|
||||
if (y) *y = cel->y;
|
||||
if (opacity) *opacity = MID(0, cel->opacity, 255);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void getCels(CelList& cels) {
|
||||
getFolder()->getCels(cels);
|
||||
}
|
||||
|
||||
void remapImages(int frame_from, int frame_to, const std::vector<int>& mapping) {
|
||||
ASSERT(m_imgtype == IMAGE_INDEXED);
|
||||
ASSERT(mapping.size() == 256);
|
||||
|
||||
CelList cels;
|
||||
getCels(cels);
|
||||
|
||||
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
|
||||
Cel* cel = *it;
|
||||
|
||||
// Remap this Cel because is inside the specified range
|
||||
if (cel->frame >= frame_from &&
|
||||
cel->frame <= frame_to) {
|
||||
Image* image = getStock()->getImage(cel->image);
|
||||
|
||||
for (int y=0; y<image->h; ++y) {
|
||||
IndexedTraits::address_t ptr = image_address_fast<IndexedTraits>(image, 0, y);
|
||||
for (int x=0; x<image->w; ++x, ++ptr)
|
||||
*ptr = mapping[*ptr];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render(Image* image, int x, int y) const {
|
||||
image_rectfill(image, x, y, x+m_width-1, y+m_height-1, 0);
|
||||
layer_render(getFolder(), image, x, y, getCurrentFrame());
|
||||
}
|
||||
|
||||
int getPixel(int x, int y) const;
|
||||
|
||||
private:
|
||||
Sprite* m_self; // pointer to the Sprite
|
||||
int m_imgtype; // image type
|
||||
int m_width; // image width (in pixels)
|
||||
int m_height; // image height (in pixels)
|
||||
int m_frames; // how many frames has this sprite
|
||||
std::vector<int> m_frlens; // duration per frame
|
||||
int m_frame; // current frame, range [0,frames)
|
||||
PalettesList m_palettes; // list of palettes
|
||||
Stock* m_stock; // stock to get images
|
||||
LayerFolder* m_folder; // main folder of layers
|
||||
Layer* m_layer; // current layer
|
||||
|
||||
// Current rgb map
|
||||
RgbMap* m_rgbMap;
|
||||
|
||||
// Transparent color used in indexed images
|
||||
ase_uint32 m_transparentColor;
|
||||
};
|
||||
|
||||
SpriteImpl::SpriteImpl(Sprite* sprite, int imgtype, int width, int height, int ncolors)
|
||||
: m_self(sprite)
|
||||
Sprite::Sprite(int imgtype, int width, int height, int ncolors)
|
||||
: GfxObj(GFXOBJ_SPRITE)
|
||||
, m_imgtype(imgtype)
|
||||
, m_width(width)
|
||||
, m_height(height)
|
||||
@ -260,7 +45,7 @@ SpriteImpl::SpriteImpl(Sprite* sprite, int imgtype, int width, int height, int n
|
||||
m_frlens.push_back(100); // First frame with 100 msecs of duration
|
||||
m_frame = 0;
|
||||
m_stock = new Stock(imgtype);
|
||||
m_folder = new LayerFolder(m_self);
|
||||
m_folder = new LayerFolder(this);
|
||||
m_layer = NULL;
|
||||
|
||||
// Generate palette
|
||||
@ -294,7 +79,7 @@ SpriteImpl::SpriteImpl(Sprite* sprite, int imgtype, int width, int height, int n
|
||||
setPalette(&pal, true);
|
||||
}
|
||||
|
||||
SpriteImpl::~SpriteImpl()
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
// Destroy layers
|
||||
delete m_folder;
|
||||
@ -315,7 +100,39 @@ SpriteImpl::~SpriteImpl()
|
||||
delete m_rgbMap;
|
||||
}
|
||||
|
||||
int SpriteImpl::getMemSize() const
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Main properties
|
||||
|
||||
void Sprite::setImgType(int imgtype)
|
||||
{
|
||||
m_imgtype = imgtype;
|
||||
}
|
||||
|
||||
void Sprite::setSize(int width, int height)
|
||||
{
|
||||
ASSERT(width > 0);
|
||||
ASSERT(height > 0);
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
bool Sprite::needAlpha() const
|
||||
{
|
||||
switch (m_imgtype) {
|
||||
case IMAGE_RGB:
|
||||
case IMAGE_GRAYSCALE:
|
||||
return (getBackgroundLayer() == NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sprite::setTransparentColor(ase_uint32 color)
|
||||
{
|
||||
m_transparentColor = color;
|
||||
}
|
||||
|
||||
int Sprite::getMemSize() const
|
||||
{
|
||||
Image *image;
|
||||
int i, size = 0;
|
||||
@ -329,7 +146,15 @@ int SpriteImpl::getMemSize() const
|
||||
return size;
|
||||
}
|
||||
|
||||
LayerImage* SpriteImpl::getBackgroundLayer() const
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Layers
|
||||
|
||||
LayerFolder* Sprite::getFolder() const
|
||||
{
|
||||
return m_folder;
|
||||
}
|
||||
|
||||
LayerImage* Sprite::getBackgroundLayer() const
|
||||
{
|
||||
if (getFolder()->get_layers_count() > 0) {
|
||||
Layer* bglayer = *getFolder()->get_layer_begin();
|
||||
@ -342,36 +167,37 @@ LayerImage* SpriteImpl::getBackgroundLayer() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SpriteImpl::setTotalFrames(int frames)
|
||||
Layer* Sprite::getCurrentLayer() const
|
||||
{
|
||||
frames = MAX(1, frames);
|
||||
m_frlens.resize(frames);
|
||||
|
||||
if (frames > m_frames) {
|
||||
int c;
|
||||
for (c=m_frames; c<frames; c++)
|
||||
m_frlens[c] = m_frlens[m_frames-1];
|
||||
}
|
||||
|
||||
m_frames = frames;
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
int SpriteImpl::getPixel(int x, int y) const
|
||||
void Sprite::setCurrentLayer(Layer* layer)
|
||||
{
|
||||
int color = 0;
|
||||
|
||||
if ((x >= 0) && (y >= 0) && (x < m_width) && (y < m_height)) {
|
||||
Image* image = image_new(m_imgtype, 1, 1);
|
||||
image_clear(image, 0);
|
||||
this->render(image, -x, -y);
|
||||
color = image_getpixel(image, 0, 0);
|
||||
image_free(image);
|
||||
}
|
||||
|
||||
return color;
|
||||
m_layer = layer;
|
||||
}
|
||||
|
||||
Palette* SpriteImpl::getPalette(int frame) const
|
||||
int Sprite::countLayers() const
|
||||
{
|
||||
return getFolder()->get_layers_count();
|
||||
}
|
||||
|
||||
Layer* Sprite::indexToLayer(int index) const
|
||||
{
|
||||
int index_count = -1;
|
||||
return index2layer(getFolder(), index, &index_count);
|
||||
}
|
||||
|
||||
int Sprite::layerToIndex(const Layer* layer) const
|
||||
{
|
||||
int index_count = -1;
|
||||
return layer2index(getFolder(), layer, &index_count);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Palettes
|
||||
|
||||
Palette* Sprite::getPalette(int frame) const
|
||||
{
|
||||
ASSERT(frame >= 0);
|
||||
|
||||
@ -393,7 +219,12 @@ Palette* SpriteImpl::getPalette(int frame) const
|
||||
return found;
|
||||
}
|
||||
|
||||
void SpriteImpl::setPalette(Palette* pal, bool truncate)
|
||||
PalettesList Sprite::getPalettes() const
|
||||
{
|
||||
return m_palettes;
|
||||
}
|
||||
|
||||
void Sprite::setPalette(Palette* pal, bool truncate)
|
||||
{
|
||||
ASSERT(pal != NULL);
|
||||
|
||||
@ -421,7 +252,7 @@ void SpriteImpl::setPalette(Palette* pal, bool truncate)
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteImpl::resetPalettes()
|
||||
void Sprite::resetPalettes()
|
||||
{
|
||||
PalettesList::iterator end = m_palettes.end();
|
||||
PalettesList::iterator it = m_palettes.begin();
|
||||
@ -436,7 +267,7 @@ void SpriteImpl::resetPalettes()
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteImpl::deletePalette(Palette* pal)
|
||||
void Sprite::deletePalette(Palette* pal)
|
||||
{
|
||||
ASSERT(pal != NULL);
|
||||
|
||||
@ -444,208 +275,67 @@ void SpriteImpl::deletePalette(Palette* pal)
|
||||
delete pal; // palette
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Constructors/Destructor
|
||||
|
||||
Sprite::Sprite()
|
||||
: GfxObj(GFXOBJ_SPRITE)
|
||||
, m_impl(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Sprite::Sprite(int imgtype, int width, int height, int ncolors)
|
||||
: GfxObj(GFXOBJ_SPRITE)
|
||||
, m_impl(new SpriteImpl(this, imgtype, width, height, ncolors))
|
||||
{
|
||||
}
|
||||
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Main properties
|
||||
|
||||
int Sprite::getImgType() const
|
||||
{
|
||||
return m_impl->getImgType();
|
||||
}
|
||||
|
||||
void Sprite::setImgType(int imgtype)
|
||||
{
|
||||
m_impl->setImgType(imgtype);
|
||||
}
|
||||
|
||||
int Sprite::getWidth() const
|
||||
{
|
||||
return m_impl->getWidth();
|
||||
}
|
||||
|
||||
int Sprite::getHeight() const
|
||||
{
|
||||
return m_impl->getHeight();
|
||||
}
|
||||
|
||||
void Sprite::setSize(int width, int height)
|
||||
{
|
||||
m_impl->setSize(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns true if the rendered images will contain alpha values less than 255.
|
||||
|
||||
@note Only RGB and Grayscale images without background needs alpha channel in the render.
|
||||
*/
|
||||
bool Sprite::needAlpha() const
|
||||
{
|
||||
return m_impl->needAlpha();
|
||||
}
|
||||
|
||||
ase_uint32 Sprite::getTransparentColor() const
|
||||
{
|
||||
return m_impl->getTransparentColor();
|
||||
}
|
||||
|
||||
void Sprite::setTransparentColor(ase_uint32 color)
|
||||
{
|
||||
m_impl->setTransparentColor(color);
|
||||
}
|
||||
|
||||
int Sprite::getMemSize() const
|
||||
{
|
||||
return m_impl->getMemSize();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Layers
|
||||
|
||||
LayerFolder* Sprite::getFolder() const
|
||||
{
|
||||
return m_impl->getFolder();
|
||||
}
|
||||
|
||||
LayerImage* Sprite::getBackgroundLayer() const
|
||||
{
|
||||
return m_impl->getBackgroundLayer();
|
||||
}
|
||||
|
||||
Layer* Sprite::getCurrentLayer() const
|
||||
{
|
||||
return m_impl->getCurrentLayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the current layer
|
||||
*/
|
||||
void Sprite::setCurrentLayer(Layer* layer)
|
||||
{
|
||||
m_impl->setCurrentLayer(layer);
|
||||
}
|
||||
|
||||
int Sprite::countLayers() const
|
||||
{
|
||||
return m_impl->countLayers();
|
||||
}
|
||||
|
||||
Layer* Sprite::indexToLayer(int index) const
|
||||
{
|
||||
return m_impl->indexToLayer(index);
|
||||
}
|
||||
|
||||
int Sprite::layerToIndex(const Layer* layer) const
|
||||
{
|
||||
return m_impl->layerToIndex(layer);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Palettes
|
||||
|
||||
Palette* Sprite::getPalette(int frame) const
|
||||
{
|
||||
return m_impl->getPalette(frame);
|
||||
}
|
||||
|
||||
PalettesList Sprite::getPalettes() const
|
||||
{
|
||||
return m_impl->getPalettes();
|
||||
}
|
||||
|
||||
void Sprite::setPalette(Palette* pal, bool truncate)
|
||||
{
|
||||
m_impl->setPalette(pal, truncate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all palettes from the sprites except the first one.
|
||||
*/
|
||||
void Sprite::resetPalettes()
|
||||
{
|
||||
m_impl->resetPalettes();
|
||||
}
|
||||
|
||||
void Sprite::deletePalette(Palette* pal)
|
||||
{
|
||||
m_impl->deletePalette(pal);
|
||||
}
|
||||
|
||||
Palette* Sprite::getCurrentPalette() const
|
||||
{
|
||||
return m_impl->getCurrentPalette();
|
||||
return getPalette(getCurrentFrame());
|
||||
}
|
||||
|
||||
RgbMap* Sprite::getRgbMap()
|
||||
{
|
||||
return m_impl->getRgbMap(getCurrentFrame());
|
||||
return getRgbMap(getCurrentFrame());
|
||||
}
|
||||
|
||||
RgbMap* Sprite::getRgbMap(int frame)
|
||||
{
|
||||
return m_impl->getRgbMap(frame);
|
||||
if (m_rgbMap == NULL) {
|
||||
m_rgbMap = new RgbMap();
|
||||
m_rgbMap->regenerate(getPalette(frame));
|
||||
}
|
||||
else if (!m_rgbMap->match(getPalette(frame))) {
|
||||
m_rgbMap->regenerate(getPalette(frame));
|
||||
}
|
||||
return m_rgbMap;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Frames
|
||||
|
||||
int Sprite::getTotalFrames() const
|
||||
{
|
||||
return m_impl->getTotalFrames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the quantity of frames
|
||||
*/
|
||||
void Sprite::setTotalFrames(int frames)
|
||||
{
|
||||
m_impl->setTotalFrames(frames);
|
||||
frames = MAX(1, frames);
|
||||
m_frlens.resize(frames);
|
||||
|
||||
if (frames > m_frames) {
|
||||
int c;
|
||||
for (c=m_frames; c<frames; c++)
|
||||
m_frlens[c] = m_frlens[m_frames-1];
|
||||
}
|
||||
|
||||
m_frames = frames;
|
||||
}
|
||||
|
||||
int Sprite::getFrameDuration(int frame) const
|
||||
{
|
||||
return m_impl->getFrameDuration(frame);
|
||||
if (frame >= 0 && frame < m_frames)
|
||||
return m_frlens[frame];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Sprite::setFrameDuration(int frame, int msecs)
|
||||
{
|
||||
m_impl->setFrameDuration(frame, msecs);
|
||||
if (frame >= 0 && frame < m_frames)
|
||||
m_frlens[frame] = MID(1, msecs, 65535);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a constant frame-rate.
|
||||
*/
|
||||
void Sprite::setDurationForAllFrames(int msecs)
|
||||
{
|
||||
m_impl->setDurationForAllFrames(msecs);
|
||||
}
|
||||
|
||||
int Sprite::getCurrentFrame() const
|
||||
{
|
||||
return m_impl->getCurrentFrame();
|
||||
std::fill(m_frlens.begin(), m_frlens.end(), MID(1, msecs, 65535));
|
||||
}
|
||||
|
||||
void Sprite::setCurrentFrame(int frame)
|
||||
{
|
||||
m_impl->setCurrentFrame(frame);
|
||||
m_frame = frame;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -653,22 +343,59 @@ void Sprite::setCurrentFrame(int frame)
|
||||
|
||||
Stock* Sprite::getStock() const
|
||||
{
|
||||
return m_impl->getStock();
|
||||
return m_stock;
|
||||
}
|
||||
|
||||
Image* Sprite::getCurrentImage(int* x, int* y, int* opacity) const
|
||||
{
|
||||
return m_impl->getCurrentImage(x, y, opacity);
|
||||
Image* image = NULL;
|
||||
|
||||
if (getCurrentLayer() != NULL &&
|
||||
getCurrentLayer()->is_image()) {
|
||||
const Cel* cel = static_cast<const LayerImage*>(getCurrentLayer())->getCel(getCurrentFrame());
|
||||
if (cel) {
|
||||
ASSERT((cel->image >= 0) &&
|
||||
(cel->image < getStock()->size()));
|
||||
|
||||
image = getStock()->getImage(cel->image);
|
||||
|
||||
if (x) *x = cel->x;
|
||||
if (y) *y = cel->y;
|
||||
if (opacity) *opacity = MID(0, cel->opacity, 255);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void Sprite::getCels(CelList& cels)
|
||||
{
|
||||
m_impl->getCels(cels);
|
||||
getFolder()->getCels(cels);
|
||||
}
|
||||
|
||||
void Sprite::remapImages(int frame_from, int frame_to, const std::vector<int>& mapping)
|
||||
{
|
||||
m_impl->remapImages(frame_from, frame_to, mapping);
|
||||
ASSERT(m_imgtype == IMAGE_INDEXED);
|
||||
ASSERT(mapping.size() == 256);
|
||||
|
||||
CelList cels;
|
||||
getCels(cels);
|
||||
|
||||
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
|
||||
Cel* cel = *it;
|
||||
|
||||
// Remap this Cel because is inside the specified range
|
||||
if (cel->frame >= frame_from &&
|
||||
cel->frame <= frame_to) {
|
||||
Image* image = getStock()->getImage(cel->image);
|
||||
|
||||
for (int y=0; y<image->h; ++y) {
|
||||
IndexedTraits::address_t ptr = image_address_fast<IndexedTraits>(image, 0, y);
|
||||
for (int x=0; x<image->w; ++x, ++ptr)
|
||||
*ptr = mapping[*ptr];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -676,17 +403,23 @@ void Sprite::remapImages(int frame_from, int frame_to, const std::vector<int>& m
|
||||
|
||||
void Sprite::render(Image* image, int x, int y) const
|
||||
{
|
||||
m_impl->render(image, x, y);
|
||||
image_rectfill(image, x, y, x+m_width-1, y+m_height-1, 0);
|
||||
layer_render(getFolder(), image, x, y, getCurrentFrame());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pixel from the sprite in the specified position. If in the
|
||||
* specified coordinates there're background this routine will return
|
||||
* the 0 color (the mask-color).
|
||||
*/
|
||||
int Sprite::getPixel(int x, int y) const
|
||||
{
|
||||
return m_impl->getPixel(x, y);
|
||||
int color = 0;
|
||||
|
||||
if ((x >= 0) && (y >= 0) && (x < m_width) && (y < m_height)) {
|
||||
Image* image = image_new(m_imgtype, 1, 1);
|
||||
image_clear(image, 0);
|
||||
this->render(image, -x, -y);
|
||||
color = image_getpixel(image, 0, 0);
|
||||
image_free(image);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "base/disable_copying.h"
|
||||
#include "raster/gfxobj.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Image;
|
||||
@ -35,8 +36,6 @@ class Sprite;
|
||||
class RgbMap;
|
||||
|
||||
typedef std::vector<Palette*> PalettesList;
|
||||
typedef std::vector<Mask*> MasksList;
|
||||
typedef std::vector<Path*> PathsList;
|
||||
|
||||
// The main structure used in the whole program to handle a sprite.
|
||||
class Sprite : public GfxObj
|
||||
@ -52,16 +51,19 @@ public:
|
||||
////////////////////////////////////////
|
||||
// Main properties
|
||||
|
||||
int getImgType() const;
|
||||
int getImgType() const { return m_imgtype; }
|
||||
void setImgType(int imgtype);
|
||||
|
||||
int getWidth() const;
|
||||
int getHeight() const;
|
||||
int getWidth() const { return m_width; }
|
||||
int getHeight() const { return m_height; }
|
||||
void setSize(int width, int height);
|
||||
|
||||
// Returns true if the rendered images will contain alpha values less
|
||||
// than 255. Only RGBA and Grayscale images without background needs
|
||||
// alpha channel in the render.
|
||||
bool needAlpha() const;
|
||||
|
||||
ase_uint32 getTransparentColor() const;
|
||||
ase_uint32 getTransparentColor() const { return m_transparentColor; }
|
||||
void setTransparentColor(ase_uint32 color);
|
||||
|
||||
int getMemSize() const;
|
||||
@ -86,7 +88,10 @@ public:
|
||||
PalettesList getPalettes() const;
|
||||
|
||||
void setPalette(Palette* pal, bool truncate);
|
||||
|
||||
// Removes all palettes from the sprites except the first one.
|
||||
void resetPalettes();
|
||||
|
||||
void deletePalette(Palette* pal);
|
||||
|
||||
Palette* getCurrentPalette() const;
|
||||
@ -97,14 +102,18 @@ public:
|
||||
////////////////////////////////////////
|
||||
// Frames
|
||||
|
||||
int getTotalFrames() const;
|
||||
int getTotalFrames() const { return m_frames; }
|
||||
|
||||
// Changes the quantity of frames
|
||||
void setTotalFrames(int frames);
|
||||
|
||||
int getFrameDuration(int frame) const;
|
||||
void setFrameDuration(int frame, int msecs);
|
||||
|
||||
// Sets a constant frame-rate.
|
||||
void setDurationForAllFrames(int msecs);
|
||||
|
||||
int getCurrentFrame() const;
|
||||
int getCurrentFrame() const { return m_frame; }
|
||||
void setCurrentFrame(int frame);
|
||||
|
||||
////////////////////////////////////////
|
||||
@ -122,12 +131,33 @@ public:
|
||||
// Drawing
|
||||
|
||||
void render(Image* image, int x, int y) const;
|
||||
|
||||
// Gets a pixel from the sprite in the specified position. If in the
|
||||
// specified coordinates there're background this routine will
|
||||
// return the 0 color (the mask-color).
|
||||
int getPixel(int x, int y) const;
|
||||
|
||||
private:
|
||||
Sprite();
|
||||
class SpriteImpl* m_impl;
|
||||
Sprite* m_self; // pointer to the Sprite
|
||||
int m_imgtype; // image type
|
||||
int m_width; // image width (in pixels)
|
||||
int m_height; // image height (in pixels)
|
||||
int m_frames; // how many frames has this sprite
|
||||
std::vector<int> m_frlens; // duration per frame
|
||||
int m_frame; // current frame, range [0,frames)
|
||||
PalettesList m_palettes; // list of palettes
|
||||
Stock* m_stock; // stock to get images
|
||||
LayerFolder* m_folder; // main folder of layers
|
||||
Layer* m_layer; // current layer
|
||||
|
||||
// Current rgb map
|
||||
RgbMap* m_rgbMap;
|
||||
|
||||
// Transparent color used in indexed images
|
||||
ase_uint32 m_transparentColor;
|
||||
|
||||
// Disable default constructor and copying
|
||||
Sprite();
|
||||
DISABLE_COPYING(Sprite);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user