Screenshot tool and saving/reading files works on android

This commit is contained in:
Yousef Khadadeh 2026-03-05 15:03:05 +03:00
parent 19983c7b1c
commit fe37c3348b
6 changed files with 30 additions and 58 deletions

View file

@ -103,7 +103,8 @@ void ScreenshotTool::gui_toolbox() {
auto world = w.lock();
if(world && world->drawProg.drawTool->get_type() == DrawingProgramToolType::SCREENSHOT) {
ScreenshotTool* screenshotTool = static_cast<ScreenshotTool*>(world->drawProg.drawTool.get());
screenshotTool->controls.screenshotSavePath = force_extension_on_path(p, setExtensionFilter.extensions);
screenshotTool->controls.screenshotSavePath = p;
screenshotTool->controls.screenshotSaveType = world->main.toolConfig.screenshot.selectedType;
screenshotTool->controls.setToTakeScreenshot = true;
}
}, "screenshot", true);
@ -281,24 +282,13 @@ bool ScreenshotTool::dragging_area_update(const Vector2f& camCursorPos) {
void ScreenshotTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) {
}
void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) {
void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath, ScreenshotType screenshotType) {
if(controls.imageSize.x() <= 0 || controls.imageSize.y() <= 0) {
std::cout << "[ScreenshotTool::take_screenshot] Image size is 0 or negative" << std::endl;
return;
}
std::string ext = filePath.extension().string();
size_t extType = SCREENSHOT_JPG;
if(ext == ".jpg" || ext == ".jpeg")
extType = SCREENSHOT_JPG;
else if(ext == ".png")
extType = SCREENSHOT_PNG;
else if(ext == ".webp")
extType = SCREENSHOT_WEBP;
else if(ext == ".svg")
extType = SCREENSHOT_SVG;
if(extType != SCREENSHOT_SVG) {
if(screenshotType != SCREENSHOT_SVG) {
size_t imageByteSize = (size_t)controls.imageSize.x() * (size_t)controls.imageSize.y() * 4;
size_t imageRowSize = 4 * controls.imageSize.x();
@ -315,12 +305,12 @@ void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) {
for(int i = 0; i < controls.imageSize.x(); i += drawP.world.main.window.size.x())
for(int j = 0; j < controls.imageSize.y(); j += drawP.world.main.window.size.y())
take_screenshot_area_hw(surface, screenshotCanvas, finalImgRawData.data(), controls.imageSize, Vector2i{i, j}, Vector2i{std::min(drawP.world.main.window.size.x(), controls.imageSize.x() - i), std::min(drawP.world.main.window.size.y(), controls.imageSize.y() - j)}, drawP.world.main.window.size, extType != 0 && controls.transparentBackground);
take_screenshot_area_hw(surface, screenshotCanvas, finalImgRawData.data(), controls.imageSize, Vector2i{i, j}, Vector2i{std::min(drawP.world.main.window.size.x(), controls.imageSize.x() - i), std::min(drawP.world.main.window.size.y(), controls.imageSize.y() - j)}, drawP.world.main.window.size, screenshotType != SCREENSHOT_JPG && controls.transparentBackground);
bool success = false;
SkDynamicMemoryWStream out;
switch(extType) {
switch(screenshotType) {
case SCREENSHOT_JPG:
success = SkJpegEncoder::Encode(&out, finalImgData, {});
break;
@ -341,10 +331,9 @@ void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) {
#ifndef __EMSCRIPTEN__
try {
std::ofstream fi(filePath, std::ios::out | std::ios::binary);
auto skData = out.detachAsData();
fi.write((const char*)skData->bytes(), skData->size());
fi.close();
if(!SDL_SaveFile(filePath.c_str(), skData->bytes(), skData->size()))
throw std::runtime_error("SDL_SaveFile failed with error: " + std::string(SDL_GetError()));
}
catch(const std::exception& e) {
Logger::get().log("WORLDFATAL", std::string("[ScreenshotTool::take_screenshot] Save screenshot error: ") + e.what());
@ -372,10 +361,9 @@ void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) {
#ifndef __EMSCRIPTEN__
try {
std::ofstream fi(filePath, std::ios::out | std::ios::binary);
auto skData = out.detachAsData();
fi.write((const char*)skData->bytes(), skData->size());
fi.close();
if(!SDL_SaveFile(filePath.c_str(), skData->bytes(), skData->size()))
throw std::runtime_error("SDL_SaveFile failed with error: " + std::string(SDL_GetError()));
}
catch(const std::exception& e) {
Logger::get().log("WORLDFATAL", std::string("[ScreenshotTool::take_screenshot] Save screenshot error: ") + e.what());
@ -467,7 +455,7 @@ void ScreenshotTool::switch_tool(DrawingProgramToolType newTool) {
void ScreenshotTool::tool_update() {
if(controls.setToTakeScreenshot) {
controls.setToTakeScreenshot = false;
take_screenshot(controls.screenshotSavePath);
take_screenshot(controls.screenshotSavePath, controls.screenshotSaveType);
}
if(controls.selectionMode == ScreenshotControls::SelectionMode::SELECTION_EXISTS)
selection_exists_update();

View file

@ -29,7 +29,7 @@ class ScreenshotTool : public DrawingProgramToolBase {
};
private:
void commit_rect();
void take_screenshot(const std::filesystem::path& filePath);
void take_screenshot(const std::filesystem::path& filePath, ScreenshotType screenshotType);
void take_screenshot_area_hw(const sk_sp<SkSurface>& surface, SkCanvas* canvas, void* fullImgRawData, const Vector2i& fullImageSize, const Vector2i& sectionImagePos, const Vector2i& sectionImageSize, const Vector2i& canvasSize, bool transparentBackground);
void take_screenshot_svg(SkCanvas* canvas, bool transparentBackground);
@ -47,7 +47,7 @@ class ScreenshotTool : public DrawingProgramToolBase {
DRAGGING_BORDER,
SELECTION_EXISTS,
DRAGGING_AREA
} selectionMode;
} selectionMode = SelectionMode::NO_SELECTION;
int dragType = 0;
Vector2i imageSize = {0, 0};
std::array<SCollision::Circle<float>, 8> circles;
@ -59,6 +59,7 @@ class ScreenshotTool : public DrawingProgramToolBase {
std::atomic<bool> setToTakeScreenshot = false;
std::filesystem::path screenshotSavePath;
ScreenshotType screenshotSaveType;
} controls;
bool dragging_border_update(const Vector2f& camCursorPos);
bool selection_exists_update();