Use current working color space in new created files

* Added the gfx::ColorSpace field in doc::ImageSpec
* Removed some methods like Sprites::add(width, height, etc.)
* Prefer methods with ImageSpec as argument (which now includes the color space)
This commit is contained in:
David Capello 2018-10-25 15:23:01 -03:00
parent d80d79d160
commit 81965b904f
33 changed files with 156 additions and 144 deletions

View File

@ -242,7 +242,7 @@
<section id="new_file">
<option id="width" type="int" default="32" />
<option id="height" type="int" default="32" />
<option id="color_mode" type="doc::PixelFormat" default="doc::IMAGE_RGB" />
<option id="color_mode" type="doc::ColorMode" default="doc::ColorMode::RGB" />
<option id="background_color" type="int" default="0" />
<option id="advanced" type="bool" default="false" />
<option id="pixel_ratio" type="std::string" />

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -10,6 +11,7 @@
#include "app/app.h"
#include "app/color.h"
#include "app/color_spaces.h"
#include "app/color_utils.h"
#include "app/commands/command.h"
#include "app/console.h"
@ -72,12 +74,12 @@ void NewFileCommand::onExecute(Context* context)
app::gen::NewSprite window;
// Default values: Indexed, 320x240, Background color
PixelFormat format = pref.newFile.colorMode();
doc::ColorMode colorMode = pref.newFile.colorMode();
// Invalid format in config file.
if (format != IMAGE_RGB &&
format != IMAGE_INDEXED &&
format != IMAGE_GRAYSCALE) {
format = IMAGE_INDEXED;
if (colorMode != ColorMode::RGB &&
colorMode != ColorMode::INDEXED &&
colorMode != ColorMode::GRAYSCALE) {
colorMode = ColorMode::INDEXED;
}
int w = pref.newFile.width();
int h = pref.newFile.height();
@ -96,7 +98,7 @@ void NewFileCommand::onExecute(Context* context)
window.height()->setTextf("%d", MAX(1, h));
// Select image-type
window.colorMode()->setSelectedItem(format);
window.colorMode()->setSelectedItem(int(colorMode));
// Select background color
window.bgColor()->setSelectedItem(bg);
@ -128,15 +130,15 @@ void NewFileCommand::onExecute(Context* context)
bool ok = false;
// Get the options
format = (doc::PixelFormat)window.colorMode()->selectedItem();
colorMode = (doc::ColorMode)window.colorMode()->selectedItem();
w = window.width()->textInt();
h = window.height()->textInt();
bg = window.bgColor()->selectedItem();
static_assert(IMAGE_RGB == 0, "RGB pixel format should be 0");
static_assert(IMAGE_INDEXED == 2, "Indexed pixel format should be 2");
static_assert(int(ColorMode::RGB) == 0, "RGB pixel format should be 0");
static_assert(int(ColorMode::INDEXED) == 2, "Indexed pixel format should be 2");
format = MID(IMAGE_RGB, format, IMAGE_INDEXED);
colorMode = MID(ColorMode::RGB, colorMode, ColorMode::INDEXED);
w = MID(1, w, DOC_SPRITE_MAX_WIDTH);
h = MID(1, h, DOC_SPRITE_MAX_HEIGHT);
bg = MID(0, bg, 2);
@ -153,23 +155,28 @@ void NewFileCommand::onExecute(Context* context)
// Save the configuration
pref.newFile.width(w);
pref.newFile.height(h);
pref.newFile.colorMode(format);
pref.newFile.colorMode(colorMode);
pref.newFile.backgroundColor(bg);
pref.newFile.advanced(window.advancedCheck()->isSelected());
pref.newFile.pixelRatio(window.pixelRatio()->getValue());
// Create the new sprite
ASSERT(format == IMAGE_RGB || format == IMAGE_GRAYSCALE || format == IMAGE_INDEXED);
ASSERT(colorMode == ColorMode::RGB ||
colorMode == ColorMode::GRAYSCALE ||
colorMode == ColorMode::INDEXED);
ASSERT(w > 0 && h > 0);
std::unique_ptr<Sprite> sprite(Sprite::createBasicSprite(format, w, h, ncolors));
std::unique_ptr<Sprite> sprite(
Sprite::createBasicSprite(
ImageSpec(colorMode, w, h, 0,
get_working_rgb_space_from_preferences()), ncolors));
if (window.advancedCheck()->isSelected()) {
sprite->setPixelRatio(
base::convert_to<PixelRatio>(window.pixelRatio()->getValue()));
}
if (sprite->pixelFormat() != IMAGE_GRAYSCALE)
if (sprite->colorMode() != ColorMode::GRAYSCALE)
get_default_palette()->copyColorsTo(sprite->palette(frame_t(0)));
// If the background color isn't transparent, we have to

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -62,10 +63,11 @@ void NewSpriteFromSelectionCommand::onExecute(Context* context)
Palette* palette = sprite->palette(site.frame());
std::unique_ptr<Sprite> dstSprite(
Sprite::createBasicSprite(image->pixelFormat(),
image->width(),
image->height(),
palette->size()));
Sprite::createBasicSprite(ImageSpec((ColorMode)image->pixelFormat(),
image->width(),
image->height(),
palette->size(),
sprite->colorSpace())));
palette->copyColorsTo(dstSprite->palette(frame_t(0)));

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -146,11 +147,6 @@ void Context::executeCommand(Command* command, const Params& params)
#endif
}
void Context::onCreateDocument(CreateDocArgs* args)
{
args->setDocument(new Doc(nullptr));
}
void Context::onAddDocument(Doc* doc)
{
m_lastSelectedDoc = doc;

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -93,7 +94,6 @@ namespace app {
protected:
// DocsObserver impl
void onCreateDocument(CreateDocArgs* args) override;
void onAddDocument(Doc* doc) override;
void onRemoveDocument(Doc* doc) override;

View File

@ -195,17 +195,17 @@ private:
}
Sprite* readSprite(std::ifstream& s) {
PixelFormat format = (PixelFormat)read8(s);
ColorMode mode = (ColorMode)read8(s);
int w = read16(s);
int h = read16(s);
color_t transparentColor = read32(s);
frame_t nframes = read32(s);
if (format != IMAGE_RGB &&
format != IMAGE_INDEXED &&
format != IMAGE_GRAYSCALE) {
if (mode != ColorMode::RGB &&
mode != ColorMode::INDEXED &&
mode != ColorMode::GRAYSCALE) {
if (!m_loadInfo)
Console().printf("Invalid sprite format #%d\n", (int)format);
Console().printf("Invalid sprite color mode #%d\n", (int)mode);
return nullptr;
}
@ -216,14 +216,14 @@ private:
}
if (m_loadInfo) {
m_loadInfo->format = format;
m_loadInfo->mode = mode;
m_loadInfo->width = w;
m_loadInfo->height = h;
m_loadInfo->frames = nframes;
return (Sprite*)1;
}
std::unique_ptr<Sprite> spr(new Sprite(format, w, h, 256));
std::unique_ptr<Sprite> spr(new Sprite(ImageSpec(mode, w, h), 256));
m_sprite = spr.get();
spr->setTransparentColor(transparentColor);
@ -449,14 +449,14 @@ Doc* read_document_with_raw_images(const std::string& dir,
DocumentInfo info;
if (!reader.loadDocumentInfo(info)) {
info.format = IMAGE_RGB;
info.mode = ColorMode::RGB;
info.width = 256;
info.height = 256;
info.filename = "Unknown";
}
info.width = MID(1, info.width, 99999);
info.height = MID(1, info.height, 99999);
Sprite* spr = new Sprite(info.format, info.width, info.height, 256);
Sprite* spr = new Sprite(ImageSpec(info.mode, info.width, info.height), 256);
// Load each image as a new frame
auto lay = new LayerImage(spr);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (c) 2018 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
@ -9,8 +10,8 @@
#pragma once
#include "app/crash/raw_images_as.h"
#include "doc/color_mode.h"
#include "doc/frame.h"
#include "doc/pixel_format.h"
#include <string>
@ -19,14 +20,14 @@ class Doc;
namespace crash {
struct DocumentInfo {
doc::PixelFormat format;
doc::ColorMode mode;
int width;
int height;
doc::frame_t frames;
std::string filename;
DocumentInfo() :
format(doc::IMAGE_RGB),
mode(doc::ColorMode::RGB),
width(0),
height(0),
frames(0) {

View File

@ -38,10 +38,10 @@ Session::Backup::Backup(const std::string& dir)
std::vector<char> buf(1024);
sprintf(&buf[0], "%s Sprite %dx%d, %d %s: %s",
info.format == IMAGE_RGB ? "RGB":
info.format == IMAGE_GRAYSCALE ? "Grayscale":
info.format == IMAGE_INDEXED ? "Indexed":
info.format == IMAGE_BITMAP ? "Bitmap": "Unknown",
info.mode == ColorMode::RGB ? "RGB":
info.mode == ColorMode::GRAYSCALE ? "Grayscale":
info.mode == ColorMode::INDEXED ? "Indexed":
info.mode == ColorMode::BITMAP ? "Bitmap": "Unknown",
info.width, info.height, info.frames,
info.frames == 1 ? "frame": "frames",
info.filename.c_str());

View File

@ -138,7 +138,7 @@ private:
}
bool writeSprite(std::ofstream& s, Sprite* spr) {
write8(s, spr->pixelFormat());
write8(s, int(spr->colorMode()));
write16(s, spr->width());
write16(s, spr->height());
write32(s, spr->transparentColor());

View File

@ -400,9 +400,7 @@ Doc* Doc::duplicate(DuplicateType type) const
{
const Sprite* sourceSprite = sprite();
std::unique_ptr<Sprite> spriteCopyPtr(new Sprite(
sourceSprite->pixelFormat(),
sourceSprite->width(),
sourceSprite->height(),
sourceSprite->spec(),
sourceSprite->palette(frame_t(0))->size()));
std::unique_ptr<Doc> documentCopy(new Doc(spriteCopyPtr.get()));

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -640,28 +641,35 @@ gfx::Size DocExporter::calculateSheetSize(const Samples& samples) const
Doc* DocExporter::createEmptyTexture(const Samples& samples) const
{
PixelFormat pixelFormat = IMAGE_INDEXED;
ColorMode colorMode = ColorMode::INDEXED;
Palette* palette = nullptr;
int maxColors = 256;
gfx::ColorSpacePtr colorSpace;
for (const auto& sample : samples) {
if (sample.isDuplicated() ||
sample.isEmpty())
continue;
// TODO throw a warning if samples contain different color spaces
if (!colorSpace) {
if (sample.sprite())
colorSpace = sample.sprite()->colorSpace();
}
// 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.
if (pixelFormat == IMAGE_INDEXED) {
if (sample.sprite()->pixelFormat() != IMAGE_INDEXED) {
pixelFormat = IMAGE_RGB;
if (colorMode == ColorMode::INDEXED) {
if (sample.sprite()->colorMode() != ColorMode::INDEXED) {
colorMode = ColorMode::RGB;
}
else if (sample.sprite()->getPalettes().size() > 1) {
pixelFormat = IMAGE_RGB;
colorMode = ColorMode::RGB;
}
else if (palette != NULL
&& palette->countDiff(sample.sprite()->palette(frame_t(0)), NULL, NULL) > 0) {
pixelFormat = IMAGE_RGB;
colorMode = ColorMode::RGB;
}
else
palette = sample.sprite()->palette(frame_t(0));
@ -672,7 +680,9 @@ Doc* DocExporter::createEmptyTexture(const Samples& samples) const
std::unique_ptr<Sprite> sprite(
Sprite::createBasicSprite(
pixelFormat, textureSize.w, textureSize.h, maxColors));
ImageSpec(colorMode, textureSize.w, textureSize.h, 0,
colorSpace ? colorSpace: gfx::ColorSpace::MakeNone()),
maxColors));
if (palette != NULL)
sprite->setPalette(palette, false);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (c) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -29,23 +30,6 @@ Docs::~Docs()
deleteAll();
}
Doc* Docs::add(int width, int height, ColorMode mode, int ncolors)
{
// Ask to observers to create the document (maybe a doc::Document or
// a derived class).
CreateDocArgs args;
notify_observers(&DocsObserver::onCreateDocument, &args);
if (!args.document())
args.setDocument(new Doc(nullptr));
std::unique_ptr<Doc> doc(args.document());
doc->sprites().add(width, height, mode, ncolors);
doc->setFilename("Sprite");
doc->setContext(m_ctx); // Change the document context to add the doc in this collection
return doc.release();
}
Doc* Docs::add(Doc* doc)
{
ASSERT(doc != NULL);
@ -63,6 +47,16 @@ Doc* Docs::add(Doc* doc)
return doc;
}
Doc* Docs::add(int width, int height, doc::ColorMode colorMode, int ncolors)
{
std::unique_ptr<Doc> doc(
new Doc(Sprite::createBasicSprite(ImageSpec(colorMode, width, height), ncolors)));
doc->setFilename("Sprite");
doc->setContext(m_ctx); // Change the document context to add the doc in this collection
return doc.release();
}
void Docs::remove(Doc* doc)
{
iterator it = std::find(begin(), end(), doc);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (c) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -42,11 +43,13 @@ namespace app {
bool empty() const { return m_docs.empty(); }
// Add a new documents to the list.
Doc* add(int width, int height,
doc::ColorMode mode = doc::ColorMode::RGB,
int ncolors = 256);
Doc* add(Doc* doc);
// Easy function for testing
Doc* add(int width, int height,
doc::ColorMode colorMode = doc::ColorMode::RGB,
int ncolors = 256);
// Removes a document from the list without deleting it. You must
// to delete the document after removing it.
void remove(Doc* doc);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (c) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -23,7 +24,6 @@ namespace app {
class DocsObserver {
public:
virtual ~DocsObserver() { }
virtual void onCreateDocument(CreateDocArgs* args) { }
virtual void onAddDocument(Doc* doc) { }
virtual void onRemoveDocument(Doc* doc) { }
};

View File

@ -1034,7 +1034,7 @@ Image* FileOp::sequenceImage(PixelFormat pixelFormat, int w, int h)
// Create the image
if (!m_document) {
sprite = new Sprite(pixelFormat, w, h, 256);
sprite = new Sprite(ImageSpec((ColorMode)pixelFormat, w, h), 256);
try {
LayerImage* layer = new LayerImage(sprite);

View File

@ -39,7 +39,8 @@ TEST(File, SeveralSizes)
std::sprintf(&fn[0], "test.ase");
{
std::unique_ptr<Doc> doc(ctx.documents().add(w, h, doc::ColorMode::INDEXED, 256));
std::unique_ptr<Doc> doc(
ctx.documents().add(w, h, doc::ColorMode::INDEXED, 256));
doc->setFilename(&fn[0]);
// Random pixels

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -83,7 +84,7 @@ bool FliFormat::onLoad(FileOp* fop)
Cel* prevCel = nullptr;
// Create the sprite
Sprite* sprite = new Sprite(IMAGE_INDEXED, w, h, 256);
Sprite* sprite = new Sprite(ImageSpec(ColorMode::INDEXED, w, h), 256);
LayerImage* layer = new LayerImage(sprite);
sprite->root()->addLayer(layer);
layer->configureAsBackground();

View File

@ -717,7 +717,7 @@ private:
int w = m_spriteBounds.w;
int h = m_spriteBounds.h;
m_sprite.reset(new Sprite(IMAGE_INDEXED, w, h, ncolors));
m_sprite.reset(new Sprite(ImageSpec(ColorMode::INDEXED, w, h), ncolors));
m_sprite->setTransparentColor(m_bgIndex);
m_currentImage.reset(Image::create(IMAGE_INDEXED, w, h));

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -135,7 +136,7 @@ bool IcoFormat::onLoad(FileOp* fop)
pixelFormat = IMAGE_RGB;
// Create the sprite with one background layer
Sprite* sprite = new Sprite(pixelFormat, width, height, numcolors);
Sprite* sprite = new Sprite(ImageSpec((ColorMode)pixelFormat, width, height), numcolors);
LayerImage* layer = new LayerImage(sprite);
sprite->root()->addLayer(layer);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -141,8 +142,10 @@ bool save_palette(const char* filename, const Palette* pal, int columns)
Context tmpContext;
Doc* doc = tmpContext.documents().add(
w, h, (pal->size() <= 256 ? doc::ColorMode::INDEXED:
doc::ColorMode::RGB), pal->size());
new Doc(Sprite::createBasicSprite(
ImageSpec((pal->size() <= 256 ? doc::ColorMode::INDEXED:
doc::ColorMode::RGB),
w, h), pal->size())));
Sprite* sprite = doc->sprite();
doc->sprite()->setPalette(pal, false);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2015-2018 David Capello
// Copyright (C) 2015 Gabriel Rauter
//
@ -156,7 +157,7 @@ bool WebPFormat::onLoad(FileOp* fop)
const int w = anim_info.canvas_width;
const int h = anim_info.canvas_height;
Sprite* sprite = new Sprite(IMAGE_RGB, w, h, 256);
Sprite* sprite = new Sprite(ImageSpec(ColorMode::RGB, w, h), 256);
LayerImage* layer = new LayerImage(sprite);
sprite->root()->addLayer(layer);
sprite->setTotalFrames(anim_info.frame_count);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -21,6 +22,7 @@
#include "doc/algorithm/resize_image.h"
#include "doc/anidir.h"
#include "doc/brush_pattern.h"
#include "doc/color_mode.h"
#include "doc/frame.h"
#include "doc/layer_list.h"
#include "filters/tiled_mode.h"

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2015-2018 David Capello
//
// This program is distributed under the terms of
@ -16,6 +17,7 @@
#include "app/cmd/remove_slice.h"
#include "app/cmd/set_sprite_size.h"
#include "app/cmd/set_transparent_color.h"
#include "app/color_spaces.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/context.h"
@ -55,12 +57,10 @@ int Sprite_new(lua_State* L)
spec.setWidth(w);
spec.setHeight(h);
spec.setColorMode((doc::ColorMode)colorMode);
spec.setColorSpace(get_working_rgb_space_from_preferences());
}
std::unique_ptr<Sprite> sprite(
Sprite::createBasicSprite(
(doc::PixelFormat)spec.colorMode(),
spec.width(), spec.height(), 256));
std::unique_ptr<Sprite> sprite(Sprite::createBasicSprite(spec, 256));
std::unique_ptr<Doc> doc(new Doc(sprite.get()));
sprite.release();

View File

@ -41,11 +41,11 @@ bool AsepriteDecoder::decode()
// Create the new sprite
std::unique_ptr<doc::Sprite> sprite(
new doc::Sprite(header.depth == 32 ? doc::IMAGE_RGB:
header.depth == 16 ? doc::IMAGE_GRAYSCALE:
doc::IMAGE_INDEXED,
header.width,
header.height,
new doc::Sprite(doc::ImageSpec(header.depth == 32 ? doc::ColorMode::RGB:
header.depth == 16 ? doc::ColorMode::GRAYSCALE:
doc::ColorMode::INDEXED,
header.width,
header.height),
header.ncolors));
// Set frames and speed

View File

@ -23,12 +23,13 @@ namespace doc {
ImageSpec(ColorMode colorMode,
int width,
int height,
int maskColor = 0)
int maskColor = 0,
const gfx::ColorSpacePtr& colorSpace = gfx::ColorSpace::MakeNone())
: m_colorMode(colorMode),
m_width(width),
m_height(height),
m_maskColor(maskColor),
m_colorSpace(gfx::ColorSpace::MakeNone()) {
m_colorSpace(colorSpace) {
ASSERT(width > 0);
ASSERT(height > 0);
}

View File

@ -1,4 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2018 Igara Studio S.A.
// Copyright (c) 2001-2015 David Capello
//
// This file is released under the terms of the MIT license.
@ -9,11 +10,13 @@
#pragma once
#include "doc/blend_funcs.h"
#include "doc/color_mode.h"
#include "doc/pixel_format.h"
namespace doc {
struct RgbTraits {
static const ColorMode color_mode = ColorMode::RGB;
static const PixelFormat pixel_format = IMAGE_RGB;
enum {
@ -41,6 +44,7 @@ namespace doc {
};
struct GrayscaleTraits {
static const ColorMode color_mode = ColorMode::GRAYSCALE;
static const PixelFormat pixel_format = IMAGE_GRAYSCALE;
enum {
@ -68,6 +72,7 @@ namespace doc {
};
struct IndexedTraits {
static const ColorMode color_mode = ColorMode::INDEXED;
static const PixelFormat pixel_format = IMAGE_INDEXED;
enum {
@ -95,6 +100,7 @@ namespace doc {
};
struct BitmapTraits {
static const ColorMode color_mode = ColorMode::BITMAP;
static const PixelFormat pixel_format = IMAGE_BITMAP;
enum {

View File

@ -1,4 +1,5 @@
// Aseprite Document Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (c) 2016-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -21,7 +22,7 @@ using namespace doc;
TEST(LayerList, AreLayersAdjacent)
{
std::unique_ptr<Sprite> spr(new Sprite(IMAGE_RGB, 32, 32, 256));
std::unique_ptr<Sprite> spr(new Sprite(ImageSpec(ColorMode::RGB, 32, 32), 256));
LayerGroup* root = spr->root();
Layer* layer1 = new LayerImage(spr.get());
Layer* layer2 = new LayerImage(spr.get());

View File

@ -33,33 +33,32 @@ namespace doc {
//////////////////////////////////////////////////////////////////////
// Constructors/Destructor
Sprite::Sprite(PixelFormat format, int width, int height, int ncolors)
Sprite::Sprite(const ImageSpec& spec,
int ncolors)
: Object(ObjectType::Sprite)
, m_document(nullptr)
, m_spec((ColorMode)format, width, height, 0)
, m_spec(spec)
, m_pixelRatio(1, 1)
, m_frames(1)
, m_frlens(1, 100) // First frame with 100 msecs of duration
, m_root(new LayerGroup(this))
, m_rgbMap(nullptr) // Initial RGB map
, m_frameTags(this)
, m_slices(this)
{
ASSERT(width > 0 && height > 0);
m_frlens.push_back(100); // First frame with 100 msecs of duration
m_root = new LayerGroup(this);
// Generate palette
switch (format) {
case IMAGE_GRAYSCALE: ncolors = 256; break;
case IMAGE_BITMAP: ncolors = 2; break;
switch (spec.colorMode()) {
case ColorMode::GRAYSCALE: ncolors = 256; break;
case ColorMode::BITMAP: ncolors = 2; break;
}
Palette pal(frame_t(0), ncolors);
switch (format) {
switch (spec.colorMode()) {
// For black and white images
case IMAGE_GRAYSCALE:
case IMAGE_BITMAP:
case ColorMode::GRAYSCALE:
case ColorMode::BITMAP:
for (int c=0; c<ncolors; c++) {
int g = 255 * c / (ncolors-1);
g = MID(0, g, 255);
@ -68,17 +67,9 @@ Sprite::Sprite(PixelFormat format, int width, int height, int ncolors)
break;
}
// Initial RGB map
m_rgbMap = NULL;
setPalette(&pal, true);
}
Sprite::Sprite(const ImageSpec& spec, int ncolors)
: Sprite((PixelFormat)spec.colorMode(), spec.width(), spec.height(), ncolors)
{
}
Sprite::~Sprite()
{
// Destroy layers
@ -97,24 +88,25 @@ Sprite::~Sprite()
}
// static
Sprite* Sprite::createBasicSprite(doc::PixelFormat format, int width, int height, int ncolors)
Sprite* Sprite::createBasicSprite(const ImageSpec& spec,
const int ncolors)
{
// Create the sprite.
std::unique_ptr<doc::Sprite> sprite(new doc::Sprite(format, width, height, ncolors));
sprite->setTotalFrames(doc::frame_t(1));
std::unique_ptr<Sprite> sprite(new Sprite(spec, ncolors));
sprite->setTotalFrames(frame_t(1));
// Create the main image.
doc::ImageRef image(doc::Image::create(format, width, height));
doc::clear_image(image.get(), 0);
ImageRef image(Image::create(spec));
clear_image(image.get(), 0);
// Create the first transparent layer.
{
std::unique_ptr<doc::LayerImage> layer(new doc::LayerImage(sprite.get()));
std::unique_ptr<LayerImage> layer(new LayerImage(sprite.get()));
layer->setName("Layer 1");
// Create the cel.
{
std::unique_ptr<doc::Cel> cel(new doc::Cel(doc::frame_t(0), image));
std::unique_ptr<Cel> cel(new Cel(frame_t(0), image));
cel->setPosition(0, 0);
// Add the cel in the layer.

View File

@ -56,11 +56,11 @@ namespace doc {
////////////////////////////////////////
// Constructors/Destructor
Sprite(PixelFormat format, int width, int height, int ncolors);
Sprite(const ImageSpec& spec, int ncolors);
Sprite(const ImageSpec& spec, int ncolors = 256);
virtual ~Sprite();
static Sprite* createBasicSprite(PixelFormat format, int width, int height, int ncolors);
static Sprite* createBasicSprite(const ImageSpec& spec,
const int ncolors = 256);
////////////////////////////////////////
// Main properties
@ -71,6 +71,7 @@ namespace doc {
void setDocument(Document* doc) { m_document = doc; }
PixelFormat pixelFormat() const { return (PixelFormat)m_spec.colorMode(); }
ColorMode colorMode() const { return m_spec.colorMode(); }
const PixelRatio& pixelRatio() const { return m_pixelRatio; }
gfx::Size size() const { return m_spec.size(); }
gfx::Rect bounds() const { return m_spec.bounds(); }

View File

@ -1,4 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2018 Igara Studio S.A.
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
@ -20,7 +21,7 @@ using namespace doc;
TEST(Sprite, Layers)
{
Sprite* spr = new Sprite(IMAGE_RGB, 32, 32, 256);
Sprite* spr = new Sprite(ImageSpec(ColorMode::RGB, 32, 32), 256);
LayerImage* lay1 = new LayerImage(spr);
LayerImage* lay2 = new LayerImage(spr);
@ -89,7 +90,7 @@ TEST(Sprite, Layers)
// - lay3: F G~H
TEST(Sprite, CelsRange)
{
Sprite* spr = new Sprite(IMAGE_RGB, 32, 32, 256);
Sprite* spr = new Sprite(ImageSpec(ColorMode::RGB, 32, 32), 256);
spr->setTotalFrames(3);
LayerImage* lay1 = new LayerImage(spr);

View File

@ -1,4 +1,5 @@
// Aseprite Document Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (c) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -32,17 +33,6 @@ Sprites::~Sprites()
deleteAll();
}
Sprite* Sprites::add(int width, int height, ColorMode mode, int ncolors)
{
std::unique_ptr<Sprite> spr(
doc::Sprite::createBasicSprite(
(doc::PixelFormat)mode, width, height, ncolors));
add(spr.get());
return spr.release();
}
Sprite* Sprites::add(Sprite* spr)
{
ASSERT(spr != NULL);

View File

@ -1,4 +1,5 @@
// Aseprite Document Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (c) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -37,7 +38,6 @@ namespace doc {
int size() const { return (int)m_sprites.size(); }
bool empty() const { return m_sprites.empty(); }
Sprite* add(int width, int height, ColorMode mode = ColorMode::RGB, int ncolors = 256);
Sprite* add(Sprite* spr);
void remove(Sprite* spr);
void move(Sprite* spr, int index);

View File

@ -66,7 +66,7 @@ TYPED_TEST_CASE(RenderAllModes, ImageAllTraits);
TEST(Render, Basic)
{
Document* doc = new Document;
doc->sprites().add(2, 2, ColorMode::INDEXED);
doc->sprites().add(Sprite::createBasicSprite(ImageSpec(ColorMode::INDEXED, 2, 2)));
Image* src = doc->sprite()->root()->firstLayer()->cel(0)->image();
clear_image(src, 2);
@ -85,7 +85,7 @@ TYPED_TEST(RenderAllModes, CheckDefaultBackgroundMode)
typedef TypeParam ImageTraits;
Document* doc = new Document;
doc->sprites().add(2, 2, ColorMode(ImageTraits::pixel_format));
doc->sprites().add(Sprite::createBasicSprite(ImageSpec(ImageTraits::color_mode, 2, 2)));
EXPECT_TRUE(!doc->sprite()->root()->firstLayer()->isBackground());
Image* src = doc->sprite()->root()->firstLayer()->cel(0)->image();
@ -105,7 +105,7 @@ TYPED_TEST(RenderAllModes, CheckDefaultBackgroundMode)
TEST(Render, DefaultBackgroundModeWithNonzeroTransparentIndex)
{
Document* doc = new Document;
doc->sprites().add(2, 2, ColorMode::INDEXED);
doc->sprites().add(Sprite::createBasicSprite(ImageSpec(ColorMode::INDEXED, 2, 2)));
doc->sprite()->setTransparentColor(2); // Transparent color is index 2
EXPECT_TRUE(!doc->sprite()->root()->firstLayer()->isBackground());
@ -133,7 +133,7 @@ TEST(Render, DefaultBackgroundModeWithNonzeroTransparentIndex)
TEST(Render, CheckedBackground)
{
Document* doc = new Document;
doc->sprites().add(4, 4, ColorMode::INDEXED);
doc->sprites().add(Sprite::createBasicSprite(ImageSpec(ColorMode::INDEXED, 4, 4)));
std::unique_ptr<Image> dst(Image::create(IMAGE_INDEXED, 4, 4));
clear_image(dst.get(), 0);
@ -185,7 +185,7 @@ TEST(Render, ZoomAndDstBounds)
// 0 4 4
// 0 4 4
Document* doc = new Document;
doc->sprites().add(3, 3, ColorMode::INDEXED);
doc->sprites().add(Sprite::createBasicSprite(ImageSpec(ColorMode::INDEXED, 3, 3)));
Image* src = doc->sprite()->root()->firstLayer()->cel(0)->image();
clear_image(src, 0);
fill_rect(src, 1, 1, 2, 2, 4);
@ -213,7 +213,7 @@ TEST(Render, ZoomAndDstBounds)
TEST(Render, BugWithMultiplesOf3ZoomFactors)
{
Document* doc = new Document;
doc->sprites().add(4, 4, ColorMode::RGB);
doc->sprites().add(Sprite::createBasicSprite(ImageSpec(ColorMode::RGB, 4, 4)));
Image* src = doc->sprite()->root()->firstLayer()->cel(0)->image();
clear_image(src, 0);
draw_line(src, 0, 0, 3, 3, rgba(255, 0, 0, 255));