Merge branch 'master' into beta

This commit is contained in:
David Capello 2016-10-27 12:51:06 -03:00
commit c60e0b915c
75 changed files with 660 additions and 312 deletions

View File

@ -4,18 +4,18 @@
* [Get the source code](#get-the-source-code) * [Get the source code](#get-the-source-code)
* [Dependencies](#dependencies) * [Dependencies](#dependencies)
* [Windows dependencies](#windows-dependencies) * [Windows dependencies](#windows-dependencies)
* [Mac OS X dependencies](#mac-os-x-dependencies) * [macOS dependencies](#macos-dependencies)
* [Linux dependencies](#linux-dependencies) * [Linux dependencies](#linux-dependencies)
* [Compiling](#compiling) * [Compiling](#compiling)
* [Windows details](#windows-details) * [Windows details](#windows-details)
* [Mac OS X details](#mac-os-x-details) * [macOS details](#macos-details)
* [Issues with Retina displays](#issues-with-retina-displays) * [Issues with Retina displays](#issues-with-retina-displays)
* [Linux details](#linux-details) * [Linux details](#linux-details)
* [Using shared third party libraries](#using-shared-third-party-libraries) * [Using shared third party libraries](#using-shared-third-party-libraries)
* [Linux issues](#linux-issues) * [Linux issues](#linux-issues)
* [Building Skia dependency](#building-skia-dependency) * [Building Skia dependency](#building-skia-dependency)
* [Skia on Windows](#skia-on-windows) * [Skia on Windows](#skia-on-windows)
* [Skia on Mac OS X](#skia-on-mac-os-x) * [Skia on macOS](#skia-on-macos)
# Platforms # Platforms
@ -23,7 +23,7 @@ You should be able to compile Aseprite successfully on the following
platforms: platforms:
* Windows 10 + VS2015 Community Edition + Windows 10 SDK * Windows 10 + VS2015 Community Edition + Windows 10 SDK
* Mac OS X 10.11.4 El Capitan + Xcode 7.3 + OS X 10.11 SDK + Skia (without GPU) * macOS 10.12.1 Sierra + Xcode 8.0 + macOS 10.12 SDK + Skia
* Linux + gcc 4.8 with some C++11 support * Linux + gcc 4.8 with some C++11 support
# Get the source code # Get the source code
@ -62,7 +62,7 @@ Aseprite can be compiled with two different back-ends:
removed in future versions. All new development is being done in removed in future versions. All new development is being done in
the new Skia back-end. the new Skia back-end.
2. Skia back-end (Windows, Mac OS X): You will need a compiled version 2. Skia back-end (Windows, macOS): You will need a compiled version
of the Skia library. Please check the details about of the Skia library. Please check the details about
[how to build Skia](#building-skia-dependency) on your platform. [how to build Skia](#building-skia-dependency) on your platform.
@ -83,12 +83,12 @@ After that you have to choose the back-end:
[Windows details](#windows-details) section to know how to call [Windows details](#windows-details) section to know how to call
`cmake` correctly. `cmake` correctly.
## Mac OS X dependencies ## macOS dependencies
On OS X you will need Mac OS X 10.11 SDK and Xcode 7.3 (maybe older On macOS you will need macOS 10.12 SDK and Xcode 8.0 (older versions
versions might work). might work).
Also, you must compile [Skia](#skia-on-mac-os-x) before starting with Also, you must compile [Skia](#skia-on-macos) before starting with
the [compilation](#compiling). the [compilation](#compiling).
## Linux dependencies ## Linux dependencies
@ -121,7 +121,7 @@ The `libxcursor-dev` package is needed to
Here `cmake` needs different options depending on your Here `cmake` needs different options depending on your
platform. You must check the details for platform. You must check the details for
[Windows](#windows-details), [OS X](#mac-os-x-details), and [Windows](#windows-details), [macOS](#macos-details), and
[Linux](#linux-details). Some `cmake` options can be modified using tools like [Linux](#linux-details). Some `cmake` options can be modified using tools like
[`ccmake`](https://cmake.org/cmake/help/latest/manual/ccmake.1.html) [`ccmake`](https://cmake.org/cmake/help/latest/manual/ccmake.1.html)
or [`cmake-gui`](https://cmake.org/cmake/help/latest/manual/cmake-gui.1.html). or [`cmake-gui`](https://cmake.org/cmake/help/latest/manual/cmake-gui.1.html).
@ -150,9 +150,9 @@ with the following arguments:
In this case, `C:\deps\skia` is the directory where Skia was compiled In this case, `C:\deps\skia` is the directory where Skia was compiled
as described in [Skia on Windows](#skia-on-windows) section. as described in [Skia on Windows](#skia-on-windows) section.
## Mac OS X details ## macOS details
After [compiling Skia](#skia-on-mac-os-x), you should run `cmake` with After [compiling Skia](#skia-on-macos), you should run `cmake` with
the following parameters and then `ninja`: the following parameters and then `ninja`:
cd aseprite cd aseprite
@ -161,7 +161,7 @@ the following parameters and then `ninja`:
cmake \ cmake \
-DCMAKE_OSX_ARCHITECTURES=x86_64 \ -DCMAKE_OSX_ARCHITECTURES=x86_64 \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \ -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \
-DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk \ -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk \
-DUSE_ALLEG4_BACKEND=OFF \ -DUSE_ALLEG4_BACKEND=OFF \
-DUSE_SKIA_BACKEND=ON \ -DUSE_SKIA_BACKEND=ON \
-DSKIA_DIR=$HOME/deps/skia \ -DSKIA_DIR=$HOME/deps/skia \
@ -171,7 +171,7 @@ the following parameters and then `ninja`:
ninja aseprite ninja aseprite
In this case, `$HOME/deps/skia` is the directory where Skia was In this case, `$HOME/deps/skia` is the directory where Skia was
compiled as described in [Skia on Mac OS X](#skia-on-mac-os-x) section. compiled as described in [Skia on macOS](#skia-on-macos) section.
### Issues with Retina displays ### Issues with Retina displays
@ -220,7 +220,7 @@ known issues solved in
# Building Skia dependency # Building Skia dependency
When you compile Aseprite with [Skia](https://skia.org) as back-end on When you compile Aseprite with [Skia](https://skia.org) as back-end on
Windows or OS X, you need to compile a specific version of Skia. In Windows or macOS, you need to compile a specific version of Skia. In
the following sections you will find straightforward steps to compile the following sections you will find straightforward steps to compile
Skia. Skia.
@ -260,7 +260,7 @@ lot of packages, please wait and re-run the same command in case it fails.)
More information about these steps in the More information about these steps in the
[official Skia documentation](https://skia.org/user/quick/windows). [official Skia documentation](https://skia.org/user/quick/windows).
## Skia on Mac OS X ## Skia on macOS
These steps will create a `deps` folder in your home directory with a These steps will create a `deps` folder in your home directory with a
couple of subdirectories needed to build Skia (you can change the couple of subdirectories needed to build Skia (you can change the
@ -280,7 +280,7 @@ several minutes to finish:
After this you should have all Skia libraries compiled. When you After this you should have all Skia libraries compiled. When you
[compile Aseprite](#compiling), remember to add [compile Aseprite](#compiling), remember to add
`-DSKIA_DIR=$HOME/deps/skia` parameter to your `cmake` call as `-DSKIA_DIR=$HOME/deps/skia` parameter to your `cmake` call as
described in the [Mac OS X details](#mac-os-x-details) section. described in the [macOS details](#macos-details) section.
More information about these steps in the More information about these steps in the
[official Skia documentation](https://skia.org/user/quick/macos). [official Skia documentation](https://skia.org/user/quick/macos).

View File

@ -1,34 +1,67 @@
GIMP Palette GIMP Palette
Columns: 16
# #
85 0 85 Untitled 0 0 0 Untitled
170 85 170 Untitled 85 0 0 Untitled
255 170 255 Untitled 170 0 0 Untitled
0 0 85 Untitled 255 0 0 Untitled
85 85 170 Untitled 0 85 0 Untitled
170 170 255 Untitled 85 85 0 Untitled
85 170 170 Untitled 170 85 0 Untitled
0 85 85 Untitled 255 85 0 Untitled
170 255 255 Untitled 0 170 0 Untitled
0 85 0 Untitled 85 170 0 Untitled
170 255 170 Untitled 170 170 0 Untitled
85 170 0 Untitled 255 170 0 Untitled
170 255 0 Untitled 0 255 0 Untitled
170 170 0 Untitled 85 255 0 Untitled
85 85 0 Untitled 170 255 0 Untitled
255 255 85 Untitled 255 255 0 Untitled
170 170 85 Untitled 0 0 85 Untitled
255 255 170 Untitled 85 0 85 Untitled
255 170 0 Untitled 170 0 85 Untitled
170 85 0 Untitled 255 0 85 Untitled
255 170 85 Untitled 0 85 85 Untitled
255 85 0 Untitled 85 85 85 Untitled
255 0 0 Untitled 170 85 85 Untitled
170 0 0 Untitled 255 85 85 Untitled
85 0 0 Untitled 0 170 85 Untitled
255 85 85 Untitled 85 170 85 Untitled
170 85 85 Untitled 170 170 85 Untitled
255 170 170 Untitled 255 170 85 Untitled
255 255 255 Untitled 0 255 85 Untitled
170 170 170 Untitled 85 255 85 Untitled
85 85 85 Untitled 170 255 85 Untitled
0 0 0 Untitled 255 255 85 Untitled
0 0 170 Untitled
85 0 170 Untitled
170 0 170 Untitled
255 0 170 Untitled
0 85 170 Untitled
85 85 170 Untitled
170 85 170 Untitled
255 85 170 Untitled
0 170 170 Untitled
85 170 170 Untitled
170 170 170 Untitled
255 170 170 Untitled
0 255 170 Untitled
85 255 170 Untitled
170 255 170 Untitled
255 255 170 Untitled
0 0 255 Untitled
85 0 255 Untitled
170 0 255 Untitled
255 0 255 Untitled
0 85 255 Untitled
85 85 255 Untitled
170 85 255 Untitled
255 85 255 Untitled
0 170 255 Untitled
85 170 255 Untitled
170 170 255 Untitled
255 170 255 Untitled
0 255 255 Untitled
85 255 255 Untitled
170 255 255 Untitled
255 255 255 Untitled

View File

@ -59,7 +59,7 @@
<enum id="SelectionMode"> <enum id="SelectionMode">
<value id="DEFAULT" value="0" /> <value id="DEFAULT" value="0" />
<value id="ADD" value="1" /> <value id="ADD" value="1" />
! <value id="SUBTRACT" value="2" /> <value id="SUBTRACT" value="2" />
</enum> </enum>
<enum id="PivotPosition"> <enum id="PivotPosition">
<value id="NORTHWEST" value="0" /> <value id="NORTHWEST" value="0" />

View File

@ -109,6 +109,7 @@ add_subdirectory(gen)
add_subdirectory(gfx) add_subdirectory(gfx)
add_subdirectory(net) add_subdirectory(net)
add_subdirectory(render) add_subdirectory(render)
add_subdirectory(docio)
add_subdirectory(script) add_subdirectory(script)
add_subdirectory(she) add_subdirectory(she)
add_subdirectory(ui) add_subdirectory(ui)

View File

@ -47,11 +47,11 @@ because they don't depend on any other component.
## Level 4 ## Level 4
* [iff](iff/) (base, doc, render): Image File Formats library (load/save documents). * [docio](docio/) (base, flic): Load/save documents.
## Level 5 ## Level 5
* [app](app/) (allegro, base, doc, filters, fixmath, gfx, iff, pen, render, scripting, she, ui, undo, updater, webserver) * [app](app/) (allegro, base, doc, docio, filters, fixmath, flic, gfx, pen, render, scripting, she, ui, undo, updater, webserver)
## Level 6 ## Level 6

View File

@ -460,6 +460,7 @@ target_link_libraries(app-lib
clip clip
css-lib css-lib
doc-lib doc-lib
docio-lib
filters-lib filters-lib
fixmath-lib fixmath-lib
flic-lib flic-lib

View File

@ -166,7 +166,7 @@ void App::initialize(const AppOptions& options)
m_modules->createDataRecovery(); m_modules->createDataRecovery();
if (isPortable()) if (isPortable())
LOG("Running in portable mode\n"); LOG("APP: Running in portable mode\n");
// Load or create the default palette, or migrate the default // Load or create the default palette, or migrate the default
// palette from an old format palette to the new one, etc. // palette from an old format palette to the new one, etc.
@ -174,7 +174,7 @@ void App::initialize(const AppOptions& options)
// Initialize GUI interface // Initialize GUI interface
if (isGui()) { if (isGui()) {
LOG("GUI mode\n"); LOG("APP: GUI mode\n");
// Setup the GUI cursor and redraw screen // Setup the GUI cursor and redraw screen
@ -202,7 +202,7 @@ void App::initialize(const AppOptions& options)
} }
// Procress options // Procress options
LOG("Processing options...\n"); LOG("APP: Processing options...\n");
{ {
base::UniquePtr<CliDelegate> delegate; base::UniquePtr<CliDelegate> delegate;
if (options.previewCLI()) if (options.previewCLI())
@ -297,11 +297,9 @@ void App::run()
App::~App() App::~App()
{ {
try { try {
LOG("APP: Exit\n");
ASSERT(m_instance == this); ASSERT(m_instance == this);
// Remove Aseprite handlers
LOG("ASE: Uninstalling\n");
// Delete file formats. // Delete file formats.
FileFormatsManager::destroyInstance(); FileFormatsManager::destroyInstance();
@ -325,12 +323,13 @@ App::~App()
m_instance = NULL; m_instance = NULL;
} }
catch (const std::exception& e) { catch (const std::exception& e) {
LOG(ERROR) << "APP: Error: " << e.what() << "\n";
she::error_message(e.what()); she::error_message(e.what());
// no re-throw // no re-throw
} }
catch (...) { catch (...) {
she::error_message("Error closing ASE.\n(uncaught exception)"); she::error_message("Error closing " PACKAGE ".\n(uncaught exception)");
// no re-throw // no re-throw
} }

View File

@ -185,7 +185,7 @@ AppBrushes::AppBrushes()
load(fn); load(fn);
} }
catch (const std::exception& ex) { catch (const std::exception& ex) {
LOG("Error loading user brushes: %s", ex.what()); LOG(ERROR) << "BRSH: Error loading user brushes: " << ex.what() << "\n";
} }
} }

View File

@ -71,7 +71,7 @@ void AppMenus::reload()
//////////////////////////////////////// ////////////////////////////////////////
// Load menus // Load menus
LOG(" - Loading menus from \"%s\"...\n", path); LOG("MENU: Loading menus from %s\n", path);
m_rootMenu.reset(loadMenuById(handle, "main_menu")); m_rootMenu.reset(loadMenuById(handle, "main_menu"));
@ -81,7 +81,7 @@ void AppMenus::reload()
m_rootMenu->insertChild(0, createInvalidVersionMenuitem()); m_rootMenu->insertChild(0, createInvalidVersionMenuitem());
#endif #endif
LOG("Main menu loaded.\n"); LOG("MENU: Main menu loaded.\n");
m_tabPopupMenu.reset(loadMenuById(handle, "tab_popup")); m_tabPopupMenu.reset(loadMenuById(handle, "tab_popup"));
m_documentTabPopupMenu.reset(loadMenuById(handle, "document_tab_popup")); m_documentTabPopupMenu.reset(loadMenuById(handle, "document_tab_popup"));
@ -96,7 +96,7 @@ void AppMenus::reload()
//////////////////////////////////////// ////////////////////////////////////////
// Load keyboard shortcuts for commands // Load keyboard shortcuts for commands
LOG(" - Loading commands keyboard shortcuts from \"%s\"...\n", path); LOG("MENU: Loading commands keyboard shortcuts from %s\n", path);
TiXmlElement* xmlKey = handle TiXmlElement* xmlKey = handle
.FirstChild("gui") .FirstChild("gui")
@ -167,8 +167,6 @@ Menu* AppMenus::loadMenuById(TiXmlHandle& handle, const char* id)
{ {
ASSERT(id != NULL); ASSERT(id != NULL);
//LOG("loadMenuById(%s)\n", id);
// <gui><menus><menu> // <gui><menus><menu>
TiXmlElement* xmlMenu = handle TiXmlElement* xmlMenu = handle
.FirstChild("gui") .FirstChild("gui")
@ -190,8 +188,6 @@ Menu* AppMenus::convertXmlelemToMenu(TiXmlElement* elem)
{ {
Menu* menu = new Menu(); Menu* menu = new Menu();
//LOG("convertXmlelemToMenu(%s, %s, %s)\n", elem->Value(), elem->Attribute("id"), elem->Attribute("text"));
TiXmlElement* child = elem->FirstChildElement(); TiXmlElement* child = elem->FirstChildElement();
while (child) { while (child) {
Widget* menuitem = convertXmlelemToMenuitem(child); Widget* menuitem = convertXmlelemToMenuitem(child);

View File

@ -103,13 +103,13 @@ void DefaultCliDelegate::loadPalette(const CliOpenFile& cof,
void DefaultCliDelegate::exportFiles(DocumentExporter& exporter) void DefaultCliDelegate::exportFiles(DocumentExporter& exporter)
{ {
LOG("Exporting sheet...\n"); LOG("APP: Exporting sheet...\n");
base::UniquePtr<app::Document> spriteSheet(exporter.exportSheet()); base::UniquePtr<app::Document> spriteSheet(exporter.exportSheet());
// Sprite sheet isn't used, we just delete it. // Sprite sheet isn't used, we just delete it.
LOG("Export sprite sheet: Done\n"); LOG("APP: Export sprite sheet: Done\n");
} }
void DefaultCliDelegate::execScript(const std::string& filename) void DefaultCliDelegate::execScript(const std::string& filename)

View File

@ -31,7 +31,7 @@ Cmd::~Cmd()
void Cmd::execute(Context* ctx) void Cmd::execute(Context* ctx)
{ {
#if TRACE_CMD #if TRACE_CMD
TRACE("Cmd: Executing cmd '%s'\n", typeid(*this).name()); TRACE("CMD: Executing cmd '%s'\n", typeid(*this).name());
#endif #endif
ASSERT(m_state == State::NotExecuted); ASSERT(m_state == State::NotExecuted);
@ -48,7 +48,7 @@ void Cmd::execute(Context* ctx)
void Cmd::undo() void Cmd::undo()
{ {
#if TRACE_CMD #if TRACE_CMD
TRACE("Cmd: Undo cmd '%s'\n", typeid(*this).name()); TRACE("CMD: Undo cmd '%s'\n", typeid(*this).name());
#endif #endif
ASSERT(m_state == State::Executed || m_state == State::Redone); ASSERT(m_state == State::Executed || m_state == State::Redone);
@ -63,7 +63,7 @@ void Cmd::undo()
void Cmd::redo() void Cmd::redo()
{ {
#if TRACE_CMD #if TRACE_CMD
TRACE("Cmd: Redo cmd '%s'\n", typeid(*this).name()); TRACE("CMD: Redo cmd '%s'\n", typeid(*this).name());
#endif #endif
ASSERT(m_state == State::Undone); ASSERT(m_state == State::Undone);

View File

@ -125,7 +125,9 @@ private:
case kKeyDownMessage: case kKeyDownMessage:
if (opacity()->hasFocus()) { if (opacity()->hasFocus()) {
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyEnter) { KeyScancode scancode = static_cast<KeyMessage*>(msg)->scancode();
if (scancode == kKeyEnter ||
scancode == kKeyEsc) {
onCommitChange(); onCommitChange();
closeWindow(this); closeWindow(this);
return true; return true;

View File

@ -139,7 +139,9 @@ private:
if (name()->hasFocus() || if (name()->hasFocus() ||
opacity()->hasFocus() || opacity()->hasFocus() ||
mode()->hasFocus()) { mode()->hasFocus()) {
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyEnter) { KeyScancode scancode = static_cast<KeyMessage*>(msg)->scancode();
if (scancode == kKeyEnter ||
scancode == kKeyEsc) {
onCommitChange(); onCommitChange();
closeWindow(this); closeWindow(this);
return true; return true;

View File

@ -60,7 +60,7 @@ void Context::executeCommand(Command* command, const Params& params)
ASSERT(command != NULL); ASSERT(command != NULL);
LOG("Context: Executing command '%s'...\n", command->id().c_str()); LOG(VERBOSE) << "CTXT: Executing command " << command->id() << "\n";
try { try {
m_flags.update(this); m_flags.update(this);
@ -70,14 +70,14 @@ void Context::executeCommand(Command* command, const Params& params)
BeforeCommandExecution(ev); BeforeCommandExecution(ev);
if (ev.isCanceled()) { if (ev.isCanceled()) {
LOG("Context: '%s' was canceled/simulated.\n", command->id().c_str()); LOG(VERBOSE) << "CTXT: Command " << command->id() << " was canceled/simulated.\n";
} }
else if (command->isEnabled(this)) { else if (command->isEnabled(this)) {
command->execute(this); command->execute(this);
LOG("Context: '%s' executed successfully\n", command->id().c_str()); LOG(VERBOSE) << "CTXT: Command " << command->id() << " executed successfully\n";
} }
else { else {
LOG("Context: '%s' is disabled\n", command->id().c_str()); LOG(VERBOSE) << "CTXT: Command " << command->id() << " is disabled\n";
} }
AfterCommandExecution(ev); AfterCommandExecution(ev);
@ -87,21 +87,20 @@ void Context::executeCommand(Command* command, const Params& params)
app_rebuild_documents_tabs(); app_rebuild_documents_tabs();
} }
catch (base::Exception& e) { catch (base::Exception& e) {
LOG("Context: Exception caught executing '%s' command\n%s\n", LOG(ERROR) << "CTXT: Exception caught executing " << command->id() << " command\n"
command->id().c_str(), e.what()); << e.what() << "\n";
Console::showException(e); Console::showException(e);
} }
catch (std::exception& e) { catch (std::exception& e) {
LOG("Context: std::exception caught executing '%s' command\n%s\n", LOG(ERROR) << "CTXT: std::exception caught executing " << command->id() << " command\n"
command->id().c_str(), e.what()); << e.what() << "\n";
console.printf("An error ocurred executing the command.\n\nDetails:\n%s", e.what()); console.printf("An error ocurred executing the command.\n\nDetails:\n%s", e.what());
} }
#ifdef NDEBUG #ifdef NDEBUG
catch (...) { catch (...) {
LOG("Context: Unknown exception executing '%s' command\n", LOG(ERROR) << "CTXT: Unknown exception executing " << command->id() << " command\n";
command->id().c_str());
console.printf("An unknown error ocurred executing the command.\n" console.printf("An unknown error ocurred executing the command.\n"
"Please save your work, close the program, try it\n" "Please save your work, close the program, try it\n"

View File

@ -47,14 +47,14 @@ void BackupObserver::stop()
void BackupObserver::onAddDocument(doc::Document* document) void BackupObserver::onAddDocument(doc::Document* document)
{ {
TRACE("DataRecovery: Observe document %p\n", document); TRACE("RECO: Observe document %p\n", document);
base::scoped_lock hold(m_mutex); base::scoped_lock hold(m_mutex);
m_documents.push_back(static_cast<app::Document*>(document)); m_documents.push_back(static_cast<app::Document*>(document));
} }
void BackupObserver::onRemoveDocument(doc::Document* document) void BackupObserver::onRemoveDocument(doc::Document* document)
{ {
TRACE("DataRecovery:: Remove document %p\n", document); TRACE("RECO:: Remove document %p\n", document);
{ {
base::scoped_lock hold(m_mutex); base::scoped_lock hold(m_mutex);
base::remove_from_container(m_documents, static_cast<app::Document*>(document)); base::remove_from_container(m_documents, static_cast<app::Document*>(document));
@ -77,7 +77,7 @@ void BackupObserver::backgroundThread()
while (!m_done) { while (!m_done) {
seconds++; seconds++;
if (seconds >= waitUntil) { if (seconds >= waitUntil) {
TRACE("DataRecovery: Start backup process for %d documents\n", m_documents.size()); TRACE("RECO: Start backup process for %d documents\n", m_documents.size());
base::scoped_lock hold(m_mutex); base::scoped_lock hold(m_mutex);
base::Chrono chrono; base::Chrono chrono;
@ -89,7 +89,7 @@ void BackupObserver::backgroundThread()
m_session->saveDocumentChanges(doc); m_session->saveDocumentChanges(doc);
} }
catch (const std::exception&) { catch (const std::exception&) {
TRACE("DataRecovery: Document '%d' is locked\n", doc->id()); TRACE("RECO: Document '%d' is locked\n", doc->id());
somethingLocked = true; somethingLocked = true;
} }
} }
@ -97,7 +97,7 @@ void BackupObserver::backgroundThread()
seconds = 0; seconds = 0;
waitUntil = (somethingLocked ? lockedPeriod: normalPeriod); waitUntil = (somethingLocked ? lockedPeriod: normalPeriod);
TRACE("DataRecovery: Backup process done (%.16g)\n", chrono.elapsed()); TRACE("RECO: Backup process done (%.16g)\n", chrono.elapsed());
} }
base::this_thread::sleep_for(1.0); base::this_thread::sleep_for(1.0);
} }

View File

@ -29,11 +29,11 @@ DataRecovery::DataRecovery(doc::Context* ctx)
std::string sessionsDir = rf.getFirstOrCreateDefault(); std::string sessionsDir = rf.getFirstOrCreateDefault();
// Existent sessions // Existent sessions
TRACE("DataRecovery: Listing sessions from '%s'\n", sessionsDir.c_str()); TRACE("RECO: Listing sessions from '%s'\n", sessionsDir.c_str());
for (auto& itemname : base::list_files(sessionsDir)) { for (auto& itemname : base::list_files(sessionsDir)) {
std::string itempath = base::join_path(sessionsDir, itemname); std::string itempath = base::join_path(sessionsDir, itemname);
if (base::is_directory(itempath)) { if (base::is_directory(itempath)) {
TRACE("- Session '%s' ", itempath.c_str()); TRACE("RECO: Session '%s' ", itempath.c_str());
SessionPtr session(new Session(itempath)); SessionPtr session(new Session(itempath));
if (!session->isRunning()) { if (!session->isRunning()) {
@ -78,7 +78,7 @@ DataRecovery::DataRecovery(doc::Context* ctx)
m_inProgress.reset(new Session(newSessionDir)); m_inProgress.reset(new Session(newSessionDir));
m_inProgress->create(pid); m_inProgress->create(pid);
TRACE("DataRecovery: Session in progress '%s'\n", newSessionDir.c_str()); TRACE("RECO: Session in progress '%s'\n", newSessionDir.c_str());
m_backup = new BackupObserver(m_inProgress.get(), ctx); m_backup = new BackupObserver(m_inProgress.get(), ctx);
} }

View File

@ -140,7 +140,7 @@ private:
if (!ver) if (!ver)
continue; continue;
TRACE(" - Restoring %s #%d v%d\n", prefix, id, ver); TRACE("RECO: Restoring %s #%d v%d\n", prefix, id, ver);
std::string fn = prefix; std::string fn = prefix;
fn.push_back('-'); fn.push_back('-');
@ -154,11 +154,11 @@ private:
obj = (this->*readMember)(s); obj = (this->*readMember)(s);
if (obj) { if (obj) {
TRACE(" - %s #%d v%d restored successfully\n", prefix, id, ver); TRACE("RECO: %s #%d v%d restored successfully\n", prefix, id, ver);
return obj; return obj;
} }
else { else {
TRACE(" - %s #%d v%d was not restored\n", prefix, id, ver); TRACE("RECO: %s #%d v%d was not restored\n", prefix, id, ver);
} }
} }

View File

@ -136,8 +136,8 @@ void Session::removeFromDisk()
} }
catch (const std::exception& ex) { catch (const std::exception& ex) {
(void)ex; (void)ex;
TRACE("Session directory cannot be removed, it's not empty\nError: '%s'\n", LOG(ERROR) << "RECO: Session directory cannot be removed, it's not empty.\n"
ex.what()); << " Error: " << ex.what() << "\n";
} }
} }
@ -147,7 +147,7 @@ void Session::saveDocumentChanges(app::Document* doc)
app::Context ctx; app::Context ctx;
std::string dir = base::join_path(m_path, std::string dir = base::join_path(m_path,
base::convert_to<std::string>(doc->id())); base::convert_to<std::string>(doc->id()));
TRACE("DataRecovery: Saving document '%s'...\n", dir.c_str()); TRACE("RECO: Saving document '%s'...\n", dir.c_str());
if (!base::is_directory(dir)) if (!base::is_directory(dir))
base::make_directory(dir); base::make_directory(dir);
@ -250,7 +250,7 @@ void Session::deleteDirectory(const std::string& dir)
for (auto& item : base::list_files(dir)) { for (auto& item : base::list_files(dir)) {
std::string objfn = base::join_path(dir, item); std::string objfn = base::join_path(dir, item);
if (base::is_file(objfn)) { if (base::is_file(objfn)) {
TRACE("DataRecovery: Deleting file '%s'\n", objfn.c_str()); TRACE("RECO: Deleting file '%s'\n", objfn.c_str());
base::delete_file(objfn); base::delete_file(objfn);
} }
} }

View File

@ -8,6 +8,10 @@
#include "config.h" #include "config.h"
#endif #endif
// Uncomment this line in case that you want TRACE() lock/unlock
// operations.
//#define DEBUG_DOCUMENT_LOCKS
#include "app/document.h" #include "app/document.h"
#include "app/app.h" #include "app/app.h"
@ -455,7 +459,10 @@ bool Document::lock(LockType lockType, int timeout)
if (m_read_locks == 0 && !m_write_lock) { if (m_read_locks == 0 && !m_write_lock) {
// We can start writting the sprite... // We can start writting the sprite...
m_write_lock = true; m_write_lock = true;
TRACE("Document::lock: Locked <%d> to write\n", id());
#ifdef DEBUG_DOCUMENT_LOCKS
TRACE("DOC: Document::lock: Locked <%d> to write\n", id());
#endif
return true; return true;
} }
break; break;
@ -467,15 +474,21 @@ bool Document::lock(LockType lockType, int timeout)
int delay = MIN(100, timeout); int delay = MIN(100, timeout);
timeout -= delay; timeout -= delay;
TRACE("Document::lock: wait 100 msecs for <%d>\n", id()); #ifdef DEBUG_DOCUMENT_LOCKS
TRACE("DOC: Document::lock: wait 100 msecs for <%d>\n", id());
#endif
base::this_thread::sleep_for(double(delay) / 1000.0); base::this_thread::sleep_for(double(delay) / 1000.0);
} }
else else
break; break;
} }
TRACE("Document::lock: Cannot lock <%d> to %s (has %d read locks and %d write locks)\n", #ifdef DEBUG_DOCUMENT_LOCKS
TRACE("DOC: Document::lock: Cannot lock <%d> to %s (has %d read locks and %d write locks)\n",
id(), (lockType == ReadLock ? "read": "write"), m_read_locks, m_write_lock); id(), (lockType == ReadLock ? "read": "write"), m_read_locks, m_write_lock);
#endif
return false; return false;
} }
@ -489,7 +502,11 @@ bool Document::lockToWrite(int timeout)
ASSERT(!m_write_lock); ASSERT(!m_write_lock);
m_read_locks = 0; m_read_locks = 0;
m_write_lock = true; m_write_lock = true;
TRACE("Document::lockToWrite: Locked <%d> to write\n", id());
#ifdef DEBUG_DOCUMENT_LOCKS
TRACE("DOC: Document::lockToWrite: Locked <%d> to write\n", id());
#endif
return true; return true;
} }
} }
@ -498,15 +515,21 @@ bool Document::lockToWrite(int timeout)
int delay = MIN(100, timeout); int delay = MIN(100, timeout);
timeout -= delay; timeout -= delay;
TRACE("Document::lockToWrite: wait 100 msecs for <%d>\n", id()); #ifdef DEBUG_DOCUMENT_LOCKS
TRACE("DOC: Document::lockToWrite: wait 100 msecs for <%d>\n", id());
#endif
base::this_thread::sleep_for(double(delay) / 1000.0); base::this_thread::sleep_for(double(delay) / 1000.0);
} }
else else
break; break;
} }
TRACE("Document::lockToWrite: Cannot lock <%d> to write (has %d read locks and %d write locks)\n", #ifdef DEBUG_DOCUMENT_LOCKS
TRACE("DOC: Document::lockToWrite: Cannot lock <%d> to write (has %d read locks and %d write locks)\n",
id(), m_read_locks, m_write_lock); id(), m_read_locks, m_write_lock);
#endif
return false; return false;
} }

View File

@ -155,6 +155,7 @@ private:
class AseFormat : public FileFormat { class AseFormat : public FileFormat {
const char* onGetName() const override { return "ase"; } const char* onGetName() const override { return "ase"; }
const char* onGetExtensions() const override { return "ase,aseprite"; } const char* onGetExtensions() const override { return "ase,aseprite"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::ASE_ANIMATION; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -45,6 +45,7 @@ class BmpFormat : public FileFormat {
const char* onGetName() const override { return "bmp"; } const char* onGetName() const override { return "bmp"; }
const char* onGetExtensions() const override { return "bmp"; } const char* onGetExtensions() const override { return "bmp"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::BMP_IMAGE; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -28,6 +28,7 @@
#include "base/shared_ptr.h" #include "base/shared_ptr.h"
#include "base/string.h" #include "base/string.h"
#include "doc/doc.h" #include "doc/doc.h"
#include "docio/detect_format.h"
#include "render/quantization.h" #include "render/quantization.h"
#include "render/render.h" #include "render/render.h"
#include "ui/alert.h" #include "ui/alert.h"
@ -122,13 +123,10 @@ int save_document(Context* context, doc::Document* document)
bool is_static_image_format(const std::string& filename) bool is_static_image_format(const std::string& filename)
{ {
std::string extension =
base::string_to_lower(
base::get_file_extension(filename));
// Get the format through the extension of the filename // Get the format through the extension of the filename
FileFormat* format = FileFormatsManager::instance() FileFormat* format =
->getFileFormatByExtension(extension.c_str()); FileFormatsManager::instance()
->getFileFormat(docio::detect_format_by_file_extension(filename));
return (format && format->support(FILE_SUPPORT_SEQUENCES)); return (format && format->support(FILE_SUPPORT_SEQUENCES));
} }
@ -172,10 +170,7 @@ FileOp* FileOp::createLoadDocumentOperation(Context* context, const char* filena
if (!fop) if (!fop)
return nullptr; return nullptr;
// Get the extension of the filename (in lower case) LOG("FILE: Loading file \"%s\"\n", filename);
std::string extension = base::string_to_lower(base::get_file_extension(filename));
LOG("Loading file \"%s\" (%s)\n", filename, extension.c_str());
// Does file exist? // Does file exist?
if (!base::is_file(filename)) { if (!base::is_file(filename)) {
@ -184,12 +179,12 @@ FileOp* FileOp::createLoadDocumentOperation(Context* context, const char* filena
} }
// Get the format through the extension of the filename // Get the format through the extension of the filename
fop->m_format = FileFormatsManager::instance() fop->m_format = FileFormatsManager::instance()->getFileFormat(
->getFileFormatByExtension(extension.c_str()); docio::detect_format(filename));
if (!fop->m_format || if (!fop->m_format ||
!fop->m_format->support(FILE_SUPPORT_LOAD)) { !fop->m_format->support(FILE_SUPPORT_LOAD)) {
fop->setError("%s can't load \"%s\" files\n", PACKAGE, extension.c_str()); fop->setError("%s can't load \"%s\" file (\"%s\")\n", PACKAGE,
filename, base::get_file_extension(filename).c_str());
goto done; goto done;
} }
@ -274,17 +269,15 @@ FileOp* FileOp::createSaveDocumentOperation(const Context* context,
fop->m_roi = roi; fop->m_roi = roi;
// Get the extension of the filename (in lower case) // Get the extension of the filename (in lower case)
std::string extension = base::string_to_lower(base::get_file_extension(filename)); LOG("FILE: Saving document \"%s\"\n", filename);
LOG("Saving document \"%s\" (%s)\n", filename, extension.c_str());
// Get the format through the extension of the filename // Get the format through the extension of the filename
fop->m_format = FileFormatsManager::instance() fop->m_format = FileFormatsManager::instance()->getFileFormat(
->getFileFormatByExtension(extension.c_str()); docio::detect_format_by_file_extension(filename));
if (!fop->m_format || if (!fop->m_format ||
!fop->m_format->support(FILE_SUPPORT_SAVE)) { !fop->m_format->support(FILE_SUPPORT_SAVE)) {
fop->setError("%s can't save \"%s\" files\n", PACKAGE, extension.c_str()); fop->setError("%s can't save \"%s\" file (\"%s\")\n", PACKAGE,
filename, base::get_file_extension(filename).c_str());
return fop.release(); return fop.release();
} }

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -33,6 +33,11 @@ const char* FileFormat::extensions() const
return onGetExtensions(); return onGetExtensions();
} }
docio::FileFormat FileFormat::docioFormat() const
{
return onGetDocioFormat();
}
bool FileFormat::load(FileOp* fop) bool FileFormat::load(FileOp* fop)
{ {
ASSERT(support(FILE_SUPPORT_LOAD)); ASSERT(support(FILE_SUPPORT_LOAD));

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -9,6 +9,7 @@
#pragma once #pragma once
#include "base/shared_ptr.h" #include "base/shared_ptr.h"
#include "docio/file_format.h"
#include <vector> #include <vector>
@ -44,6 +45,8 @@ namespace app {
const char* name() const; // File format name const char* name() const; // File format name
const char* extensions() const; // Extensions (e.g. "jpeg,jpg") const char* extensions() const; // Extensions (e.g. "jpeg,jpg")
docio::FileFormat docioFormat() const;
bool load(FileOp* fop); bool load(FileOp* fop);
#ifdef ENABLE_SAVE #ifdef ENABLE_SAVE
bool save(FileOp* fop); bool save(FileOp* fop);
@ -70,6 +73,7 @@ namespace app {
protected: protected:
virtual const char* onGetName() const = 0; virtual const char* onGetName() const = 0;
virtual const char* onGetExtensions() const = 0; virtual const char* onGetExtensions() const = 0;
virtual docio::FileFormat onGetDocioFormat() const = 0;
virtual int onGetFlags() const = 0; virtual int onGetFlags() const = 0;
virtual bool onLoad(FileOp* fop) = 0; virtual bool onLoad(FileOp* fop) = 0;

View File

@ -13,6 +13,7 @@
#include "app/file/file_format.h" #include "app/file/file_format.h"
#include "app/file/format_options.h" #include "app/file/format_options.h"
#include "base/string.h" #include "base/string.h"
#include "docio/detect_format.h"
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
@ -93,21 +94,12 @@ FileFormatsList::iterator FileFormatsManager::end()
return m_formats.end(); return m_formats.end();
} }
FileFormat* FileFormatsManager::getFileFormatByExtension(const char* extension) const FileFormat* FileFormatsManager::getFileFormat(const docio::FileFormat docioFormat) const
{ {
char buf[512], *tok; for (FileFormat* ff : m_formats)
if (ff->docioFormat() == docioFormat)
for (FileFormat* ff : m_formats) { return ff;
std::strcpy(buf, ff->extensions()); return nullptr;
for (tok=std::strtok(buf, ","); tok;
tok=std::strtok(NULL, ",")) {
if (base::utf8_icmp(extension, tok) == 0)
return ff;
}
}
return NULL;
} }
} // namespace app } // namespace app

View File

@ -8,6 +8,8 @@
#define APP_FILE_FILE_FORMATS_MANAGER_H_INCLUDED #define APP_FILE_FILE_FORMATS_MANAGER_H_INCLUDED
#pragma once #pragma once
#include "docio/file_format.h"
#include <vector> #include <vector>
namespace app { namespace app {
@ -32,7 +34,7 @@ namespace app {
FileFormatsList::iterator begin(); FileFormatsList::iterator begin();
FileFormatsList::iterator end(); FileFormatsList::iterator end();
FileFormat* getFileFormatByExtension(const char* extension) const; FileFormat* getFileFormat(const docio::FileFormat docioFormat) const;
private: private:
FileFormatsManager(); FileFormatsManager();

View File

@ -27,6 +27,7 @@ using namespace base;
class FliFormat : public FileFormat { class FliFormat : public FileFormat {
const char* onGetName() const override { return "flc"; } const char* onGetName() const override { return "flc"; }
const char* onGetExtensions() const override{ return "flc,fli"; } const char* onGetExtensions() const override{ return "flc,fli"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::FLIC_ANIMATION; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -63,6 +63,7 @@ class GifFormat : public FileFormat {
const char* onGetName() const override { return "gif"; } const char* onGetName() const override { return "gif"; }
const char* onGetExtensions() const override { return "gif"; } const char* onGetExtensions() const override { return "gif"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::GIF_ANIMATION; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |
@ -188,8 +189,8 @@ public:
, m_remap(256) , m_remap(256)
, m_hasLocalColormaps(false) , m_hasLocalColormaps(false)
, m_firstLocalColormap(nullptr) { , m_firstLocalColormap(nullptr) {
TRACE("[GifDecoder] GIF background index=%d\n", (int)m_gifFile->SBackGroundColor); TRACE("GIF: background index=%d\n", (int)m_gifFile->SBackGroundColor);
TRACE("[GifDecoder] GIF global colormap=%d, ncolors=%d\n", TRACE("GIF: global colormap=%d, ncolors=%d\n",
(m_gifFile->SColorMap ? 1: 0), (m_gifFile->SColorMap ? 1: 0),
(m_gifFile->SColorMap ? m_gifFile->SColorMap->ColorCount: 0)); (m_gifFile->SColorMap ? m_gifFile->SColorMap->ColorCount: 0));
} }
@ -309,7 +310,7 @@ private:
UniquePtr<Image> frameImage( UniquePtr<Image> frameImage(
readFrameIndexedImage(frameBounds)); readFrameIndexedImage(frameBounds));
TRACE("[GifDecoder] Frame[%d] transparent index = %d\n", (int)m_frameNum, m_localTransparentIndex); TRACE("GIF: Frame[%d] transparent index = %d\n", (int)m_frameNum, m_localTransparentIndex);
if (m_frameNum == 0) { if (m_frameNum == 0) {
if (m_localTransparentIndex >= 0) if (m_localTransparentIndex >= 0)
@ -324,7 +325,7 @@ private:
// Convert the sprite to RGB if we have more than 256 colors // Convert the sprite to RGB if we have more than 256 colors
if ((m_sprite->pixelFormat() == IMAGE_INDEXED) && if ((m_sprite->pixelFormat() == IMAGE_INDEXED) &&
(m_sprite->palette(m_frameNum)->size() > 256)) { (m_sprite->palette(m_frameNum)->size() > 256)) {
TRACE("[GifDecoder] Converting to RGB because we have %d colors\n", TRACE("GIF: Converting to RGB because we have %d colors\n",
m_sprite->palette(m_frameNum)->size()); m_sprite->palette(m_frameNum)->size());
convertIndexedSpriteToRgb(); convertIndexedSpriteToRgb();
@ -443,7 +444,7 @@ private:
int ncolors = colormap->ColorCount; int ncolors = colormap->ColorCount;
bool isLocalColormap = (m_gifFile->Image.ColorMap ? true: false); bool isLocalColormap = (m_gifFile->Image.ColorMap ? true: false);
TRACE("[GifDecoder] Local colormap=%d, ncolors=%d\n", isLocalColormap, ncolors); TRACE("GIF: Local colormap=%d, ncolors=%d\n", isLocalColormap, ncolors);
// We'll calculate the list of used colormap indexes in this // We'll calculate the list of used colormap indexes in this
// frameImage. // frameImage.
@ -526,7 +527,7 @@ private:
// Number of colors in the image that aren't in the palette. // Number of colors in the image that aren't in the palette.
int missing = (usedNColors - found); int missing = (usedNColors - found);
TRACE("[GifDecoder] Bg index=%d,\n" TRACE("GIF: Bg index=%d,\n"
" Local transparent index=%d,\n" " Local transparent index=%d,\n"
" Need extra index to show bg color=%d,\n " " Need extra index to show bg color=%d,\n "
" Found colors in palette=%d,\n" " Found colors in palette=%d,\n"
@ -644,7 +645,7 @@ private:
m_localTransparentIndex = (extension[1] & 1) ? extension[4]: -1; m_localTransparentIndex = (extension[1] & 1) ? extension[4]: -1;
m_frameDelay = (extension[3] << 8) | extension[2]; m_frameDelay = (extension[3] << 8) | extension[2];
TRACE("[GifDecoder] Disposal method: %d\n Transparent index: %d\n Frame delay: %d\n", TRACE("GIF: Disposal method: %d\n Transparent index: %d\n Frame delay: %d\n",
m_disposalMethod, m_localTransparentIndex, m_frameDelay); m_disposalMethod, m_localTransparentIndex, m_frameDelay);
} }
} }
@ -1058,7 +1059,7 @@ private:
} }
} }
TRACE("[GifEncoder] frameBounds=%d %d %d %d prev=%d %d %d %d next=%d %d %d %d\n", TRACE("GIF: frameBounds=%d %d %d %d prev=%d %d %d %d next=%d %d %d %d\n",
frameBounds.x, frameBounds.y, frameBounds.w, frameBounds.h, frameBounds.x, frameBounds.y, frameBounds.w, frameBounds.h,
prev.x, prev.y, prev.w, prev.h, prev.x, prev.y, prev.w, prev.h,
next.x, next.y, next.w, next.h); next.x, next.y, next.w, next.h);

View File

@ -26,6 +26,7 @@ using namespace base;
class IcoFormat : public FileFormat { class IcoFormat : public FileFormat {
const char* onGetName() const override { return "ico"; } const char* onGetName() const override { return "ico"; }
const char* onGetExtensions() const override { return "ico"; } const char* onGetExtensions() const override { return "ico"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::ICO_IMAGES; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -42,6 +42,7 @@ class JpegFormat : public FileFormat {
const char* onGetName() const override { return "jpeg"; } const char* onGetName() const override { return "jpeg"; }
const char* onGetExtensions() const override { return "jpeg,jpg"; } const char* onGetExtensions() const override { return "jpeg,jpg"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::JPEG_IMAGE; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |
@ -88,7 +89,7 @@ static void output_message(j_common_ptr cinfo)
(*cinfo->err->format_message)(cinfo, buffer); (*cinfo->err->format_message)(cinfo, buffer);
// Put in the log file if. // Put in the log file if.
LOG("JPEG library: \"%s\"\n", buffer); LOG(ERROR) << "JPEG: \"" << buffer << "\"\n";
// Leave the message for the application. // Leave the message for the application.
((struct error_mgr *)cinfo->err)->fop->setError("%s\n", buffer); ((struct error_mgr *)cinfo->err)->fop->setError("%s\n", buffer);

View File

@ -24,6 +24,7 @@
#include "doc/layer.h" #include "doc/layer.h"
#include "doc/palette.h" #include "doc/palette.h"
#include "doc/sprite.h" #include "doc/sprite.h"
#include "docio/detect_format.h"
#include <cstring> #include <cstring>
@ -45,26 +46,34 @@ std::string get_writable_palette_extensions()
return buf; return buf;
} }
Palette* load_palette(const char *filename) Palette* load_palette(const char* filename)
{ {
std::string ext = base::string_to_lower(base::get_file_extension(filename)); docio::FileFormat docioFormat = docio::detect_format(filename);
Palette* pal = NULL; Palette* pal = nullptr;
switch (docioFormat) {
case docio::FileFormat::COL_PALETTE:
pal = doc::file::load_col_file(filename);
break;
case docio::FileFormat::GPL_PALETTE:
pal = doc::file::load_gpl_file(filename);
break;
case docio::FileFormat::HEX_PALETTE:
pal = doc::file::load_hex_file(filename);
break;
case docio::FileFormat::PAL_PALETTE:
pal = doc::file::load_pal_file(filename);
break;
default: {
FileFormat* ff = FileFormatsManager::instance()->getFileFormat(docioFormat);
if (!ff || !ff->support(FILE_SUPPORT_LOAD))
break;
if (ext == "col") {
pal = doc::file::load_col_file(filename);
}
else if (ext == "gpl") {
pal = doc::file::load_gpl_file(filename);
}
else if (ext == "hex") {
pal = doc::file::load_hex_file(filename);
}
else if (ext == "pal") {
pal = doc::file::load_pal_file(filename);
}
else {
FileFormat* ff = FileFormatsManager::instance()->getFileFormatByExtension(ext.c_str());
if (ff && ff->support(FILE_SUPPORT_LOAD)) {
base::UniquePtr<FileOp> fop( base::UniquePtr<FileOp> fop(
FileOp::createLoadDocumentOperation( FileOp::createLoadDocumentOperation(
nullptr, filename, nullptr, filename,
@ -85,6 +94,7 @@ Palette* load_palette(const char *filename)
delete fop->releaseDocument(); delete fop->releaseDocument();
fop->done(); fop->done();
} }
break;
} }
} }
@ -94,26 +104,34 @@ Palette* load_palette(const char *filename)
return pal; return pal;
} }
bool save_palette(const char *filename, const Palette* pal, int columns) bool save_palette(const char* filename, const Palette* pal, int columns)
{ {
std::string ext = base::string_to_lower(base::get_file_extension(filename)); docio::FileFormat docioFormat = docio::detect_format_by_file_extension(filename);
bool success = false; bool success = false;
if (ext == "col") { switch (docioFormat) {
success = doc::file::save_col_file(pal, filename);
} case docio::FileFormat::COL_PALETTE:
else if (ext == "gpl") { success = doc::file::save_col_file(pal, filename);
success = doc::file::save_gpl_file(pal, filename); break;
}
else if (ext == "hex") { case docio::FileFormat::GPL_PALETTE:
success = doc::file::save_hex_file(pal, filename); success = doc::file::save_gpl_file(pal, filename);
} break;
else if (ext == "pal") {
success = doc::file::save_pal_file(pal, filename); case docio::FileFormat::HEX_PALETTE:
} success = doc::file::save_hex_file(pal, filename);
else { break;
FileFormat* ff = FileFormatsManager::instance()->getFileFormatByExtension(ext.c_str());
if (ff && ff->support(FILE_SUPPORT_SAVE)) { case docio::FileFormat::PAL_PALETTE:
success = doc::file::save_pal_file(pal, filename);
break;
default: {
FileFormat* ff = FileFormatsManager::instance()->getFileFormat(docioFormat);
if (!ff || !ff->support(FILE_SUPPORT_SAVE))
break;
int w = (columns > 0 ? MID(0, columns, pal->size()): pal->size()); int w = (columns > 0 ? MID(0, columns, pal->size()): pal->size());
int h = (pal->size() / w) + (pal->size() % w > 0 ? 1: 0); int h = (pal->size() / w) + (pal->size() % w > 0 ? 1: 0);
@ -150,6 +168,7 @@ bool save_palette(const char *filename, const Palette* pal, int columns)
doc->close(); doc->close();
delete doc; delete doc;
break;
} }
} }

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -24,6 +24,7 @@ using namespace base;
class PcxFormat : public FileFormat { class PcxFormat : public FileFormat {
const char* onGetName() const override { return "pcx"; } const char* onGetName() const override { return "pcx"; }
const char* onGetExtensions() const override { return "pcx"; } const char* onGetExtensions() const override { return "pcx"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::PCX_IMAGE; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -31,6 +31,7 @@ using namespace base;
class PixlyFormat : public FileFormat { class PixlyFormat : public FileFormat {
const char* onGetName() const override { return "anim"; } const char* onGetName() const override { return "anim"; }
const char* onGetExtensions() const override { return "anim"; } const char* onGetExtensions() const override { return "anim"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::PIXLY_ANIMATION; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -29,6 +29,7 @@ using namespace base;
class PngFormat : public FileFormat { class PngFormat : public FileFormat {
const char* onGetName() const override { return "png"; } const char* onGetName() const override { return "png"; }
const char* onGetExtensions() const override { return "png"; } const char* onGetExtensions() const override { return "png"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::PNG_IMAGE; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -25,6 +25,7 @@ using namespace base;
class TgaFormat : public FileFormat { class TgaFormat : public FileFormat {
const char* onGetName() const override { return "tga"; } const char* onGetName() const override { return "tga"; }
const char* onGetExtensions() const override { return "tga"; } const char* onGetExtensions() const override { return "tga"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::TARGA_IMAGE; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -41,6 +41,7 @@ class WebPFormat : public FileFormat {
const char* onGetName() const override { return "webp"; } const char* onGetName() const override { return "webp"; }
const char* onGetExtensions() const override { return "webp"; } const char* onGetExtensions() const override { return "webp"; }
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::WEBP_ANIMATION; }
int onGetFlags() const override { int onGetFlags() const override {
return return
FILE_SUPPORT_LOAD | FILE_SUPPORT_LOAD |

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -164,13 +164,10 @@ FileSystemModule::FileSystemModule()
// get the root element of the file system (this will create // get the root element of the file system (this will create
// the 'rootitem' FileItem) // the 'rootitem' FileItem)
getRootFileItem(); getRootFileItem();
LOG("File system module installed\n");
} }
FileSystemModule::~FileSystemModule() FileSystemModule::~FileSystemModule()
{ {
LOG("File system module: uninstalling\n");
ASSERT(m_instance == this); ASSERT(m_instance == this);
for (FileItemMap::iterator for (FileItemMap::iterator
@ -197,7 +194,6 @@ FileSystemModule::~FileSystemModule()
delete fileitems_map; delete fileitems_map;
delete thumbnail_map; delete thumbnail_map;
LOG("File system module: uninstalled\n");
m_instance = NULL; m_instance = NULL;
} }
@ -564,7 +560,7 @@ FileItem::FileItem(FileItem* parent)
FileItem::~FileItem() FileItem::~FileItem()
{ {
LOG("FS: Destroying FileItem() with parent %p\n", m_parent); TRACE("FS: Destroying FileItem() with parent %p\n", m_parent);
#ifdef _WIN32 #ifdef _WIN32
if (m_fullpidl && m_fullpidl != m_pidl) { if (m_fullpidl && m_fullpidl != m_pidl) {

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -28,7 +28,7 @@ GuiXml* GuiXml::instance()
GuiXml::GuiXml() GuiXml::GuiXml()
{ {
LOG("Loading gui.xml file...\n"); LOG("GUIXML: Loading gui.xml file\n");
ResourceFinder rf; ResourceFinder rf;
rf.includeDataDir("gui.xml"); rf.includeDataDir("gui.xml");

View File

@ -31,7 +31,7 @@ LoggerModule::LoggerModule(bool createLogInDesktop)
LoggerModule::~LoggerModule() LoggerModule::~LoggerModule()
{ {
LOG("Logger module: shutting down (this is the last line)\n"); LOG("LOG: Done\n");
// Close log file // Close log file
base::set_log_filename(""); base::set_log_filename("");

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -41,7 +41,7 @@ LegacyModules::LegacyModules(int requirements)
{ {
for (int c=0; c<modules; c++) for (int c=0; c<modules; c++)
if ((module[c].reqs & requirements) == module[c].reqs) { if ((module[c].reqs & requirements) == module[c].reqs) {
LOG("Installing module: %s\n", module[c].name); LOG("MODS: Installing module: %s\n", module[c].name);
if ((*module[c].init)() < 0) if ((*module[c].init)() < 0)
throw base::Exception("Error initializing module: %s", throw base::Exception("Error initializing module: %s",
@ -55,7 +55,7 @@ LegacyModules::~LegacyModules()
{ {
for (int c=modules-1; c>=0; c--) for (int c=modules-1; c>=0; c--)
if (module[c].installed) { if (module[c].installed) {
LOG("Unstalling module: %s\n", module[c].name); LOG("MODS: Unstalling module: %s\n", module[c].name);
(*module[c].exit)(); (*module[c].exit)();
module[c].installed = false; module[c].installed = false;
} }

View File

@ -48,7 +48,7 @@ void HttpLoader::threadHttpRequest()
try { try {
base::ScopedValue<bool> scoped(m_done, false, true); base::ScopedValue<bool> scoped(m_done, false, true);
LOG("Sending http request to %s...\n", m_url.c_str()); LOG("HTTP: Sending http request to %s\n", m_url.c_str());
std::string dir = base::join_path(base::get_temp_path(), PACKAGE); std::string dir = base::join_path(base::get_temp_path(), PACKAGE);
base::make_all_directories(dir); base::make_all_directories(dir);
@ -68,13 +68,13 @@ void HttpLoader::threadHttpRequest()
m_filename = fn; m_filename = fn;
} }
LOG("Response: %d\n", response.status()); LOG("HTTP: Response: %d\n", response.status());
} }
catch (const std::exception& e) { catch (const std::exception& e) {
LOG("Unexpected exception sending http request: '%s'\n", e.what()); LOG(ERROR) << "HTTP: Unexpected exception sending http request: " << e.what() << "\n";
} }
catch (...) { catch (...) {
LOG("Unexpected unknown exception sending http request\n"); LOG(ERROR) << "HTTP: Unexpected unknown exception sending http request\n";
} }
delete m_request; delete m_request;

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -27,14 +27,11 @@ ResourcesLoader::ResourcesLoader(ResourcesLoaderDelegate* delegate)
, m_cancel(false) , m_cancel(false)
, m_thread(base::Bind<void>(&ResourcesLoader::threadLoadResources, this)) , m_thread(base::Bind<void>(&ResourcesLoader::threadLoadResources, this))
{ {
LOG("ResourcesLoader::ResourcesLoader()\n");
} }
ResourcesLoader::~ResourcesLoader() ResourcesLoader::~ResourcesLoader()
{ {
m_thread.join(); m_thread.join();
LOG("ResourcesLoader::~ResourcesLoader()\n");
} }
void ResourcesLoader::cancel() void ResourcesLoader::cancel()
@ -55,12 +52,10 @@ bool ResourcesLoader::next(base::UniquePtr<Resource>& resource)
void ResourcesLoader::threadLoadResources() void ResourcesLoader::threadLoadResources()
{ {
LOG("threadLoadResources()\n");
base::ScopedValue<bool> scoped(m_done, false, true); base::ScopedValue<bool> scoped(m_done, false, true);
std::string path = m_delegate->resourcesLocation(); std::string path = m_delegate->resourcesLocation();
LOG("Loading resources from %s...\n", path.c_str()); TRACE("RESLOAD: Loading resources from %s...\n", path.c_str());
if (path.empty()) if (path.empty())
return; return;

View File

@ -57,7 +57,7 @@ bool ResourceFinder::findFirst()
{ {
while (next()) { while (next()) {
if (m_log) if (m_log)
LOG("Searching file \"%s\"...", filename().c_str()); LOG("FIND: \"%s\"", filename().c_str());
if (base::is_file(filename())) { if (base::is_file(filename())) {
if (m_log) if (m_log)
@ -142,7 +142,7 @@ void ResourceFinder::includeHomeDir(const char* filename)
addPath(buf); addPath(buf);
} }
else { else {
LOG("You don't have set $HOME variable\n"); LOG("FIND: You don't have set $HOME variable\n");
addPath(filename); addPath(filename);
} }

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -81,8 +81,6 @@ const char* WellKnownPointShapes::Spray = "spray";
ToolBox::ToolBox() ToolBox::ToolBox()
{ {
LOG("Toolbox module: installing\n");
m_inks[WellKnownInks::Selection] = new SelectionInk(); m_inks[WellKnownInks::Selection] = new SelectionInk();
m_inks[WellKnownInks::Paint] = new PaintInk(PaintInk::Simple); m_inks[WellKnownInks::Paint] = new PaintInk(PaintInk::Simple);
m_inks[WellKnownInks::PaintFg] = new PaintInk(PaintInk::WithFg); m_inks[WellKnownInks::PaintFg] = new PaintInk(PaintInk::WithFg);
@ -122,8 +120,6 @@ ToolBox::ToolBox()
m_intertwiners[WellKnownIntertwiners::AsPixelPerfect] = new IntertwineAsPixelPerfect(); m_intertwiners[WellKnownIntertwiners::AsPixelPerfect] = new IntertwineAsPixelPerfect();
loadTools(); loadTools();
LOG("Toolbox module: installed\n");
} }
struct deleter { struct deleter {
@ -136,16 +132,12 @@ struct deleter {
ToolBox::~ToolBox() ToolBox::~ToolBox()
{ {
LOG("Toolbox module: uninstalling\n");
std::for_each(m_tools.begin(), m_tools.end(), deleter()); std::for_each(m_tools.begin(), m_tools.end(), deleter());
std::for_each(m_groups.begin(), m_groups.end(), deleter()); std::for_each(m_groups.begin(), m_groups.end(), deleter());
std::for_each(m_intertwiners.begin(), m_intertwiners.end(), deleter()); std::for_each(m_intertwiners.begin(), m_intertwiners.end(), deleter());
std::for_each(m_pointshapers.begin(), m_pointshapers.end(), deleter()); std::for_each(m_pointshapers.begin(), m_pointshapers.end(), deleter());
std::for_each(m_controllers.begin(), m_controllers.end(), deleter()); std::for_each(m_controllers.begin(), m_controllers.end(), deleter());
std::for_each(m_inks.begin(), m_inks.end(), deleter()); std::for_each(m_inks.begin(), m_inks.end(), deleter());
LOG("Toolbox module: uninstalled\n");
} }
Tool* ToolBox::getToolById(const std::string& id) Tool* ToolBox::getToolById(const std::string& id)
@ -155,9 +147,7 @@ Tool* ToolBox::getToolById(const std::string& id)
if (tool->getId() == id) if (tool->getId() == id)
return tool; return tool;
} }
// LOG("Error get_tool_by_name() with '%s'\n", name.c_str()); return nullptr;
// ASSERT(false);
return NULL;
} }
Ink* ToolBox::getInkById(const std::string& id) Ink* ToolBox::getInkById(const std::string& id)
@ -177,7 +167,7 @@ PointShape* ToolBox::getPointShapeById(const std::string& id)
void ToolBox::loadTools() void ToolBox::loadTools()
{ {
LOG("Loading Aseprite tools\n"); LOG("TOOL: Loading tools...\n");
XmlDocumentRef doc(GuiXml::instance()->doc()); XmlDocumentRef doc(GuiXml::instance()->doc());
TiXmlHandle handle(doc.get()); TiXmlHandle handle(doc.get());
@ -188,11 +178,11 @@ void ToolBox::loadTools()
const char* group_id = xmlGroup->Attribute("id"); const char* group_id = xmlGroup->Attribute("id");
const char* group_text = xmlGroup->Attribute("text"); const char* group_text = xmlGroup->Attribute("text");
LOG(" - New group '%s'\n", group_id);
if (!group_id || !group_text) if (!group_id || !group_text)
throw base::Exception("The configuration file has a <group> without 'id' or 'text' attributes."); throw base::Exception("The configuration file has a <group> without 'id' or 'text' attributes.");
LOG(VERBOSE) << "TOOL: Group " << group_id << "\n";
ToolGroup* tool_group = new ToolGroup(group_id, group_text); ToolGroup* tool_group = new ToolGroup(group_id, group_text);
// For each tool // For each tool
@ -207,7 +197,7 @@ void ToolBox::loadTools()
Tool* tool = new Tool(tool_group, tool_id, tool_text, tool_tips, Tool* tool = new Tool(tool_group, tool_id, tool_text, tool_tips,
default_brush_size ? strtol(default_brush_size, NULL, 10): 1); default_brush_size ? strtol(default_brush_size, NULL, 10): 1);
LOG(" - New tool '%s' in group '%s' found\n", tool_id, group_id); LOG(VERBOSE) << "TOOL: Tool " << tool_id << " in group " << group_id << " found\n";
loadToolProperties(xmlTool, tool, 0, "left"); loadToolProperties(xmlTool, tool, 0, "left");
loadToolProperties(xmlTool, tool, 1, "right"); loadToolProperties(xmlTool, tool, 1, "right");
@ -220,6 +210,8 @@ void ToolBox::loadTools()
m_groups.push_back(tool_group); m_groups.push_back(tool_group);
xmlGroup = xmlGroup->NextSiblingElement(); xmlGroup = xmlGroup->NextSiblingElement();
} }
LOG("TOOL: Done. %d tools, %d groups.\n", m_tools.size(), m_groups.size());
} }
void ToolBox::loadToolProperties(TiXmlElement* xmlTool, Tool* tool, int button, const std::string& suffix) void ToolBox::loadToolProperties(TiXmlElement* xmlTool, Tool* tool, int button, const std::string& suffix)

View File

@ -144,7 +144,7 @@ void MovingPixelsState::onEnterState(Editor* editor)
EditorState::LeaveAction MovingPixelsState::onLeaveState(Editor* editor, EditorState* newState) EditorState::LeaveAction MovingPixelsState::onLeaveState(Editor* editor, EditorState* newState)
{ {
LOG("MovingPixels: leave state\n"); TRACE("MOVPIXS: onLeaveState\n");
ASSERT(m_pixelsMovement); ASSERT(m_pixelsMovement);
ASSERT(editor == m_editor); ASSERT(editor == m_editor);
@ -481,7 +481,7 @@ void MovingPixelsState::onBeforeCommandExecution(CommandExecutionEvent& ev)
{ {
Command* command = ev.command(); Command* command = ev.command();
LOG("MovingPixelsState::onBeforeCommandExecution %s\n", command->id().c_str()); TRACE("MOVPIXS: onBeforeCommandExecution %s\n", command->id().c_str());
// If the command is for other editor, we don't drop pixels. // If the command is for other editor, we don't drop pixels.
if (!isActiveEditor()) if (!isActiveEditor())
@ -637,7 +637,7 @@ void MovingPixelsState::setTransparentColor(bool opaque, const app::Color& color
void MovingPixelsState::dropPixels() void MovingPixelsState::dropPixels()
{ {
LOG("MovingPixels: drop pixels\n"); TRACE("MOVPIXS: dropPixels\n");
// Just change to default state (StandbyState generally). We'll // Just change to default state (StandbyState generally). We'll
// receive an onLeaveState() event after this call. // receive an onLeaveState() event after this call.

View File

@ -437,7 +437,7 @@ std::string FileSelector::show(
if (!start_folder) if (!start_folder)
start_folder = fs->getFileItemFromPath(start_folder_path); start_folder = fs->getFileItemFromPath(start_folder_path);
LOG("start_folder_path = %s (%p)\n", start_folder_path.c_str(), start_folder); TRACE("FILESEL: Start folder '%s' (%p)\n", start_folder_path.c_str(), start_folder);
setMinSize(gfx::Size(ui::display_w()*9/10, ui::display_h()*9/10)); setMinSize(gfx::Size(ui::display_w()*9/10, ui::display_h()*9/10));
remapWindow(); remapWindow();

View File

@ -383,7 +383,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
if (tool) { if (tool) {
Key* key = this->tool(tool); Key* key = this->tool(tool);
if (key && tool_key) { if (key && tool_key) {
LOG(" - Shortcut for tool `%s': <%s>\n", tool_id, tool_key); LOG(VERBOSE) << "KEYS: Shortcut for tool " << tool_id << ": " << tool_key << "\n";
Accelerator accel(tool_key); Accelerator accel(tool_key);
if (!removed) if (!removed)
@ -411,7 +411,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
if (tool) { if (tool) {
Key* key = this->quicktool(tool); Key* key = this->quicktool(tool);
if (key && tool_key) { if (key && tool_key) {
LOG(" - Shortcut for quicktool `%s': <%s>\n", tool_id, tool_key); LOG(VERBOSE) << "KEYS: Shortcut for quicktool " << tool_id << ": " << tool_key << "\n";
Accelerator accel(tool_key); Accelerator accel(tool_key);
if (!removed) if (!removed)
@ -439,7 +439,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
if (action != KeyAction::None) { if (action != KeyAction::None) {
Key* key = this->action(action); Key* key = this->action(action);
if (key && tool_key) { if (key && tool_key) {
LOG(" - Shortcut for action '%s': <%s>\n", tool_action, tool_key); LOG(VERBOSE) << "KEYS: Shortcut for action " << tool_action << ": " << tool_key << "\n";
Accelerator accel(tool_key); Accelerator accel(tool_key);
if (!removed) if (!removed)

View File

@ -180,8 +180,6 @@ void ResourcesListBox::onTick()
if (!m_resourcesLoader->next(resource)) { if (!m_resourcesLoader->next(resource)) {
if (m_resourcesLoader->isDone()) { if (m_resourcesLoader->isDone()) {
stop(); stop();
LOG("Done\n");
} }
return; return;
} }

View File

@ -8,6 +8,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include "app/console.h"
#include "app/modules/gui.h" #include "app/modules/gui.h"
#include "app/pref/preferences.h" #include "app/pref/preferences.h"
#include "app/resource_finder.h" #include "app/resource_finder.h"
@ -191,12 +192,26 @@ void SkinTheme::onRegenerate()
loadAll(pref.theme.selected.defaultValue()); loadAll(pref.theme.selected.defaultValue());
// Then we load the selected theme to redefine default theme parts. // Then we load the selected theme to redefine default theme parts.
if (pref.theme.selected.defaultValue() != pref.theme.selected()) if (pref.theme.selected.defaultValue() != pref.theme.selected()) {
loadAll(pref.theme.selected()); try {
loadAll(pref.theme.selected());
}
catch (const std::exception& e) {
LOG("SKIN: Error loading user-theme: %s\n", e.what());
if (CurrentTheme::get())
Console::showException(e);
// We can continue, as we've already loaded the default theme
// anyway...
}
}
} }
void SkinTheme::loadAll(const std::string& skinId) void SkinTheme::loadAll(const std::string& skinId)
{ {
LOG("SKIN: Loading theme %s\n", skinId.c_str());
loadSheet(skinId); loadSheet(skinId);
loadFonts(skinId); loadFonts(skinId);
loadXml(skinId); loadXml(skinId);
@ -204,13 +219,6 @@ void SkinTheme::loadAll(const std::string& skinId)
void SkinTheme::loadSheet(const std::string& skinId) void SkinTheme::loadSheet(const std::string& skinId)
{ {
TRACE("SkinTheme::loadSheet(%s)\n", skinId.c_str());
if (m_sheet) {
m_sheet->dispose();
m_sheet = NULL;
}
// Load the skin sheet // Load the skin sheet
std::string sheet_filename("skins/" + skinId + "/sheet.png"); std::string sheet_filename("skins/" + skinId + "/sheet.png");
@ -220,6 +228,10 @@ void SkinTheme::loadSheet(const std::string& skinId)
throw base::Exception("File %s not found", sheet_filename.c_str()); throw base::Exception("File %s not found", sheet_filename.c_str());
try { try {
if (m_sheet) {
m_sheet->dispose();
m_sheet = nullptr;
}
m_sheet = she::instance()->loadRgbaSurface(rf.filename().c_str()); m_sheet = she::instance()->loadRgbaSurface(rf.filename().c_str());
} }
catch (...) { catch (...) {
@ -229,8 +241,6 @@ void SkinTheme::loadSheet(const std::string& skinId)
void SkinTheme::loadFonts(const std::string& skinId) void SkinTheme::loadFonts(const std::string& skinId)
{ {
TRACE("SkinTheme::loadFonts(%s)\n", skinId.c_str());
if (m_defaultFont) m_defaultFont->dispose(); if (m_defaultFont) m_defaultFont->dispose();
if (m_miniFont) m_miniFont->dispose(); if (m_miniFont) m_miniFont->dispose();
@ -242,8 +252,6 @@ void SkinTheme::loadFonts(const std::string& skinId)
void SkinTheme::loadXml(const std::string& skinId) void SkinTheme::loadXml(const std::string& skinId)
{ {
TRACE("SkinTheme::loadXml(%s)\n", skinId.c_str());
// Load the skin XML // Load the skin XML
std::string xml_filename = "skins/" + skinId + "/skin.xml"; std::string xml_filename = "skins/" + skinId + "/skin.xml";
ResourceFinder rf; ResourceFinder rf;
@ -264,7 +272,7 @@ void SkinTheme::loadXml(const std::string& skinId)
std::string id = xmlDim->Attribute("id"); std::string id = xmlDim->Attribute("id");
uint32_t value = strtol(xmlDim->Attribute("value"), NULL, 10); uint32_t value = strtol(xmlDim->Attribute("value"), NULL, 10);
LOG("Loading dimension '%s'...\n", id.c_str()); LOG(VERBOSE) << "SKIN: Loading dimension '" << id << "\n";
m_dimensions_by_id[id] = value; m_dimensions_by_id[id] = value;
xmlDim = xmlDim->NextSiblingElement(); xmlDim = xmlDim->NextSiblingElement();
@ -285,7 +293,7 @@ void SkinTheme::loadXml(const std::string& skinId)
(value & 0xff00) >> 8, (value & 0xff00) >> 8,
(value & 0xff)); (value & 0xff));
LOG("Loading color '%s'...\n", id.c_str()); LOG(VERBOSE) << "SKIN: Loading color " << id << "\n";
m_colors_by_id[id] = color; m_colors_by_id[id] = color;
xmlColor = xmlColor->NextSiblingElement(); xmlColor = xmlColor->NextSiblingElement();
@ -308,7 +316,7 @@ void SkinTheme::loadXml(const std::string& skinId)
int focusy = strtol(xmlCursor->Attribute("focusy"), NULL, 10); int focusy = strtol(xmlCursor->Attribute("focusy"), NULL, 10);
int c; int c;
LOG("Loading cursor '%s'...\n", id.c_str()); LOG(VERBOSE) << "SKIN: Loading cursor " << id << "\n";
for (c=0; c<kCursorTypes; ++c) { for (c=0; c<kCursorTypes; ++c) {
if (id != cursor_names[c]) if (id != cursor_names[c])
@ -341,17 +349,17 @@ void SkinTheme::loadXml(const std::string& skinId)
.FirstChild("tool").ToElement(); .FirstChild("tool").ToElement();
while (xmlIcon) { while (xmlIcon) {
// Get the tool-icon rectangle // Get the tool-icon rectangle
const char* tool_id = xmlIcon->Attribute("id"); const char* id = xmlIcon->Attribute("id");
int x = strtol(xmlIcon->Attribute("x"), NULL, 10); int x = strtol(xmlIcon->Attribute("x"), NULL, 10);
int y = strtol(xmlIcon->Attribute("y"), NULL, 10); int y = strtol(xmlIcon->Attribute("y"), NULL, 10);
int w = strtol(xmlIcon->Attribute("w"), NULL, 10); int w = strtol(xmlIcon->Attribute("w"), NULL, 10);
int h = strtol(xmlIcon->Attribute("h"), NULL, 10); int h = strtol(xmlIcon->Attribute("h"), NULL, 10);
LOG("Loading tool icon '%s'...\n", tool_id); LOG(VERBOSE) << "SKIN: Loading tool icon " << id << "\n";
// Crop the tool-icon from the sheet // Crop the tool-icon from the sheet
m_toolicon[tool_id] = sliceSheet( m_toolicon[id] = sliceSheet(
m_toolicon[tool_id], gfx::Rect(x, y, w, h)); m_toolicon[id], gfx::Rect(x, y, w, h));
xmlIcon = xmlIcon->NextSiblingElement(); xmlIcon = xmlIcon->NextSiblingElement();
} }
@ -371,7 +379,7 @@ void SkinTheme::loadXml(const std::string& skinId)
int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0; int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0;
int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0; int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0;
LOG("Loading part '%s'...\n", part_id); LOG(VERBOSE) << "SKIN: Loading part " << part_id << "\n";
SkinPartPtr part = m_parts_by_id[part_id]; SkinPartPtr part = m_parts_by_id[part_id];
if (!part) if (!part)
@ -424,7 +432,8 @@ void SkinTheme::loadXml(const std::string& skinId)
while (xmlRule) { while (xmlRule) {
const std::string ruleName = xmlRule->Value(); const std::string ruleName = xmlRule->Value();
LOG("- Rule '%s' for '%s'\n", ruleName.c_str(), style_id); LOG(VERBOSE) << "SKIN: Rule " << ruleName
<< " for " << style_id << "\n";
// TODO This code design to read styles could be improved. // TODO This code design to read styles could be improved.

View File

@ -4,6 +4,7 @@
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
#include "base/config.h"
#include "base/string.h" #include "base/string.h"
#ifdef HAVE_DLFCN_H #ifdef HAVE_DLFCN_H

View File

@ -8,7 +8,9 @@
#include "config.h" #include "config.h"
#endif #endif
#include "base/debug.h"
#include "base/string.h" #include "base/string.h"
#include <cassert> #include <cassert>
#include <cctype> #include <cctype>
#include <vector> #include <vector>
@ -158,7 +160,7 @@ std::wstring from_utf8(const std::string& src)
utf8_const_iterator end(src.end()); utf8_const_iterator end(src.end());
while (it != end) { while (it != end) {
assert(buf_it != buf_end); ASSERT(buf_it != buf_end);
*buf_it = *it; *buf_it = *it;
++buf_it; ++buf_it;
++it; ++it;

View File

@ -1,5 +1,5 @@
// Aseprite Base Library // Aseprite Base Library
// Copyright (c) 2001-2013, 2015 David Capello // Copyright (c) 2001-2016 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -141,6 +141,30 @@ namespace base {
} }
}; };
class utf8 {
public:
utf8(std::string& s) : m_begin(utf8_iterator(s.begin())),
m_end(utf8_iterator(s.end())) {
}
const utf8_iterator& begin() const { return m_begin; }
const utf8_iterator& end() const { return m_end; }
private:
utf8_iterator m_begin;
utf8_iterator m_end;
};
class utf8_const {
public:
utf8_const(const std::string& s) : m_begin(utf8_const_iterator(s.begin())),
m_end(utf8_const_iterator(s.end())) {
}
const utf8_const_iterator& begin() const { return m_begin; }
const utf8_const_iterator& end() const { return m_end; }
private:
utf8_const_iterator m_begin;
utf8_const_iterator m_end;
};
} }
#endif #endif

View File

@ -29,6 +29,30 @@ TEST(String, Utf8Conversion)
ASSERT_EQ(a, c); ASSERT_EQ(a, c);
} }
TEST(String, Utf8Wrapper)
{
std::string a, b = "abc";
for (int ch : utf8(b))
a.push_back(ch);
EXPECT_EQ("abc", a);
std::string c, d = "def";
for (int ch : utf8_const(d)) // TODO we should be able to specify a string-literal here
c.push_back(ch);
EXPECT_EQ("def", c);
int i = 0;
d = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E";
for (int ch : utf8_const(d)) { // 日本語
switch (i++) {
case 0: EXPECT_EQ(ch, 0x65E5); break;
case 1: EXPECT_EQ(ch, 0x672C); break;
case 2: EXPECT_EQ(ch, 0x8A9E); break;
default: EXPECT_FALSE(true); break;
}
}
}
TEST(String, Utf8Iterator) TEST(String, Utf8Iterator)
{ {
std::string a = "Hello"; std::string a = "Hello";

View File

@ -14,7 +14,8 @@
#include "base/log.h" #include "base/log.h"
#include "base/string.h" #include "base/string.h"
#include <stdlib.h> #include <cstdlib>
#include <iostream>
#include "SimpleIni.h" #include "SimpleIni.h"
namespace cfg { namespace cfg {
@ -67,8 +68,9 @@ public:
base::FileHandle file(base::open_file(m_filename, "rb")); base::FileHandle file(base::open_file(m_filename, "rb"));
if (file) { if (file) {
SI_Error err = m_ini.LoadFile(file.get()); SI_Error err = m_ini.LoadFile(file.get());
if (err != SI_OK) if (err != SI_OK) {
LOG("Error '%d' loading configuration from '%s'.", err, m_filename.c_str()); LOG(ERROR) << "CFG: Error " << err << " loading configuration from " << m_filename << "\n";
}
} }
} }
@ -76,8 +78,9 @@ public:
base::FileHandle file(base::open_file(m_filename, "wb")); base::FileHandle file(base::open_file(m_filename, "wb"));
if (file) { if (file) {
SI_Error err = m_ini.SaveFile(file.get()); SI_Error err = m_ini.SaveFile(file.get());
if (err != SI_OK) if (err != SI_OK) {
LOG("Error '%d' saving configuration into '%s'.", err, m_filename.c_str()); LOG(ERROR) << "CFG: Error " << err << " saving configuration into " << m_filename << "\n";
}
} }
} }

View File

@ -17,6 +17,8 @@
#include "doc/rgbmap.h" #include "doc/rgbmap.h"
#include "gfx/point.h" #include "gfx/point.h"
#include <cmath>
namespace doc { namespace doc {
namespace algorithm { namespace algorithm {
@ -31,9 +33,9 @@ void resize_image_nearest(const Image* src, Image* dst)
auto dstIt = dstBits.begin(); auto dstIt = dstBits.begin();
for (int y=0; y<dst->height(); ++y) { for (int y=0; y<dst->height(); ++y) {
py = floor(y * y_ratio); py = std::floor(y * y_ratio);
for (int x=0; x<dst->width(); ++x, ++dstIt) { for (int x=0; x<dst->width(); ++x, ++dstIt) {
px = floor(x * x_ratio); px = std::floor(x * x_ratio);
*dstIt = get_pixel_fast<ImageTraits>(src, px, py); *dstIt = get_pixel_fast<ImageTraits>(src, px, py);
} }
} }
@ -69,8 +71,8 @@ void resize_image(const Image* src, Image* dst, ResizeMethod method, const Palet
dv = (src->height()-1) * 1.0 / (dst->height()-1); dv = (src->height()-1) * 1.0 / (dst->height()-1);
for (y=0; y<dst->height(); ++y) { for (y=0; y<dst->height(); ++y) {
for (x=0; x<dst->width(); ++x) { for (x=0; x<dst->width(); ++x) {
u_floor = (int)floor(u); u_floor = (int)std::floor(u);
v_floor = (int)floor(v); v_floor = (int)std::floor(v);
if (u_floor > src->width()-1) { if (u_floor > src->width()-1) {
u_floor = src->width()-1; u_floor = src->width()-1;

View File

@ -1,5 +1,5 @@
// Aseprite Document Library // Aseprite Document Library
// Copyright (c) 2001-2014 David Capello // Copyright (c) 2001-2016 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -13,7 +13,7 @@ namespace doc {
class CreateDocumentArgs { class CreateDocumentArgs {
public: public:
CreateDocumentArgs() : m_doc(NULL) { } CreateDocumentArgs() : m_doc(nullptr) { }
Document* document() { return m_doc; } Document* document() { return m_doc; }
void setDocument(Document* doc) { m_doc = doc; } void setDocument(Document* doc) { m_doc = doc; }
private: private:

View File

@ -9,6 +9,7 @@
#endif #endif
#include "base/fstream_path.h" #include "base/fstream_path.h"
#include "base/log.h"
#include "base/split_string.h" #include "base/split_string.h"
#include "base/trim_string.h" #include "base/trim_string.h"
#include "base/unique_ptr.h" #include "base/unique_ptr.h"
@ -72,7 +73,7 @@ Palette* load_gpl_file(const char *filename)
base::trim_string(comment, comment); base::trim_string(comment, comment);
if (!comment.empty()) { if (!comment.empty()) {
LOG("%s comment: %s\n", filename, comment.c_str()); LOG(VERBOSE) << "PAL: " << filename << " comment: " << comment << "\n";
pal->setComment(comment); pal->setComment(comment);
} }

View File

@ -492,7 +492,6 @@ void Sprite::pickCels(int x, int y, frame_t frame, int opacityThreshold, CelList
cels.push_back(cel); cels.push_back(cel);
} }
fflush(stdout);
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

9
src/docio/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
# Aseprite Document IO Library
# Copyright (c) 2016 David Capello
add_library(docio-lib
detect_format.cpp)
target_link_libraries(docio-lib
flic-lib
base-lib)

View File

@ -1,4 +1,4 @@
Copyright (c) 2014 David Capello Copyright (c) 2016 David Capello
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

4
src/docio/README.md Normal file
View File

@ -0,0 +1,4 @@
# Aseprite Document IO Library
*Copyright (C) 2016 David Capello*
> Distributed under [MIT license](LICENSE.txt)

140
src/docio/detect_format.cpp Normal file
View File

@ -0,0 +1,140 @@
// Aseprite Document IO Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#include "docio/detect_format.h"
#include "base/file_handle.h"
#include "base/path.h"
#include "base/string.h"
#include "flic/flic_details.h"
#include <cstring>
#define ASE_MAGIC_NUMBER 0xA5E0
#define BMP_MAGIC_NUMBER 0x4D42 // "BM"
#define JPG_MAGIC_NUMBER 0xD8FF
#define GIF_87_STAMP "GIF87a"
#define GIF_89_STAMP "GIF89a"
#define PNG_MAGIC_DWORD1 0x474E5089
#define PNG_MAGIC_DWORD2 0x0A1A0A0D
namespace docio {
FileFormat detect_format(const std::string& filename)
{
FileFormat ff = detect_format_by_file_content(filename);
if (ff == FileFormat::UNKNOWN)
ff = detect_format_by_file_extension(filename);
return ff;
}
FileFormat detect_format_by_file_content(const std::string& filename)
{
#define IS_MAGIC_WORD(offset, word) \
((buf[offset+0] == (word & 0xff)) && \
(buf[offset+1] == ((word & 0xff00) >> 8)))
#define IS_MAGIC_DWORD(offset, dword) \
((buf[offset+0] == (dword & 0xff)) && \
(buf[offset+1] == ((dword & 0xff00) >> 8)) && \
(buf[offset+2] == ((dword & 0xff0000) >> 16)) && \
(buf[offset+3] == ((dword & 0xff000000) >> 24)))
base::FileHandle handle(base::open_file(filename.c_str(), "rb"));
if (!handle)
return FileFormat::ERROR;
FILE* f = handle.get();
unsigned char buf[8];
int count = fread(buf, 1, 8, f);
if (count >= 2) {
if (IS_MAGIC_WORD(0, BMP_MAGIC_NUMBER))
return FileFormat::BMP_IMAGE;
if (IS_MAGIC_WORD(0, JPG_MAGIC_NUMBER))
return FileFormat::JPEG_IMAGE;
if (count >= 6) {
if (std::strncmp((const char*)buf, GIF_87_STAMP, 6) == 0 ||
std::strncmp((const char*)buf, GIF_89_STAMP, 6) == 0)
return FileFormat::GIF_ANIMATION;
if (IS_MAGIC_WORD(4, ASE_MAGIC_NUMBER))
return FileFormat::ASE_ANIMATION;
if (IS_MAGIC_WORD(4, FLI_MAGIC_NUMBER) ||
IS_MAGIC_WORD(4, FLC_MAGIC_NUMBER))
return FileFormat::FLIC_ANIMATION;
if (count >= 8) {
if (IS_MAGIC_DWORD(0, PNG_MAGIC_DWORD1) &&
IS_MAGIC_DWORD(4, PNG_MAGIC_DWORD2))
return FileFormat::PNG_IMAGE;
}
}
}
return FileFormat::UNKNOWN;
}
FileFormat detect_format_by_file_extension(const std::string& filename)
{
// By extension
const std::string ext = base::string_to_lower(base::get_file_extension(filename));
if (ext == "ase" ||
ext == "aseprite")
return FileFormat::ASE_ANIMATION;
if (ext == "bmp")
return FileFormat::BMP_IMAGE;
if (ext == "col")
return FileFormat::COL_PALETTE;
if (ext == "flc" ||
ext == "fli")
return FileFormat::FLIC_ANIMATION;
if (ext == "gif")
return FileFormat::GIF_ANIMATION;
if (ext == "gpl")
return FileFormat::GPL_PALETTE;
if (ext == "hex")
return FileFormat::HEX_PALETTE;
if (ext == "ico")
return FileFormat::ICO_IMAGES;
if (ext == "jpg" ||
ext == "jpeg")
return FileFormat::JPEG_IMAGE;
if (ext == "pal")
return FileFormat::PAL_PALETTE;
if (ext == "pcx")
return FileFormat::PCX_IMAGE;
if (ext == "anim")
return FileFormat::PIXLY_ANIMATION;
if (ext == "png")
return FileFormat::PNG_IMAGE;
if (ext == "tga")
return FileFormat::TARGA_IMAGE;
if (ext == "webp")
return FileFormat::WEBP_ANIMATION;
return FileFormat::UNKNOWN;
}
} // namespace docio

23
src/docio/detect_format.h Normal file
View File

@ -0,0 +1,23 @@
// Aseprite Document IO Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOCIO_DETECT_FORMAT_H_INCLUDED
#define DOCIO_DETECT_FORMAT_H_INCLUDED
#pragma once
#include "docio/file_format.h"
#include <string>
namespace docio {
FileFormat detect_format(const std::string& filename);
FileFormat detect_format_by_file_content(const std::string& filename);
FileFormat detect_format_by_file_extension(const std::string& filename);
} // namespace docio
#endif

37
src/docio/file_format.h Normal file
View File

@ -0,0 +1,37 @@
// Aseprite Document IO Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOCIO_FILE_FORMAT_H_INCLUDED
#define DOCIO_FILE_FORMAT_H_INCLUDED
#pragma once
namespace docio {
enum class FileFormat {
ERROR = -1,
UNKNOWN = 0,
ASE_ANIMATION, // Aseprite File Format
ASE_PALETTE, // Adobe Swatch Exchange
BMP_IMAGE,
COL_PALETTE,
FLIC_ANIMATION,
GIF_ANIMATION,
GPL_PALETTE,
HEX_PALETTE,
ICO_IMAGES,
JPEG_IMAGE,
PAL_PALETTE,
PCX_IMAGE,
PIXLY_ANIMATION,
PNG_IMAGE,
TARGA_IMAGE,
WEBP_ANIMATION,
};
} // namespace docio
#endif

View File

@ -8,6 +8,7 @@
#define FT_FACE_H_INCLUDED #define FT_FACE_H_INCLUDED
#pragma once #pragma once
#include "base/debug.h"
#include "base/disable_copying.h" #include "base/disable_copying.h"
#include "base/string.h" #include "base/string.h"
#include "ft/freetype_headers.h" #include "ft/freetype_headers.h"

View File

@ -1,4 +0,0 @@
# Aseprite Image File Formats Library
*Copyright (C) 2014 David Capello*
> Distributed under [MIT license](LICENSE.txt)

View File

@ -32,7 +32,7 @@ public:
bool createGLContext() override { bool createGLContext() override {
m_display = getD3DEGLDisplay((HDC)GetDC((HWND)m_nativeDisplay)); m_display = getD3DEGLDisplay((HDC)GetDC((HWND)m_nativeDisplay));
if (m_display == EGL_NO_DISPLAY) { if (m_display == EGL_NO_DISPLAY) {
LOG("Cannot create EGL display"); LOG("OS: Cannot create EGL display");
return false; return false;
} }

View File

@ -12,6 +12,7 @@
#include "she/osx/app.h" #include "she/osx/app.h"
#include "base/debug.h"
#include "base/thread.h" #include "base/thread.h"
#include "she/osx/app_delegate.h" #include "she/osx/app_delegate.h"

View File

@ -10,6 +10,7 @@
#include "she/osx/window.h" #include "she/osx/window.h"
#include "base/debug.h"
#include "she/event.h" #include "she/event.h"
#include "she/osx/event_queue.h" #include "she/osx/event_queue.h"
#include "she/osx/view.h" #include "she/osx/view.h"

View File

@ -10,6 +10,7 @@
#include "she/skia/skia_window_osx.h" #include "she/skia/skia_window_osx.h"
#include "base/log.h"
#include "base/unique_ptr.h" #include "base/unique_ptr.h"
#include "gfx/size.h" #include "gfx/size.h"
#include "she/event.h" #include "she/event.h"
@ -30,6 +31,8 @@
#endif #endif
#include <iostream>
namespace she { namespace she {
class SkiaWindow::Impl : public OSXWindowImpl { class SkiaWindow::Impl : public OSXWindowImpl {
@ -196,7 +199,7 @@ private:
m_glInterfaces.reset(GrGLCreateNativeInterface()); m_glInterfaces.reset(GrGLCreateNativeInterface());
if (!m_glInterfaces || !m_glInterfaces->validate()) { if (!m_glInterfaces || !m_glInterfaces->validate()) {
LOG("Cannot create GL interfaces\n"); LOG(ERROR) << "OS: Cannot create GL interfaces\n";
detachGL(); detachGL();
return false; return false;
} }
@ -209,10 +212,10 @@ private:
initWithCGLContextObj:static_cast<GLContextCGL*>(m_glCtx.get())->cglContext()]; initWithCGLContextObj:static_cast<GLContextCGL*>(m_glCtx.get())->cglContext()];
[m_nsGL setView:m_window.contentView]; [m_nsGL setView:m_window.contentView];
LOG("Using CGL backend\n"); LOG("OS: Using CGL backend\n");
} }
catch (const std::exception& ex) { catch (const std::exception& ex) {
LOG("Cannot create GL context: %s\n", ex.what()); LOG(ERROR) << "OS: Cannot create GL context: " << ex.what() << "\n";
detachGL(); detachGL();
return false; return false;
} }

View File

@ -33,6 +33,7 @@
#endif #endif
#include <iostream>
namespace she { namespace she {
@ -214,10 +215,10 @@ bool SkiaWindow::attachANGLE()
GrContext::Create(kOpenGL_GrBackend, GrContext::Create(kOpenGL_GrBackend,
(GrBackendContext)m_glInterfaces.get())); (GrBackendContext)m_glInterfaces.get()));
LOG("Using EGL backend\n"); LOG("OS: Using EGL backend\n");
} }
catch (const std::exception& ex) { catch (const std::exception& ex) {
LOG("Error initializing EGL backend: %s\n", ex.what()); LOG(ERROR) << "OS: Error initializing EGL backend: " << ex.what() << "\n";
detachGL(); detachGL();
} }
} }
@ -250,10 +251,10 @@ bool SkiaWindow::attachGL()
GrContext::Create(kOpenGL_GrBackend, GrContext::Create(kOpenGL_GrBackend,
(GrBackendContext)m_glInterfaces.get())); (GrBackendContext)m_glInterfaces.get()));
LOG("Using WGL backend\n"); LOG("OS: Using WGL backend\n");
} }
catch (const std::exception& ex) { catch (const std::exception& ex) {
LOG("Error initializing WGL backend: %s\n", ex.what()); LOG(ERROR) << "OS: Error initializing WGL backend: " << ex.what() << "\n";
detachGL(); detachGL();
} }
} }

View File

@ -16,6 +16,8 @@
#include "base/path.h" #include "base/path.h"
#include "base/string.h" #include "base/string.h"
#include <iostream>
typedef UINT (API* WTInfoW_Func)(UINT, UINT, LPVOID); typedef UINT (API* WTInfoW_Func)(UINT, UINT, LPVOID);
typedef HCTX (API* WTOpenW_Func)(HWND, LPLOGCONTEXTW, BOOL); typedef HCTX (API* WTOpenW_Func)(HWND, LPLOGCONTEXTW, BOOL);
typedef BOOL (API* WTClose_Func)(HCTX); typedef BOOL (API* WTClose_Func)(HCTX);
@ -57,11 +59,10 @@ HCTX PenAPI::open(HWND hwnd)
ASSERT(logctx.lcOptions & CXO_SYSTEM); ASSERT(logctx.lcOptions & CXO_SYSTEM);
if (infoRes != sizeof(LOGCONTEXTW)) { if (infoRes != sizeof(LOGCONTEXTW)) {
LOG("Not supported WTInfo:\n" LOG(ERROR)
" Expected context size: %d\n" << "PEN: Not supported WTInfo:\n"
" Actual context size: %d (options %d)\n", << " Expected context size: " << sizeof(LOGCONTEXTW) << "\n"
sizeof(LOGCONTEXTW), << " Actual context size: " << infoRes << " (options " << logctx.lcOptions << ")\n";
infoRes, logctx.lcOptions);
return nullptr; return nullptr;
} }
@ -75,11 +76,11 @@ HCTX PenAPI::open(HWND hwnd)
HCTX ctx = WTOpen(hwnd, &logctx, TRUE); HCTX ctx = WTOpen(hwnd, &logctx, TRUE);
if (!ctx) { if (!ctx) {
LOG("Error attaching pen to display\n"); LOG("PEN: Error attaching pen to display\n");
return nullptr; return nullptr;
} }
LOG("Pen attached to display\n"); LOG("PEN: Pen attached to display\n");
return ctx; return ctx;
} }
@ -87,7 +88,7 @@ void PenAPI::close(HCTX ctx)
{ {
if (ctx) { if (ctx) {
ASSERT(m_wintabLib); ASSERT(m_wintabLib);
LOG("Pen detached from window\n"); LOG("PEN: Pen detached from window\n");
WTClose(ctx); WTClose(ctx);
} }
} }
@ -103,7 +104,7 @@ bool PenAPI::loadWintab()
m_wintabLib = base::load_dll("wintab32.dll"); m_wintabLib = base::load_dll("wintab32.dll");
if (!m_wintabLib) { if (!m_wintabLib) {
LOG("wintab32.dll is not present\n"); LOG(ERROR) << "PEN: wintab32.dll is not present\n";
return false; return false;
} }
@ -112,11 +113,11 @@ bool PenAPI::loadWintab()
WTClose = base::get_dll_proc<WTClose_Func>(m_wintabLib, "WTClose"); WTClose = base::get_dll_proc<WTClose_Func>(m_wintabLib, "WTClose");
WTPacket = base::get_dll_proc<WTPacket_Func>(m_wintabLib, "WTPacket"); WTPacket = base::get_dll_proc<WTPacket_Func>(m_wintabLib, "WTPacket");
if (!WTInfo || !WTOpen || !WTClose || !WTPacket) { if (!WTInfo || !WTOpen || !WTClose || !WTPacket) {
LOG("wintab32.dll does not contain all required functions\n"); LOG(ERROR) << "PEN: wintab32.dll does not contain all required functions\n";
return false; return false;
} }
LOG("Pen initialized\n"); LOG("PEN: Pen initialized\n");
return true; return true;
} }

View File

@ -40,22 +40,22 @@ public:
base::join_path(base::get_file_path(base::get_app_path()), base::join_path(base::get_file_path(base::get_app_path()),
STEAM_API_DLL_FILENAME)); STEAM_API_DLL_FILENAME));
if (!m_steamLib) { if (!m_steamLib) {
LOG("Steam library not found...\n"); LOG("STEAM: Steam library not found...\n");
return; return;
} }
auto SteamAPI_Init = base::get_dll_proc<SteamAPI_Init_Func>(m_steamLib, "SteamAPI_Init"); auto SteamAPI_Init = base::get_dll_proc<SteamAPI_Init_Func>(m_steamLib, "SteamAPI_Init");
if (!SteamAPI_Init) { if (!SteamAPI_Init) {
LOG("SteamAPI_Init not found...\n"); LOG("STEAM: SteamAPI_Init not found...\n");
return; return;
} }
if (!SteamAPI_Init()) { if (!SteamAPI_Init()) {
LOG("Steam is not initialized...\n"); LOG("STEAM: Steam is not initialized...\n");
return; return;
} }
LOG("Steam initialized...\n"); LOG("STEAM: Steam initialized...\n");
m_initialized = true; m_initialized = true;
} }
@ -65,7 +65,7 @@ public:
auto SteamAPI_Shutdown = base::get_dll_proc<SteamAPI_Shutdown_Func>(m_steamLib, "SteamAPI_Shutdown"); auto SteamAPI_Shutdown = base::get_dll_proc<SteamAPI_Shutdown_Func>(m_steamLib, "SteamAPI_Shutdown");
if (SteamAPI_Shutdown) { if (SteamAPI_Shutdown) {
LOG("Steam shutdown...\n"); LOG("STEAM: Steam shutdown...\n");
SteamAPI_Shutdown(); SteamAPI_Shutdown();
} }

View File

@ -1,5 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -58,10 +58,15 @@ void Theme::regenerate()
void CurrentTheme::set(Theme* theme) void CurrentTheme::set(Theme* theme)
{ {
current_theme = theme; if (theme) {
// As the regeneration may fail, first we regenerate the theme and
// then we set is as "the current theme." E.g. In case that we'd
// like to show some kind of error message with the UI controls,
// we should be able to use the previous theme to do so (instead
// of this new unsuccessfully regenerated theme).
theme->regenerate();
if (current_theme) { current_theme = theme;
current_theme->regenerate();
Manager* manager = Manager::getDefault(); Manager* manager = Manager::getDefault();
if (manager && !manager->theme()) if (manager && !manager->theme())

View File

@ -160,10 +160,8 @@ void Widget::setTextQuiet(const std::string& text)
she::Font* Widget::font() const she::Font* Widget::font() const
{ {
if (!m_font) { if (!m_font && m_theme)
ASSERT(m_theme);
m_font = m_theme->getWidgetFont(this); m_font = m_theme->getWidgetFont(this);
}
return m_font; return m_font;
} }