Move export snapshot target support to app core
This commit is contained in:
@@ -424,6 +424,71 @@ public:
|
||||
return "Document export failed";
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool ascii_iequals(std::string_view left, std::string_view right) noexcept
|
||||
{
|
||||
if (left.size() != right.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < left.size(); ++i) {
|
||||
auto lhs = left[i];
|
||||
if (lhs >= 'A' && lhs <= 'Z') {
|
||||
lhs = static_cast<char>(lhs - 'A' + 'a');
|
||||
}
|
||||
auto rhs = right[i];
|
||||
if (rhs >= 'A' && rhs <= 'Z') {
|
||||
rhs = static_cast<char>(rhs - 'A' + 'a');
|
||||
}
|
||||
if (lhs != rhs) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool document_export_path_has_extension(
|
||||
std::string_view path,
|
||||
std::string_view extension) noexcept
|
||||
{
|
||||
return path.size() >= extension.size()
|
||||
&& ascii_iequals(path.substr(path.size() - extension.size()), extension);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool document_export_path_is_png_target(std::string_view path) noexcept
|
||||
{
|
||||
return document_export_path_has_extension(path, ".png");
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool document_export_path_is_jpeg_target(std::string_view path) noexcept
|
||||
{
|
||||
return document_export_path_has_extension(path, ".jpg")
|
||||
|| document_export_path_has_extension(path, ".jpeg");
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool document_export_snapshot_target_supported(
|
||||
DocumentExportExecutionKind kind,
|
||||
std::string_view target_path = {}) noexcept
|
||||
{
|
||||
switch (kind) {
|
||||
case DocumentExportExecutionKind::equirectangular_file:
|
||||
return document_export_path_is_png_target(target_path)
|
||||
|| document_export_path_is_jpeg_target(target_path);
|
||||
case DocumentExportExecutionKind::layers_collection:
|
||||
case DocumentExportExecutionKind::layers_stem:
|
||||
case DocumentExportExecutionKind::animation_frames_collection:
|
||||
case DocumentExportExecutionKind::animation_frames_stem:
|
||||
case DocumentExportExecutionKind::cube_faces:
|
||||
return true;
|
||||
case DocumentExportExecutionKind::depth:
|
||||
case DocumentExportExecutionKind::animation_mp4:
|
||||
case DocumentExportExecutionKind::timelapse:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr DocumentExportSnapshotRoutePlan plan_document_export_snapshot_route(
|
||||
DocumentExportExecutionKind kind,
|
||||
DocumentCanvasSaveSnapshotReport report,
|
||||
@@ -456,6 +521,19 @@ public:
|
||||
return plan;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr DocumentExportSnapshotRoutePlan plan_document_export_snapshot_route_for_target(
|
||||
DocumentExportExecutionKind kind,
|
||||
DocumentCanvasSaveSnapshotReport report,
|
||||
std::string_view target_path,
|
||||
bool platform_supported) noexcept
|
||||
{
|
||||
return plan_document_export_snapshot_route(
|
||||
kind,
|
||||
report,
|
||||
document_export_snapshot_target_supported(kind, target_path),
|
||||
platform_supported);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr DocumentExportCollectionTargetPlan plan_document_export_collection_target(
|
||||
DocumentExportCollectionKind kind,
|
||||
bool use_work_directory_collection) noexcept
|
||||
|
||||
@@ -25,53 +25,6 @@ void show_export_success_dialog(
|
||||
}
|
||||
}
|
||||
|
||||
bool is_png_export_target(std::string_view path) noexcept
|
||||
{
|
||||
if (path.size() < 4U) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto extension = path.substr(path.size() - 4U);
|
||||
return extension[0] == '.'
|
||||
&& (extension[1] == 'p' || extension[1] == 'P')
|
||||
&& (extension[2] == 'n' || extension[2] == 'N')
|
||||
&& (extension[3] == 'g' || extension[3] == 'G');
|
||||
}
|
||||
|
||||
bool ascii_iequals(std::string_view left, std::string_view right) noexcept
|
||||
{
|
||||
if (left.size() != right.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < left.size(); ++i) {
|
||||
auto lhs = left[i];
|
||||
if (lhs >= 'A' && lhs <= 'Z') {
|
||||
lhs = static_cast<char>(lhs - 'A' + 'a');
|
||||
}
|
||||
auto rhs = right[i];
|
||||
if (rhs >= 'A' && rhs <= 'Z') {
|
||||
rhs = static_cast<char>(rhs - 'A' + 'a');
|
||||
}
|
||||
if (lhs != rhs) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_extension(std::string_view path, std::string_view extension) noexcept
|
||||
{
|
||||
return path.size() >= extension.size()
|
||||
&& ascii_iequals(path.substr(path.size() - extension.size()), extension);
|
||||
}
|
||||
|
||||
bool is_jpeg_export_target(std::string_view path) noexcept
|
||||
{
|
||||
return has_extension(path, ".jpg") || has_extension(path, ".jpeg");
|
||||
}
|
||||
|
||||
struct LegacyDocumentExportSnapshotReports {
|
||||
pp::app::DocumentCanvasSnapshotResult snapshot;
|
||||
pp::paint_renderer::DocumentFrameFacePngExportResult face_pngs;
|
||||
@@ -202,18 +155,18 @@ void prepare_legacy_document_export_snapshot_or_continue(App& app, const char* c
|
||||
}
|
||||
}
|
||||
|
||||
bool use_legacy_document_snapshot_writer(
|
||||
bool should_use_document_snapshot_writer(
|
||||
const char* context,
|
||||
pp::app::DocumentExportExecutionKind kind,
|
||||
const LegacyDocumentExportSnapshotReports& reports,
|
||||
bool target_supported,
|
||||
std::string_view target_path,
|
||||
bool platform_supported)
|
||||
{
|
||||
const auto report = pp::app::make_document_canvas_save_snapshot_report(reports.snapshot);
|
||||
const auto route = pp::app::plan_document_export_snapshot_route(
|
||||
const auto route = pp::app::plan_document_export_snapshot_route_for_target(
|
||||
kind,
|
||||
report,
|
||||
target_supported,
|
||||
target_path,
|
||||
platform_supported);
|
||||
if (!route.uses_document_snapshot_writer) {
|
||||
LOG(
|
||||
@@ -344,7 +297,7 @@ pp::foundation::Status export_equirectangular_from_document_snapshot(
|
||||
pp::paint_renderer::DocumentFrameEquirectangularPngExportResult png_export;
|
||||
pp::paint_renderer::DocumentFrameEquirectangularJpegExportResult jpeg_export;
|
||||
|
||||
if (is_png_export_target(target.path)) {
|
||||
if (pp::app::document_export_path_is_png_target(target.path)) {
|
||||
auto exported = pp::paint_renderer::export_document_frame_equirectangular_png(reports.face_pngs.composite);
|
||||
if (!exported) {
|
||||
return exported.status();
|
||||
@@ -359,7 +312,7 @@ pp::foundation::Status export_equirectangular_from_document_snapshot(
|
||||
png_export.face_payload_count,
|
||||
png_export.composited_layer_face_count);
|
||||
bytes = std::span<const std::byte>(png_export.png.data(), png_export.png.size());
|
||||
} else if (is_jpeg_export_target(target.path)) {
|
||||
} else if (pp::app::document_export_path_is_jpeg_target(target.path)) {
|
||||
auto exported = pp::paint_renderer::export_document_frame_equirectangular_jpeg(reports.face_pngs.composite);
|
||||
if (!exported) {
|
||||
return exported.status();
|
||||
@@ -405,40 +358,37 @@ public:
|
||||
{
|
||||
auto* app = &app_;
|
||||
#if !__WEB__
|
||||
if (is_png_export_target(target.path) || is_jpeg_export_target(target.path)) {
|
||||
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-equirectangular");
|
||||
if (prepared) {
|
||||
if (use_legacy_document_snapshot_writer(
|
||||
"export-equirectangular",
|
||||
pp::app::DocumentExportExecutionKind::equirectangular_file,
|
||||
prepared.value(),
|
||||
true,
|
||||
true)) {
|
||||
const auto exported = export_equirectangular_from_document_snapshot(app_, target, prepared.value());
|
||||
if (exported.ok()) {
|
||||
show_export_success_dialog(
|
||||
app_,
|
||||
pp::app::plan_document_export_success_dialog(
|
||||
pp::app::DocumentExportSuccessKind::equirectangular,
|
||||
pp::app::document_export_equirectangular_platform_destination(),
|
||||
app_.work_path));
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(
|
||||
"export-equirectangular document export writer retained legacy export after failure: %s",
|
||||
exported.message);
|
||||
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-equirectangular");
|
||||
if (prepared) {
|
||||
if (should_use_document_snapshot_writer(
|
||||
"export-equirectangular",
|
||||
pp::app::DocumentExportExecutionKind::equirectangular_file,
|
||||
prepared.value(),
|
||||
target.path,
|
||||
true)) {
|
||||
const auto exported = export_equirectangular_from_document_snapshot(app_, target, prepared.value());
|
||||
if (exported.ok()) {
|
||||
show_export_success_dialog(
|
||||
app_,
|
||||
pp::app::plan_document_export_success_dialog(
|
||||
pp::app::DocumentExportSuccessKind::equirectangular,
|
||||
pp::app::document_export_equirectangular_platform_destination(),
|
||||
app_.work_path));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
LOG(
|
||||
"export-equirectangular document export snapshot bridge retained legacy export after failure: %s",
|
||||
prepared.status().message);
|
||||
"export-equirectangular document export writer retained legacy export after failure: %s",
|
||||
exported.message);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
prepare_legacy_document_export_snapshot_or_continue(app_, "export-equirectangular");
|
||||
} else {
|
||||
LOG(
|
||||
"export-equirectangular document export snapshot bridge retained legacy export after failure: %s",
|
||||
prepared.status().message);
|
||||
}
|
||||
#else
|
||||
prepare_legacy_document_export_snapshot_or_continue(app_, "export-equirectangular");
|
||||
#endif
|
||||
app_.canvas->m_canvas->export_equirectangular(target.path, [app, target] {
|
||||
#if __WEB__
|
||||
app->ui_task([app, target] {
|
||||
@@ -465,11 +415,11 @@ public:
|
||||
const auto collection_target = pp::app::DocumentExportCollectionTarget {
|
||||
.stem_path = target.stem_path,
|
||||
};
|
||||
if (use_legacy_document_snapshot_writer(
|
||||
if (should_use_document_snapshot_writer(
|
||||
"export-layers",
|
||||
pp::app::DocumentExportExecutionKind::layers_stem,
|
||||
prepared.value(),
|
||||
true,
|
||||
{},
|
||||
true)) {
|
||||
const auto exported = export_layers_from_document_snapshot(app_, collection_target, prepared.value());
|
||||
if (exported.ok()) {
|
||||
@@ -508,11 +458,11 @@ public:
|
||||
#if !__WEB__
|
||||
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-layers");
|
||||
if (prepared) {
|
||||
if (use_legacy_document_snapshot_writer(
|
||||
if (should_use_document_snapshot_writer(
|
||||
"export-layers",
|
||||
pp::app::DocumentExportExecutionKind::layers_collection,
|
||||
prepared.value(),
|
||||
true,
|
||||
{},
|
||||
true)) {
|
||||
const auto exported = export_layers_from_document_snapshot(app_, target, prepared.value());
|
||||
if (exported.ok()) {
|
||||
@@ -552,11 +502,11 @@ public:
|
||||
const auto collection_target = pp::app::DocumentExportCollectionTarget {
|
||||
.stem_path = target.stem_path,
|
||||
};
|
||||
if (use_legacy_document_snapshot_writer(
|
||||
if (should_use_document_snapshot_writer(
|
||||
"export-animation-frames",
|
||||
pp::app::DocumentExportExecutionKind::animation_frames_stem,
|
||||
prepared.value(),
|
||||
true,
|
||||
{},
|
||||
true)) {
|
||||
const auto exported = export_animation_frames_from_document_snapshot(
|
||||
app_,
|
||||
@@ -600,11 +550,11 @@ public:
|
||||
#if !__WEB__
|
||||
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-animation-frames");
|
||||
if (prepared) {
|
||||
if (use_legacy_document_snapshot_writer(
|
||||
if (should_use_document_snapshot_writer(
|
||||
"export-animation-frames",
|
||||
pp::app::DocumentExportExecutionKind::animation_frames_collection,
|
||||
prepared.value(),
|
||||
true,
|
||||
{},
|
||||
true)) {
|
||||
const auto exported = export_animation_frames_from_document_snapshot(app_, target, prepared.value());
|
||||
if (exported.ok()) {
|
||||
@@ -697,11 +647,11 @@ public:
|
||||
auto* app = &app_;
|
||||
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-cube-faces");
|
||||
if (prepared) {
|
||||
if (use_legacy_document_snapshot_writer(
|
||||
if (should_use_document_snapshot_writer(
|
||||
"export-cube-faces",
|
||||
pp::app::DocumentExportExecutionKind::cube_faces,
|
||||
prepared.value(),
|
||||
true,
|
||||
{},
|
||||
true)) {
|
||||
const auto exported = export_cube_faces_from_document_snapshot(app_, document_name, prepared.value());
|
||||
if (exported.ok()) {
|
||||
|
||||
Reference in New Issue
Block a user