diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index 8b70e33d69..e42526cb15 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -65,9 +65,7 @@ DrawWidget::DrawWidget(Framework & framework, bool apiOpenGLES3, std::unique_ptr if (screenshotParams != nullptr) { - QSize size(static_cast(screenshotParams->m_width), static_cast(screenshotParams->m_height)); - setMaximumSize(size); - setMinimumSize(size); + m_ratio = screenshotParams->m_dpiScale; m_screenshoter = std::make_unique(*screenshotParams, m_framework, this); } QTimer * countryStatusTimer = new QTimer(this); diff --git a/qt/main.cpp b/qt/main.cpp index 52fa57e08c..9982c949b9 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -31,9 +31,11 @@ DEFINE_string(log_abort_level, base::ToString(base::GetDefaultLogAbortLevel()), "Log messages severity that causes termination."); DEFINE_string(resources_path, "", "Path to resources directory"); DEFINE_string(kml_path, "", "Path to a directory with kml files to take screenshots."); +DEFINE_string(dst_path, "", "Path to a directory to save screenshots."); DEFINE_string(lang, "", "Device language."); DEFINE_int32(width, 0, "Screenshot width"); DEFINE_int32(height, 0, "Screenshot height"); +DEFINE_double(dpi_scale, 0.0, "Screenshot dpi scale"); namespace { @@ -158,20 +160,21 @@ int main(int argc, char * argv[]) #if defined(OMIM_OS_MAC) apiOpenGLES3 = a.arguments().contains("es3", Qt::CaseInsensitive); + if (!FLAGS_lang.empty()) + (void)::setenv("LANGUAGE", FLAGS_lang.c_str(), 1); + if (!FLAGS_kml_path.empty()) { screenshotParams = std::make_unique(); - screenshotParams->m_path = FLAGS_kml_path; + screenshotParams->m_kmlPath = FLAGS_kml_path; + if (!FLAGS_dst_path.empty()) + screenshotParams->m_dstPath = FLAGS_dst_path; if (FLAGS_width > 0) screenshotParams->m_width = FLAGS_width; if (FLAGS_height > 0) screenshotParams->m_height = FLAGS_height; - - if (!FLAGS_lang.empty()) - (void)::setenv("LANGUAGE", FLAGS_lang.c_str(), 1); - - //screenshotParams->m_width /= a.devicePixelRatio(); - //screenshotParams->m_height /= a.devicePixelRatio(); + if (FLAGS_dpi_scale >= df::VisualParams::kMdpiScale && FLAGS_dpi_scale <= df::VisualParams::kXxxhdpiScale) + screenshotParams->m_dpiScale = FLAGS_dpi_scale; } #endif qt::MainWindow::SetDefaultSurfaceFormat(apiOpenGLES3); diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp index f52d0ee2cf..d8c8f40a89 100644 --- a/qt/mainwindow.cpp +++ b/qt/mainwindow.cpp @@ -76,14 +76,8 @@ MainWindow::MainWindow(Framework & framework, bool apiOpenGLES3, QDesktopWidget const * desktop(QApplication::desktop()); setGeometry(desktop->screenGeometry(desktop->primaryScreen())); - if (screenshotParams != nullptr) + if (m_screenshotMode) { - QSizePolicy policy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setSizePolicy(policy); - QSize size(static_cast(screenshotParams->m_width), - static_cast(screenshotParams->m_height + statusBar()->geometry().height())); - setMaximumSize(size); - setMinimumSize(size); screenshotParams->m_statusChangedFn = [this](std::string const & state, bool finished) { statusBar()->showMessage(QString::fromStdString("Screenshot mode. " + state)); @@ -93,6 +87,18 @@ MainWindow::MainWindow(Framework & framework, bool apiOpenGLES3, } m_pDrawWidget = new DrawWidget(framework, apiOpenGLES3, std::move(screenshotParams), this); + + if (m_screenshotMode) + { + QSizePolicy policy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setSizePolicy(policy); + QSize size(static_cast(screenshotParams->m_width), static_cast(screenshotParams->m_height)); + m_pDrawWidget->resize(size); + size.setHeight(size.height() + statusBar()->height()); + setMaximumSize(size); + setMinimumSize(size); + } + setCentralWidget(m_pDrawWidget); QObject::connect(m_pDrawWidget, SIGNAL(BeforeEngineCreation()), this, SLOT(OnBeforeEngineCreation())); diff --git a/qt/qt_common/map_widget.cpp b/qt/qt_common/map_widget.cpp index 4c880d055a..6c31b4d9c6 100644 --- a/qt/qt_common/map_widget.cpp +++ b/qt/qt_common/map_widget.cpp @@ -91,9 +91,10 @@ void MapWidget::CreateEngine() Framework::DrapeCreationParams p; p.m_apiVersion = m_apiOpenGLES3 ? dp::ApiVersion::OpenGLES3 : dp::ApiVersion::OpenGLES2; - p.m_surfaceWidth = m_ratio * width(); - p.m_surfaceHeight = m_ratio * height(); - p.m_visualScale = m_ratio; + + p.m_surfaceWidth = m_screenshotMode ? width() : static_cast(m_ratio * width()); + p.m_surfaceHeight = m_screenshotMode ? height() : static_cast(m_ratio * height()); + p.m_visualScale = static_cast(m_ratio); p.m_hints.m_screenshotMode = m_screenshotMode; m_skin.reset(new gui::Skin(gui::ResolveGuiSkinFile("default"), m_ratio)); @@ -311,7 +312,8 @@ void MapWidget::ShowInfoPopup(QMouseEvent * e, m2::PointD const & pt) void MapWidget::initializeGL() { ASSERT(m_contextFactory == nullptr, ()); - m_ratio = devicePixelRatio(); + if (!m_screenshotMode) + m_ratio = devicePixelRatio(); m_contextFactory.reset(new QtOGLContextFactory(context())); emit BeforeEngineCreation(); @@ -360,8 +362,8 @@ void MapWidget::paintGL() void MapWidget::resizeGL(int width, int height) { - float w = m_ratio * width; - float h = m_ratio * height; + float w = m_screenshotMode ? width : static_cast(m_ratio * width); + float h = m_screenshotMode ? height : static_cast(m_ratio * height); m_framework.OnSize(w, h); m_framework.SetVisibleViewport(m2::RectD(0, 0, w, h)); if (m_skin) diff --git a/qt/screenshoter.cpp b/qt/screenshoter.cpp index 06d8571636..6d645e817b 100644 --- a/qt/screenshoter.cpp +++ b/qt/screenshoter.cpp @@ -33,14 +33,23 @@ void Screenshoter::Start() if (m_state != State::NotStarted) return; + if (m_screenshotParams.m_dstPath.empty()) + m_screenshotParams.m_dstPath = base::JoinPath(m_screenshotParams.m_kmlPath, "screenshots"); + + if (!Platform::IsDirectory(m_screenshotParams.m_kmlPath) || !Platform::MkDirChecked(m_screenshotParams.m_dstPath)) + { + ChangeState(State::FileError); + return; + } + m_framework.SetGraphicsReadyListener(std::bind(&Screenshoter::OnGraphicsReady, this)); Platform::FilesList files; - Platform::GetFilesByExt(m_screenshotParams.m_path, kKmlExtension, files); + Platform::GetFilesByExt(m_screenshotParams.m_kmlPath, kKmlExtension, files); for (auto const & file : files) { - auto const filePath = base::JoinPath(m_screenshotParams.m_path, file); + auto const filePath = base::JoinPath(m_screenshotParams.m_kmlPath, file); m_filesToProcess.push_back(filePath); } m_filesCount = m_filesToProcess.size(); @@ -59,8 +68,9 @@ void Screenshoter::ProcessNextKml() { auto const filePath = m_filesToProcess.front(); m_filesToProcess.pop_front(); - kmlData = LoadKmlFile(filePath, KmlFileType::Text); + m_nextScreenshotName = base::GetNameFromFullPathWithoutExt(filePath); + kmlData = LoadKmlFile(filePath, KmlFileType::Text); if (kmlData != nullptr && kmlData->m_bookmarksData.empty() && kmlData->m_tracksData.empty()) kmlData.reset(); } @@ -73,7 +83,9 @@ void Screenshoter::ProcessNextKml() } kmlData->m_categoryData.m_visible = true; - m_nextScreenshotName = kmlData->m_serverId + kml::GetDefaultStr(kmlData->m_categoryData.m_name); + + if (!kmlData->m_serverId.empty()) + m_nextScreenshotName = kmlData->m_serverId; BookmarkManager::KMLDataCollection collection; collection.emplace_back("", std::move(kmlData)); @@ -124,7 +136,7 @@ void Screenshoter::OnCountryChanged(storage::CountryId countryId) { if (m_state != State::WaitCountries) return; - CHECK_EQUAL(m_state, State::WaitCountries, ()); + auto const status = m_framework.GetStorage().CountryStatusEx(countryId); if (status == storage::Status::EOnDisk || status == storage::Status::EDownloadFailed || @@ -144,7 +156,6 @@ void Screenshoter::OnViewportChanged() if (m_state != State::WaitPosition) return; - CHECK_EQUAL(m_state, State::WaitPosition, ()); PrepareCountries(); } @@ -155,7 +166,7 @@ void Screenshoter::OnGraphicsReady() ChangeState(State::Ready); - auto const kWaitGraphicsDelay = seconds(3); + auto const kWaitGraphicsDelay = seconds(1); GetPlatform().RunDelayedTask(Platform::Thread::File, kWaitGraphicsDelay, [this]() { GetPlatform().RunTask(Platform::Thread::Gui, [this]() { SaveScreenshot(); }); @@ -166,8 +177,10 @@ void Screenshoter::SaveScreenshot() { CHECK_EQUAL(m_state, State::Ready, ()); - auto pixmap = QPixmap::grabWidget(m_widget); - pixmap.save(QString::fromStdString(base::JoinPath(m_screenshotParams.m_path, m_nextScreenshotName + ".png")), nullptr, 100); + QPixmap pixmap(QSize(m_screenshotParams.m_width, m_screenshotParams.m_height)); + m_widget->render(&pixmap, QPoint(), QRegion(m_widget->geometry())); + pixmap.save(QString::fromStdString(base::JoinPath(m_screenshotParams.m_dstPath, m_nextScreenshotName + ".png")), + nullptr, 100); m_nextScreenshotName.clear(); ProcessNextKml(); @@ -195,6 +208,7 @@ std::string DebugPrint(Screenshoter::State state) case Screenshoter::State::WaitCountries: return "WaitCountries"; case Screenshoter::State::WaitGraphics: return "WaitGraphics"; case Screenshoter::State::Ready: return "Ready"; + case Screenshoter::State::FileError: return "FileError"; case Screenshoter::State::Done: return "Done"; } UNREACHABLE(); diff --git a/qt/screenshoter.hpp b/qt/screenshoter.hpp index fb867c3ff3..d3c7cd180a 100644 --- a/qt/screenshoter.hpp +++ b/qt/screenshoter.hpp @@ -1,5 +1,7 @@ #pragma once +#include "drape_frontend/visual_params.hpp" + #include "storage/storage_defines.hpp" #include "geometry/rect2d.hpp" @@ -20,9 +22,11 @@ struct ScreenshotParams using TStatusChangedFn = std::function; - std::string m_path; + std::string m_kmlPath; + std::string m_dstPath; uint32_t m_width = kDefaultWidth; uint32_t m_height = kDefaultHeight; + double m_dpiScale = df::VisualParams::kXhdpiScale; TStatusChangedFn m_statusChangedFn; }; @@ -46,6 +50,7 @@ private: WaitCountries, WaitGraphics, Ready, + FileError, Done };