mirror of
https://github.com/aseprite/aseprite.git
synced 2024-12-29 09:23:32 +00:00
Simple implementation of issue #17 - Export animation to JSON/sprite sheet files
This is a good start point. From here we can add more formats and options (XML, custom formats, templates, etc.), rotated sprites, trim, etc.)
This commit is contained in:
parent
d77efb602e
commit
f531f6d0d0
@ -100,6 +100,7 @@ add_library(app-library
|
||||
data_recovery.cpp
|
||||
document.cpp
|
||||
document_api.cpp
|
||||
document_exporter.cpp
|
||||
document_location.cpp
|
||||
document_undo.cpp
|
||||
documents.cpp
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "app/commands/params.h"
|
||||
#include "app/console.h"
|
||||
#include "app/data_recovery.h"
|
||||
#include "app/document_exporter.h"
|
||||
#include "app/document_location.h"
|
||||
#include "app/document_observer.h"
|
||||
#include "app/drop_files.h"
|
||||
@ -112,6 +113,7 @@ App::App(int argc, const char* argv[])
|
||||
, m_legacy(NULL)
|
||||
, m_isGui(false)
|
||||
, m_isShell(false)
|
||||
, m_exporter(NULL)
|
||||
{
|
||||
ASSERT(m_instance == NULL);
|
||||
m_instance = this;
|
||||
@ -124,6 +126,14 @@ App::App(int argc, const char* argv[])
|
||||
m_legacy = new LegacyModules(isGui() ? REQUIRE_INTERFACE: 0);
|
||||
m_files = options.files();
|
||||
|
||||
if (options.hasExporterParams()) {
|
||||
m_exporter.reset(new DocumentExporter);
|
||||
|
||||
m_exporter->setDataFilename(options.data());
|
||||
m_exporter->setTextureFilename(options.sheet());
|
||||
m_exporter->setScale(options.scale());
|
||||
}
|
||||
|
||||
// Register well-known image file types.
|
||||
FileFormatsManager::instance().registerAllFormats();
|
||||
|
||||
@ -186,6 +196,7 @@ int App::run()
|
||||
PRINTF("Processing options...\n");
|
||||
|
||||
{
|
||||
UIContext* context = UIContext::instance();
|
||||
Console console;
|
||||
for (FileList::iterator
|
||||
it = m_files.begin(),
|
||||
@ -199,17 +210,29 @@ int App::run()
|
||||
}
|
||||
else {
|
||||
// Mount and select the sprite
|
||||
UIContext* context = UIContext::instance();
|
||||
context->addDocument(document);
|
||||
|
||||
if (isGui()) {
|
||||
// Recent file
|
||||
// Add the given file in the argument as a "recent file" only
|
||||
// if we are running in GUI mode. If the program is executed
|
||||
// in batch mode this is not desirable.
|
||||
if (isGui())
|
||||
getRecentFiles()->addRecentFile(it->c_str());
|
||||
}
|
||||
|
||||
// Add the document to the exporter.
|
||||
if (m_exporter != NULL)
|
||||
m_exporter->addDocument(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export
|
||||
if (m_exporter != NULL) {
|
||||
PRINTF("Exporting sheet...\n");
|
||||
|
||||
m_exporter->exportSheet();
|
||||
m_exporter.reset(NULL);
|
||||
}
|
||||
|
||||
// Run the GUI
|
||||
if (isGui()) {
|
||||
// Support to drop files from Windows explorer
|
||||
|
@ -39,6 +39,7 @@ namespace raster {
|
||||
|
||||
namespace app {
|
||||
class Document;
|
||||
class DocumentExporter;
|
||||
class LegacyModules;
|
||||
class LoggerModule;
|
||||
class MainWindow;
|
||||
@ -90,6 +91,7 @@ namespace app {
|
||||
bool m_isShell;
|
||||
base::UniquePtr<MainWindow> m_mainWindow;
|
||||
FileList m_files;
|
||||
base::UniquePtr<DocumentExporter> m_exporter;
|
||||
};
|
||||
|
||||
void app_refresh_screen();
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "base/path.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
namespace app {
|
||||
@ -35,10 +36,20 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||
, m_startUI(true)
|
||||
, m_startShell(false)
|
||||
, m_verbose(false)
|
||||
, m_scale(1.0)
|
||||
{
|
||||
Option& palette = m_po.add("palette").requiresValue("GFXFILE").description("Use a specific palette by default");
|
||||
Option& palette = m_po.add("palette").requiresValue("<filename>").description("Use a specific palette by default");
|
||||
Option& shell = m_po.add("shell").description("Start an interactive console to execute scripts");
|
||||
Option& batch = m_po.add("batch").description("Do not start the UI");
|
||||
// Option& dataFormat = m_po.add("format").requiresValue("<name>").description("Select the format for the sprite sheet data");
|
||||
Option& data = m_po.add("data").requiresValue("<filename>").description("File to store the sprite sheet metadata (.json file)");
|
||||
//Option& textureFormat = m_po.add("texture-format").requiresValue("<name>").description("Output texture format.");
|
||||
Option& sheet = m_po.add("sheet").requiresValue("<filename>").description("Image file to save the texture (.png)");
|
||||
//Option& scale = m_po.add("scale").requiresValue("<float>").description("");
|
||||
//Option& scaleMode = m_po.add("scale-mode").requiresValue("<mode>").description("Export the first given document to a JSON object");
|
||||
//Option& splitLayers = m_po.add("split-layers").description("Specifies that each layer of the given file should be saved as a different image in the sheet.");
|
||||
//Option& rotsprite = m_po.add("rotsprite").requiresValue("<angle1,angle2,...>").description("Specifies different angles to export the given image.");
|
||||
//Option& merge = m_po.add("merge").requiresValue("<datafiles>").description("Merge several sprite sheets in one.");
|
||||
Option& verbose = m_po.add("verbose").description("Explain what is being done (in stderr or a log file)");
|
||||
Option& help = m_po.add("help").mnemonic('?').description("Display this help and exits");
|
||||
Option& version = m_po.add("version").description("Output version information and exit");
|
||||
@ -49,6 +60,13 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||
m_verbose = verbose.enabled();
|
||||
m_paletteFileName = palette.value();
|
||||
m_startShell = shell.enabled();
|
||||
// m_dataFormat = dataFormat.value();
|
||||
m_data = data.value();
|
||||
// m_textureFormat = textureFormat.value();
|
||||
m_sheet = sheet.value();
|
||||
// if (scale.enabled())
|
||||
// m_scale = std::strtod(scale.value().c_str(), NULL);
|
||||
// m_scaleMode = scaleMode.value();
|
||||
|
||||
if (help.enabled()) {
|
||||
showHelp();
|
||||
|
@ -41,6 +41,22 @@ public:
|
||||
return m_po.values();
|
||||
}
|
||||
|
||||
// Export options
|
||||
const std::string& dataFormat() const { return m_dataFormat; }
|
||||
const std::string& data() const { return m_data; }
|
||||
const std::string& textureFormat() const { return m_textureFormat; }
|
||||
const std::string& sheet() const { return m_sheet; }
|
||||
const double scale() const { return m_scale; }
|
||||
const std::string& scaleMode() const { return m_scaleMode; }
|
||||
|
||||
bool hasExporterParams() {
|
||||
return
|
||||
!m_dataFormat.empty() ||
|
||||
!m_data.empty() ||
|
||||
!m_textureFormat.empty() ||
|
||||
!m_sheet.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
void showHelp();
|
||||
void showVersion();
|
||||
@ -51,6 +67,13 @@ private:
|
||||
bool m_startShell;
|
||||
bool m_verbose;
|
||||
std::string m_paletteFileName;
|
||||
|
||||
std::string m_dataFormat;
|
||||
std::string m_data;
|
||||
std::string m_textureFormat;
|
||||
std::string m_sheet;
|
||||
double m_scale;
|
||||
std::string m_scaleMode;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
329
src/app/document_exporter.cpp
Normal file
329
src/app/document_exporter.cpp
Normal file
@ -0,0 +1,329 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2013 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/document_exporter.h"
|
||||
|
||||
#include "app/document.h"
|
||||
#include "app/document_api.h"
|
||||
#include "app/file/file.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/path.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "gfx/size.h"
|
||||
#include "raster/cel.h"
|
||||
#include "raster/dithering_method.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/layer.h"
|
||||
#include "raster/palette.h"
|
||||
#include "raster/sprite.h"
|
||||
#include "raster/stock.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace raster;
|
||||
|
||||
namespace app {
|
||||
|
||||
class DocumentExporter::Sample {
|
||||
public:
|
||||
Sample(Document* document, Sprite* sprite,
|
||||
FrameNumber frame, const std::string& filename) :
|
||||
m_document(document),
|
||||
m_sprite(sprite),
|
||||
m_frame(frame),
|
||||
m_filename(filename) {
|
||||
}
|
||||
|
||||
Document* document() const { return m_document; }
|
||||
Sprite* sprite() const { return m_sprite; }
|
||||
FrameNumber frame() const { return m_frame; }
|
||||
std::string filename() const { return m_filename; }
|
||||
const gfx::Size& originalSize() const { return m_originalSize; }
|
||||
const gfx::Rect& trimmedBounds() const { return m_trimmedBounds; }
|
||||
const gfx::Rect& inTextureBounds() const { return m_inTextureBounds; }
|
||||
|
||||
bool trimmed() const {
|
||||
return m_trimmedBounds.x > 0
|
||||
|| m_trimmedBounds.y > 0
|
||||
|| m_trimmedBounds.w != m_originalSize.w
|
||||
|| m_trimmedBounds.h != m_originalSize.h;
|
||||
}
|
||||
|
||||
void setOriginalSize(const gfx::Size& size) { m_originalSize = size; }
|
||||
void setTrimmedBounds(const gfx::Rect& bounds) { m_trimmedBounds = bounds; }
|
||||
void setInTextureBounds(const gfx::Rect& bounds) { m_inTextureBounds = bounds; }
|
||||
|
||||
private:
|
||||
Document* m_document;
|
||||
Sprite* m_sprite;
|
||||
FrameNumber m_frame;
|
||||
std::string m_filename;
|
||||
gfx::Size m_originalSize;
|
||||
gfx::Rect m_trimmedBounds;
|
||||
gfx::Rect m_inTextureBounds;
|
||||
};
|
||||
|
||||
class DocumentExporter::Samples {
|
||||
public:
|
||||
typedef std::list<Sample> List;
|
||||
typedef List::iterator iterator;
|
||||
typedef List::const_iterator const_iterator;
|
||||
|
||||
void addSample(const Sample& sample) {
|
||||
m_samples.push_back(sample);
|
||||
}
|
||||
|
||||
iterator begin() { return m_samples.begin(); }
|
||||
iterator end() { return m_samples.end(); }
|
||||
const_iterator begin() const { return m_samples.begin(); }
|
||||
const_iterator end() const { return m_samples.end(); }
|
||||
|
||||
private:
|
||||
List m_samples;
|
||||
};
|
||||
|
||||
class DocumentExporter::LayoutSamples {
|
||||
public:
|
||||
virtual ~LayoutSamples() { }
|
||||
virtual void layoutSamples(Samples& samples) = 0;
|
||||
};
|
||||
|
||||
class DocumentExporter::SimpleLayoutSamples :
|
||||
public DocumentExporter::LayoutSamples {
|
||||
public:
|
||||
void layoutSamples(Samples& samples) OVERRIDE {
|
||||
const Sprite* oldSprite = NULL;
|
||||
|
||||
gfx::Point framePt(0, 0);
|
||||
for (Samples::iterator it=samples.begin(), end=samples.end();
|
||||
it != end; ++it) {
|
||||
const Sprite* sprite = it->sprite();
|
||||
gfx::Size size(sprite->getWidth(), sprite->getHeight());
|
||||
|
||||
it->setOriginalSize(size);
|
||||
it->setTrimmedBounds(gfx::Rect(gfx::Point(0, 0), size));
|
||||
it->setInTextureBounds(gfx::Rect(framePt, size));
|
||||
|
||||
// All frames of each sprite in one row.
|
||||
if (oldSprite != NULL && oldSprite != it->sprite()) {
|
||||
framePt.x = 0;
|
||||
framePt.y += size.h;
|
||||
}
|
||||
else {
|
||||
framePt.x += size.w;
|
||||
}
|
||||
|
||||
oldSprite = it->sprite();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DocumentExporter::exportSheet()
|
||||
{
|
||||
// We output the metadata to std::cout if the user didn't specify a file.
|
||||
std::ofstream fos;
|
||||
std::streambuf* osbuf;
|
||||
if (m_dataFilename.empty())
|
||||
osbuf = std::cout.rdbuf();
|
||||
else {
|
||||
fos.open(m_dataFilename.c_str(), std::ios::out);
|
||||
osbuf = fos.rdbuf();
|
||||
}
|
||||
std::ostream os(osbuf);
|
||||
|
||||
// Steps for sheet construction:
|
||||
// 1) Capture the samples (each sprite+frame pair)
|
||||
Samples samples;
|
||||
captureSamples(samples);
|
||||
|
||||
// 2) Layout those samples in a texture field.
|
||||
SimpleLayoutSamples layout;
|
||||
layout.layoutSamples(samples);
|
||||
|
||||
// 3) Create and render the texture.
|
||||
base::UniquePtr<Document> textureDocument(
|
||||
createEmptyTexture(samples));
|
||||
|
||||
Sprite* texture = textureDocument->getSprite();
|
||||
Image* textureImage = texture->getStock()->getImage(
|
||||
static_cast<LayerImage*>(texture->getFolder()->getFirstLayer())
|
||||
->getCel(FrameNumber(0))->getImage());
|
||||
|
||||
renderTexture(samples, textureImage);
|
||||
|
||||
// Save the metadata.
|
||||
createDataFile(samples, os, textureImage);
|
||||
|
||||
// Save the image files.
|
||||
if (!m_textureFilename.empty()) {
|
||||
textureDocument->setFilename(m_textureFilename.c_str());
|
||||
save_document(textureDocument.get());
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentExporter::captureSamples(Samples& samples)
|
||||
{
|
||||
std::vector<char> buf(32);
|
||||
|
||||
for (std::vector<Document*>::iterator
|
||||
it = m_documents.begin(),
|
||||
end = m_documents.end(); it != end; ++it) {
|
||||
Document* document = *it;
|
||||
Sprite* sprite = document->getSprite();
|
||||
|
||||
for (FrameNumber frame=FrameNumber(0);
|
||||
frame<sprite->getTotalFrames(); ++frame) {
|
||||
base::string filename = document->getFilename();
|
||||
|
||||
if (sprite->getTotalFrames() > FrameNumber(1)) {
|
||||
int frameNumWidth =
|
||||
(sprite->getTotalFrames() < 10)? 1:
|
||||
(sprite->getTotalFrames() < 100)? 2:
|
||||
(sprite->getTotalFrames() < 1000)? 3: 4;
|
||||
std::sprintf(&buf[0], "%0*d", frameNumWidth, frame);
|
||||
|
||||
base::string path = base::get_file_path(filename);
|
||||
base::string title = base::get_file_title(filename);
|
||||
base::string ext = base::get_file_extension(filename);
|
||||
filename = base::join_path(path, title + &buf[0] + "." + ext);
|
||||
}
|
||||
|
||||
samples.addSample(Sample(document, sprite, frame, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Document* DocumentExporter::createEmptyTexture(const Samples& samples)
|
||||
{
|
||||
Palette* palette = NULL;
|
||||
PixelFormat pixelFormat = IMAGE_INDEXED;
|
||||
gfx::Rect fullTextureBounds;
|
||||
int maxColors = 256;
|
||||
|
||||
for (Samples::const_iterator
|
||||
it = samples.begin(),
|
||||
end = samples.end(); it != end; ++it) {
|
||||
// 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 (it->sprite()->getPixelFormat() != IMAGE_INDEXED) {
|
||||
pixelFormat = IMAGE_RGB;
|
||||
}
|
||||
else if (it->sprite()->getPalettes().size() > 1) {
|
||||
pixelFormat = IMAGE_RGB;
|
||||
}
|
||||
else if (palette != NULL
|
||||
&& palette->countDiff(it->sprite()->getPalette(FrameNumber(0)), NULL, NULL) > 0) {
|
||||
pixelFormat = IMAGE_RGB;
|
||||
}
|
||||
else
|
||||
palette = it->sprite()->getPalette(FrameNumber(0));
|
||||
}
|
||||
|
||||
fullTextureBounds = fullTextureBounds.createUnion(it->inTextureBounds());
|
||||
}
|
||||
|
||||
base::UniquePtr<Document> document(Document::createBasicDocument(pixelFormat,
|
||||
fullTextureBounds.w, fullTextureBounds.h, maxColors));
|
||||
|
||||
if (palette != NULL)
|
||||
document->getSprite()->setPalette(palette, false);
|
||||
|
||||
return document.release();
|
||||
}
|
||||
|
||||
void DocumentExporter::renderTexture(const Samples& samples, Image* textureImage)
|
||||
{
|
||||
textureImage->clear(0);
|
||||
|
||||
for (Samples::const_iterator
|
||||
it = samples.begin(),
|
||||
end = samples.end(); it != end; ++it) {
|
||||
// Make the sprite compatible with the texture so the render()
|
||||
// works correctly.
|
||||
if (it->sprite()->getPixelFormat() != textureImage->getPixelFormat()) {
|
||||
DocumentApi docApi(it->document(), NULL); // DocumentApi without undo
|
||||
docApi.setPixelFormat(it->sprite(), textureImage->getPixelFormat(),
|
||||
DITHERING_NONE);
|
||||
}
|
||||
|
||||
it->sprite()->render(textureImage,
|
||||
it->inTextureBounds().x - it->trimmedBounds().x,
|
||||
it->inTextureBounds().y - it->trimmedBounds().y,
|
||||
it->frame());
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os, Image* textureImage)
|
||||
{
|
||||
os << "{ \"frames\": {\n";
|
||||
for (Samples::const_iterator
|
||||
it = samples.begin(),
|
||||
end = samples.end(); it != end; ) {
|
||||
gfx::Size srcSize = it->originalSize();
|
||||
gfx::Rect spriteSourceBounds = it->trimmedBounds();
|
||||
gfx::Rect frameBounds = it->inTextureBounds();
|
||||
|
||||
os << " \"" << it->filename() << "\": {\n"
|
||||
<< " \"frame\": { "
|
||||
<< "\"x\": " << frameBounds.x << ", "
|
||||
<< "\"y\": " << frameBounds.y << ", "
|
||||
<< "\"w\": " << frameBounds.w << ", "
|
||||
<< "\"h\": " << frameBounds.h << " },\n"
|
||||
<< " \"rotated\": false,\n"
|
||||
<< " \"trimmed\": " << (it->trimmed() ? "true": "false") << ",\n"
|
||||
<< " \"spriteSourceSize\": { "
|
||||
<< "\"x\": " << spriteSourceBounds.x << ", "
|
||||
<< "\"y\": " << spriteSourceBounds.y << ", "
|
||||
<< "\"w\": " << spriteSourceBounds.w << ", "
|
||||
<< "\"h\": " << spriteSourceBounds.h << " },\n"
|
||||
<< " \"sourceSize\": { "
|
||||
<< "\"w\": " << srcSize.w << ", "
|
||||
<< "\"h\": " << srcSize.h << " },\n"
|
||||
<< " \"duration\": " << it->sprite()->getFrameDuration(it->frame()) << "\n"
|
||||
<< " }";
|
||||
|
||||
if (++it != samples.end())
|
||||
os << ",\n";
|
||||
else
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
os << " },\n"
|
||||
<< " \"meta\": {\n"
|
||||
<< " \"app\": \"" << WEBSITE << "\",\n"
|
||||
<< " \"version\": \"" << VERSION << "\",\n";
|
||||
if (!m_textureFilename.empty())
|
||||
os << " \"image\": \"" << m_textureFilename.c_str() << "\",\n";
|
||||
os << " \"format\": \"" << (textureImage->getPixelFormat() == IMAGE_RGB ? "RGBA8888": "I8") << "\",\n"
|
||||
<< " \"size\": { "
|
||||
<< "\"w\": " << textureImage->getWidth() << ", "
|
||||
<< "\"h\": " << textureImage->getHeight() << " },\n"
|
||||
<< " \"scale\": \"" << m_scale << "\"\n"
|
||||
<< " }\n"
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
} // namespace app
|
111
src/app/document_exporter.h
Normal file
111
src/app/document_exporter.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2013 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef APP_DOCUMENT_EXPORTER_H_INCLUDED
|
||||
#define APP_DOCUMENT_EXPORTER_H_INCLUDED
|
||||
|
||||
#include "base/disable_copying.h"
|
||||
#include "gfx/fwd.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
|
||||
namespace raster {
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
class Document;
|
||||
|
||||
class DocumentExporter {
|
||||
public:
|
||||
enum DataFormat {
|
||||
JsonDataFormat,
|
||||
DefaultDataFormat = JsonDataFormat
|
||||
};
|
||||
|
||||
enum TextureFormat {
|
||||
JsonTextureFormat,
|
||||
DefaultTextureFormat = JsonTextureFormat
|
||||
};
|
||||
|
||||
enum ScaleMode {
|
||||
DefaultScaleMode
|
||||
};
|
||||
|
||||
DocumentExporter() :
|
||||
m_dataFormat(DefaultDataFormat),
|
||||
m_textureFormat(DefaultTextureFormat),
|
||||
m_scaleMode(DefaultScaleMode) {
|
||||
}
|
||||
|
||||
void setDataFormat(DataFormat format) {
|
||||
m_dataFormat = format;
|
||||
}
|
||||
|
||||
void setDataFilename(const std::string& filename) {
|
||||
m_dataFilename = filename;
|
||||
}
|
||||
|
||||
void setTextureFormat(TextureFormat format) {
|
||||
m_textureFormat = format;
|
||||
}
|
||||
|
||||
void setTextureFilename(const std::string& filename) {
|
||||
m_textureFilename = filename;
|
||||
}
|
||||
|
||||
void setScale(double scale) {
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
void setScaleMode(ScaleMode mode) {
|
||||
m_scaleMode = mode;
|
||||
}
|
||||
|
||||
void addDocument(Document* document) {
|
||||
m_documents.push_back(document);
|
||||
}
|
||||
|
||||
void exportSheet();
|
||||
|
||||
private:
|
||||
class Sample;
|
||||
class Samples;
|
||||
class LayoutSamples;
|
||||
class SimpleLayoutSamples;
|
||||
|
||||
void captureSamples(Samples& samples);
|
||||
Document* createEmptyTexture(const Samples& samples);
|
||||
void renderTexture(const Samples& samples, raster::Image* textureImage);
|
||||
void createDataFile(const Samples& samples, std::ostream& os, raster::Image* textureImage);
|
||||
|
||||
DataFormat m_dataFormat;
|
||||
std::string m_dataFilename;
|
||||
TextureFormat m_textureFormat;
|
||||
std::string m_textureFilename;
|
||||
double m_scale;
|
||||
ScaleMode m_scaleMode;
|
||||
std::vector<Document*> m_documents;
|
||||
|
||||
DISABLE_COPYING(DocumentExporter);
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -134,6 +134,10 @@ void UIContext::onAddDocument(Document* document)
|
||||
// base method
|
||||
Context::onAddDocument(document);
|
||||
|
||||
// We don't create views in batch mode.
|
||||
if (!App::instance()->isGui())
|
||||
return;
|
||||
|
||||
// Add a new view for this document
|
||||
DocumentView* view = new DocumentView(document, DocumentView::Normal);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user