From 5ef6730497c54b311b39cc3394e9f73149c6793a Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 29 Jul 2017 12:54:53 -0300 Subject: [PATCH] Added a variant of love.graphics.captureScreenshot which takes a single filename parameter. Resolves issue #1293. --HG-- branch : minor --- src/modules/filesystem/wrap_Filesystem.cpp | 6 +-- src/modules/graphics/wrap_Graphics.cpp | 46 ++++++++++++++++++++++ src/modules/image/ImageData.h | 2 +- src/modules/image/magpie/ImageData.cpp | 25 +++++++++++- src/modules/image/magpie/ImageData.h | 2 +- src/modules/image/wrap_ImageData.cpp | 11 +----- 6 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/modules/filesystem/wrap_Filesystem.cpp b/src/modules/filesystem/wrap_Filesystem.cpp index 319bc69e8..3d5a9542d 100644 --- a/src/modules/filesystem/wrap_Filesystem.cpp +++ b/src/modules/filesystem/wrap_Filesystem.cpp @@ -459,11 +459,9 @@ int w_getDirectoryItems(lua_State *L) int w_lines(lua_State *L) { - File *file; - if (lua_isstring(L, 1)) { - file = instance()->newFile(lua_tostring(L, 1)); + File *file = instance()->newFile(lua_tostring(L, 1)); bool success = false; luax_catchexcept(L, [&](){ success = file->open(File::MODE_READ); }); @@ -488,7 +486,7 @@ int w_load(lua_State *L) { std::string filename = std::string(luaL_checkstring(L, 1)); - Data *data = 0; + Data *data = nullptr; try { data = instance()->read(filename.c_str()); diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 0d8d183a2..a27ee25e1 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -439,8 +439,54 @@ static void screenshotCallback(love::image::ImageData *i, Reference *ref, void * delete ref; } +static int screenshotSaveToFile(lua_State *L) +{ + image::ImageData *id = image::luax_checkimagedata(L, 1); + + const char *filename = luaL_checkstring(L, lua_upvalueindex(1)); + const char *ext = luaL_checkstring(L, lua_upvalueindex(2)); + + image::ImageData::EncodedFormat format; + if (!image::ImageData::getConstant(ext, format)) + return 0; + + try + { + id->encode(format, filename, true); + } + catch (love::Exception &e) + { + printf("Screenshot encoding or saving failed: %s", e.what()); + // Do nothing... + } + + return 0; +} + int w_captureScreenshot(lua_State *L) { + if (lua_isstring(L, 1)) + { + std::string filename = luax_checkstring(L, 1); + std::string ext; + + size_t dotpos = filename.rfind('.'); + + if (dotpos != std::string::npos) + ext = filename.substr(dotpos + 1); + + std::transform(ext.begin(), ext.end(), ext.begin(), tolower); + + image::ImageData::EncodedFormat format; + if (!image::ImageData::getConstant(ext.c_str(), format)) + return luaL_error(L, "Invalid encoded image format: %s", ext.c_str()); + + lua_pushvalue(L, 1); + luax_pushstring(L, ext); + lua_pushcclosure(L, screenshotSaveToFile, 2); + lua_replace(L, 1); + } + luaL_checktype(L, 1, LUA_TFUNCTION); Graphics::ScreenshotInfo info; diff --git a/src/modules/image/ImageData.h b/src/modules/image/ImageData.h index 4d122fc92..c7f84bd01 100644 --- a/src/modules/image/ImageData.h +++ b/src/modules/image/ImageData.h @@ -111,7 +111,7 @@ public: * @param f The file to save the encoded image data to. * @param format The format of the encoded data. **/ - virtual love::filesystem::FileData *encode(EncodedFormat format, const char *filename) = 0; + virtual love::filesystem::FileData *encode(EncodedFormat format, const char *filename, bool writefile) = 0; love::thread::Mutex *getMutex() const; diff --git a/src/modules/image/magpie/ImageData.cpp b/src/modules/image/magpie/ImageData.cpp index 23f32d363..fc2de49b3 100644 --- a/src/modules/image/magpie/ImageData.cpp +++ b/src/modules/image/magpie/ImageData.cpp @@ -22,6 +22,8 @@ #include "ImageData.h" #include "Image.h" +#include "filesystem/Filesystem.h" + namespace love { namespace image @@ -154,7 +156,7 @@ void ImageData::decode(love::filesystem::FileData *data) decodeHandler = decoder; } -love::filesystem::FileData *ImageData::encode(EncodedFormat encodedFormat, const char *filename) +love::filesystem::FileData *ImageData::encode(EncodedFormat encodedFormat, const char *filename, bool writefile) { FormatHandler *encoder = nullptr; FormatHandler::EncodedImage encodedimage; @@ -208,6 +210,27 @@ love::filesystem::FileData *ImageData::encode(EncodedFormat encodedFormat, const memcpy(filedata->getData(), encodedimage.data, encodedimage.size); encoder->free(encodedimage.data); + if (writefile) + { + auto fs = Module::getInstance(Module::M_FILESYSTEM); + + if (fs == nullptr) + { + filedata->release(); + throw love::Exception("love.filesystem must be loaded in order to write an encoded ImageData to a file."); + } + + try + { + fs->write(filename, filedata->getData(), filedata->getSize()); + } + catch (love::Exception &) + { + filedata->release(); + throw; + } + } + return filedata; } diff --git a/src/modules/image/magpie/ImageData.h b/src/modules/image/magpie/ImageData.h index 97bbe59a9..91ec6a362 100644 --- a/src/modules/image/magpie/ImageData.h +++ b/src/modules/image/magpie/ImageData.h @@ -47,7 +47,7 @@ public: // Implements image::ImageData. virtual love::image::ImageData *clone() const; - virtual love::filesystem::FileData *encode(EncodedFormat encodedFormat, const char *filename); + virtual love::filesystem::FileData *encode(EncodedFormat encodedFormat, const char *filename, bool writefile); private: diff --git a/src/modules/image/wrap_ImageData.cpp b/src/modules/image/wrap_ImageData.cpp index 3f411e2fe..dd33d5faf 100644 --- a/src/modules/image/wrap_ImageData.cpp +++ b/src/modules/image/wrap_ImageData.cpp @@ -22,6 +22,7 @@ #include "common/wrap_Data.h" #include "filesystem/File.h" +#include "filesystem/Filesystem.h" // Shove the wrap_ImageData.lua code directly into a raw string literal. static const char imagedata_lua[] = @@ -276,19 +277,11 @@ int w_ImageData_encode(lua_State *L) } love::filesystem::FileData *filedata = nullptr; - luax_catchexcept(L, [&](){ filedata = t->encode(format, filename.c_str()); }); + luax_catchexcept(L, [&](){ filedata = t->encode(format, filename.c_str(), hasfilename); }); luax_pushtype(L, filedata); filedata->release(); - if (hasfilename) - { - luax_getfunction(L, "filesystem", "write"); - lua_pushvalue(L, 3); // filename - lua_pushvalue(L, -3); // FileData - lua_call(L, 2, 0); - } - return 1; }