diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 02fa58c6b..356c9dbf0 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -131,6 +131,7 @@ set(file_formats file/jpeg_format.cpp file/pcx_format.cpp file/png_format.cpp + file/svg_format.cpp file/tga_format.cpp) if(WITH_WEBP_SUPPORT) list(APPEND file_formats file/webp_format.cpp) diff --git a/src/app/file/file_formats_manager.cpp b/src/app/file/file_formats_manager.cpp index de68d408a..143f5eae4 100644 --- a/src/app/file/file_formats_manager.cpp +++ b/src/app/file/file_formats_manager.cpp @@ -28,6 +28,7 @@ extern FileFormat* CreateIcoFormat(); extern FileFormat* CreateJpegFormat(); extern FileFormat* CreatePcxFormat(); extern FileFormat* CreatePngFormat(); +extern FileFormat* CreateSvgFormat(); extern FileFormat* CreateTgaFormat(); #ifdef ASEPRITE_WITH_WEBP_SUPPORT @@ -62,6 +63,7 @@ FileFormatsManager::FileFormatsManager() registerFormat(CreateJpegFormat()); registerFormat(CreatePcxFormat()); registerFormat(CreatePngFormat()); + registerFormat(CreateSvgFormat()); registerFormat(CreateTgaFormat()); #ifdef ASEPRITE_WITH_WEBP_SUPPORT diff --git a/src/app/file/svg_format.cpp b/src/app/file/svg_format.cpp new file mode 100644 index 000000000..d269e1868 --- /dev/null +++ b/src/app/file/svg_format.cpp @@ -0,0 +1,145 @@ +// Aseprite +// Copyright (c) 2018 Igara Studio S.A. +// +// 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/doc.h" +#include "app/file/file.h" +#include "app/file/file_format.h" +#include "app/file/format_options.h" +#include "base/cfile.h" +#include "base/file_handle.h" +#include "doc/doc.h" + +namespace app { + +using namespace base; + +class SvgFormat : public FileFormat { + const char* onGetName() const override { + return "svg"; + } + + void onGetExtensions(base::paths& exts) const override { + exts.push_back("svg"); + } + + dio::FileFormat onGetDioFormat() const override { + return dio::FileFormat::SVG_IMAGE; + } + + int onGetFlags() const override { + return + FILE_SUPPORT_SAVE | + FILE_SUPPORT_RGB | + FILE_SUPPORT_RGBA | + FILE_SUPPORT_GRAY | + FILE_SUPPORT_INDEXED | + FILE_SUPPORT_SEQUENCES; + } + + bool onLoad(FileOp* fop) override; +#ifdef ENABLE_SAVE + bool onSave(FileOp* fop) override; +#endif +}; + +FileFormat* CreateSvgFormat() +{ + return new SvgFormat; +} + + bool SvgFormat::onLoad(FileOp* fop) { return false;} + +#ifdef ENABLE_SAVE + +bool SvgFormat::onSave(FileOp* fop) +{ + const Image* image = fop->sequenceImage(); + int x, y, c, r, g, b, a, alpha; + FileHandle handle(open_file_with_exception_sync_on_close(fop->filename(), "wb")); + FILE* f = handle.get(); + auto printcol = [f](int x, int y, int r, int g, int b, int a) { + fprintf(f, "\n"); + }; + fprintf(f, "\n"); + fprintf(f, "\n", + image->width(), image->height()); + + switch (image->pixelFormat()) { + + case IMAGE_RGB: { + for (y=0; yheight(); y++) { + for (x=0; xwidth(); x++) { + c = get_pixel_fast(image, x, y); + alpha = rgba_geta(c); + if (alpha != 0x00) + printcol(x, y, rgba_getr(c), rgba_getg(c), rgba_getb(c), alpha); + } + fop->setProgress((float)y / (float)(image->height())); + } + break; + } + case IMAGE_GRAYSCALE: { + for (y=0; yheight(); y++) { + for (x=0; xwidth(); x++) { + c = get_pixel_fast(image, x, y); + auto v = graya_getv(c); + alpha = graya_geta(c); + if (alpha != 0x00) + printcol(x, y, v, v, v, alpha); + } + fop->setProgress((float)y / (float)(image->height())); + } + break; + } + case IMAGE_INDEXED: { + unsigned char image_palette[256][4]; + for (y=0; y<256; y++) { + fop->sequenceGetColor(y, &r, &g, &b); + image_palette[y][0] = r; + image_palette[y][1] = g; + image_palette[y][2] = b; + fop->sequenceGetAlpha(y, &a); + image_palette[y][3] = a; + } + color_t mask_color = -1; + if (fop->document()->sprite()->backgroundLayer() == NULL || + !fop->document()->sprite()->backgroundLayer()->isVisible()) { + mask_color = fop->document()->sprite()->transparentColor(); + } + for (y=0; yheight(); y++) { + for (x=0; xwidth(); x++) { + c = get_pixel_fast(image, x, y); + if (c != mask_color) + printcol(x, y, image_palette[c][0] & 0xff, + image_palette[c][1] & 0xff, + image_palette[c][2] & 0xff, + image_palette[c][3] & 0xff); + } + fop->setProgress((float)y / (float)(image->height())); + } + break; + } + } + fprintf(f, ""); + if (ferror(f)) { + fop->setError("Error writing file.\n"); + return false; + } + else { + return true; + } +} +#endif + +} // namespace app diff --git a/src/dio/detect_format.cpp b/src/dio/detect_format.cpp index 9e29dacb6..51af8cbbe 100644 --- a/src/dio/detect_format.cpp +++ b/src/dio/detect_format.cpp @@ -131,6 +131,9 @@ FileFormat detect_format_by_file_extension(const std::string& filename) if (ext == "png") return FileFormat::PNG_IMAGE; + + if (ext == "svg") + return FileFormat::SVG_IMAGE; if (ext == "tga") return FileFormat::TARGA_IMAGE; diff --git a/src/dio/file_format.h b/src/dio/file_format.h index 6650efe2d..60db98736 100644 --- a/src/dio/file_format.h +++ b/src/dio/file_format.h @@ -27,6 +27,7 @@ enum class FileFormat { PAL_PALETTE, PCX_IMAGE, PNG_IMAGE, + SVG_IMAGE, TARGA_IMAGE, WEBP_ANIMATION, };