1 // Aseprite
2 // Copyright (C) 2001-2018  David Capello
3 //
4 // This program is distributed under the terms of
5 // the End-User License Agreement for Aseprite.
6 
7 #ifndef APP_DOC_EXPORTER_H_INCLUDED
8 #define APP_DOC_EXPORTER_H_INCLUDED
9 #pragma once
10 
11 #include "app/sprite_sheet_type.h"
12 #include "base/disable_copying.h"
13 #include "doc/frame.h"
14 #include "doc/image_buffer.h"
15 #include "doc/object_id.h"
16 #include "gfx/fwd.h"
17 
18 #include <iosfwd>
19 #include <map>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 namespace doc {
25   class FrameTag;
26   class Image;
27   class SelectedLayers;
28   class SelectedFrames;
29 }
30 
31 namespace app {
32 
33   class Context;
34   class Doc;
35 
36   class DocExporter {
37   public:
38     enum DataFormat {
39       JsonHashDataFormat,
40       JsonArrayDataFormat,
41       DefaultDataFormat = JsonHashDataFormat
42     };
43 
44     DocExporter();
45 
dataFormat()46     DataFormat dataFormat() const { return m_dataFormat; }
dataFilename()47     const std::string& dataFilename() { return m_dataFilename; }
textureFilename()48     const std::string& textureFilename() { return m_textureFilename; }
textureWidth()49     int textureWidth() const { return m_textureWidth; }
textureHeight()50     int textureHeight() const { return m_textureHeight; }
spriteSheetType()51     SpriteSheetType spriteSheetType() { return m_sheetType; }
ignoreEmptyCels()52     bool ignoreEmptyCels() { return m_ignoreEmptyCels; }
borderPadding()53     int borderPadding() const { return m_borderPadding; }
shapePadding()54     int shapePadding() const { return m_shapePadding; }
innerPadding()55     int innerPadding() const { return m_innerPadding; }
trimCels()56     bool trimCels() const { return m_trimCels; }
filenameFormat()57     const std::string& filenameFormat() const { return m_filenameFormat; }
listFrameTags()58     bool listFrameTags() const { return m_listFrameTags; }
listLayers()59     bool listLayers() const { return m_listLayers; }
60 
setDataFormat(DataFormat format)61     void setDataFormat(DataFormat format) { m_dataFormat = format; }
setDataFilename(const std::string & filename)62     void setDataFilename(const std::string& filename) { m_dataFilename = filename; }
setTextureFilename(const std::string & filename)63     void setTextureFilename(const std::string& filename) { m_textureFilename = filename; }
setTextureWidth(int width)64     void setTextureWidth(int width) { m_textureWidth = width; }
setTextureHeight(int height)65     void setTextureHeight(int height) { m_textureHeight = height; }
setSpriteSheetType(SpriteSheetType type)66     void setSpriteSheetType(SpriteSheetType type) { m_sheetType = type; }
setIgnoreEmptyCels(bool ignore)67     void setIgnoreEmptyCels(bool ignore) { m_ignoreEmptyCels = ignore; }
setBorderPadding(int padding)68     void setBorderPadding(int padding) { m_borderPadding = padding; }
setShapePadding(int padding)69     void setShapePadding(int padding) { m_shapePadding = padding; }
setInnerPadding(int padding)70     void setInnerPadding(int padding) { m_innerPadding = padding; }
setTrimCels(bool trim)71     void setTrimCels(bool trim) { m_trimCels = trim; }
setFilenameFormat(const std::string & format)72     void setFilenameFormat(const std::string& format) { m_filenameFormat = format; }
setListFrameTags(bool value)73     void setListFrameTags(bool value) { m_listFrameTags = value; }
setListLayers(bool value)74     void setListLayers(bool value) { m_listLayers = value; }
setListSlices(bool value)75     void setListSlices(bool value) { m_listSlices = value; }
76 
addDocument(Doc * document,doc::FrameTag * tag,doc::SelectedLayers * selLayers,doc::SelectedFrames * selFrames)77     void addDocument(Doc* document,
78                      doc::FrameTag* tag,
79                      doc::SelectedLayers* selLayers,
80                      doc::SelectedFrames* selFrames) {
81       m_documents.push_back(Item(document, tag, selLayers, selFrames));
82     }
83 
84     Doc* exportSheet(Context* ctx);
85     gfx::Size calculateSheetSize();
86 
87   private:
88     class Sample;
89     class Samples;
90     class LayoutSamples;
91     class SimpleLayoutSamples;
92     class BestFitLayoutSamples;
93 
94     void captureSamples(Samples& samples);
95     void layoutSamples(Samples& samples);
96     gfx::Size calculateSheetSize(const Samples& samples) const;
97     Doc* createEmptyTexture(const Samples& samples) const;
98     void renderTexture(Context* ctx, const Samples& samples, doc::Image* textureImage) const;
99     void createDataFile(const Samples& samples, std::ostream& os, doc::Image* textureImage);
100     void renderSample(const Sample& sample, doc::Image* dst, int x, int y) const;
101 
102     class Item {
103     public:
104       Doc* doc;
105       doc::FrameTag* frameTag;
106       doc::SelectedLayers* selLayers;
107       doc::SelectedFrames* selFrames;
108 
109       Item(Doc* doc,
110            doc::FrameTag* frameTag,
111            doc::SelectedLayers* selLayers,
112            doc::SelectedFrames* selFrames);
113       Item(Item&& other);
114       ~Item();
115 
116       Item() = delete;
117       Item(const Item&) = delete;
118       Item& operator=(const Item&) = delete;
119 
120       int frames() const;
121       doc::frame_t firstFrame() const;
122       doc::SelectedFrames getSelectedFrames() const;
123     };
124     typedef std::vector<Item> Items;
125 
126     DataFormat m_dataFormat;
127     std::string m_dataFilename;
128     std::string m_textureFilename;
129     int m_textureWidth;
130     int m_textureHeight;
131     SpriteSheetType m_sheetType;
132     bool m_ignoreEmptyCels;
133     int m_borderPadding;
134     int m_shapePadding;
135     int m_innerPadding;
136     bool m_trimCels;
137     Items m_documents;
138     std::string m_filenameFormat;
139     doc::ImageBufferPtr m_sampleRenderBuf;
140     bool m_listFrameTags;
141     bool m_listLayers;
142     bool m_listSlices;
143 
144     // Displacement for each tag from/to frames in case we export
145     // them. It's used in case we trim frames outside tags and they
146     // will not be exported at all in the final result.
147     std::map<doc::ObjectId, std::pair<int, int> > m_tagDelta;
148 
149     DISABLE_COPYING(DocExporter);
150   };
151 
152 } // namespace app
153 
154 #endif
155