747 lines
29 KiB
C++
747 lines
29 KiB
C++
#include "pch.h"
|
|
|
|
#include "legacy_document_export_services.h"
|
|
|
|
#include "app.h"
|
|
#include "legacy_document_canvas_services.h"
|
|
#include "paint_renderer/compositor.h"
|
|
|
|
#include <array>
|
|
#include <fstream>
|
|
#include <limits>
|
|
#include <span>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
namespace pp::panopainter {
|
|
namespace {
|
|
|
|
void show_export_success_dialog(
|
|
App& app,
|
|
const pp::app::DocumentExportSuccessDialogPlan& plan)
|
|
{
|
|
if (plan.show_dialog) {
|
|
app.message_box(plan.dialog.title, plan.dialog.message, plan.dialog.show_cancel);
|
|
}
|
|
}
|
|
|
|
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');
|
|
}
|
|
|
|
struct LegacyDocumentExportSnapshotReports {
|
|
pp::app::DocumentCanvasSnapshotResult snapshot;
|
|
pp::paint_renderer::DocumentFrameFacePngExportResult face_pngs;
|
|
};
|
|
|
|
pp::foundation::Status write_export_binary_file(std::string_view path, std::span<const std::byte> bytes)
|
|
{
|
|
if (path.empty()) {
|
|
return pp::foundation::Status::invalid_argument("export path must not be empty");
|
|
}
|
|
if (bytes.size() > static_cast<std::size_t>(std::numeric_limits<std::streamsize>::max())) {
|
|
return pp::foundation::Status::out_of_range("export payload is too large to write");
|
|
}
|
|
|
|
std::ofstream stream(std::string(path), std::ios::binary);
|
|
if (!stream) {
|
|
return pp::foundation::Status::invalid_argument("export path could not be opened for writing");
|
|
}
|
|
|
|
stream.write(reinterpret_cast<const char*>(bytes.data()), static_cast<std::streamsize>(bytes.size()));
|
|
if (!stream) {
|
|
return pp::foundation::Status::invalid_argument("export payload could not be written");
|
|
}
|
|
|
|
return pp::foundation::Status::success();
|
|
}
|
|
|
|
class LegacyExportWriteServices final
|
|
: public pp::app::DocumentCubeFaceExportWriteServices
|
|
, public pp::app::DocumentDepthExportWriteServices
|
|
, public pp::app::DocumentExportCollectionWriteServices {
|
|
public:
|
|
explicit LegacyExportWriteServices(App& app) noexcept
|
|
: app_(app)
|
|
{
|
|
}
|
|
|
|
pp::foundation::Status write_binary_file(
|
|
std::string_view path,
|
|
std::span<const std::byte> bytes) override
|
|
{
|
|
return write_export_binary_file(path, bytes);
|
|
}
|
|
|
|
void publish_exported_image(std::string_view path) override
|
|
{
|
|
app_.publish_exported_image(std::string(path));
|
|
}
|
|
|
|
private:
|
|
App& app_;
|
|
};
|
|
|
|
pp::foundation::Result<LegacyDocumentExportSnapshotReports> prepare_legacy_document_export_snapshot(
|
|
App& app,
|
|
const char* context)
|
|
{
|
|
auto snapshot = capture_legacy_canvas_document_payload_snapshot(app);
|
|
if (!snapshot) {
|
|
LOG("%s document export snapshot failed: %s", context, snapshot.status().message);
|
|
return pp::foundation::Result<LegacyDocumentExportSnapshotReports>::failure(snapshot.status());
|
|
}
|
|
|
|
const auto report = pp::app::make_document_canvas_save_snapshot_report(snapshot.value());
|
|
LOG(
|
|
"%s document export snapshot: %ux%u layers=%zu frames=%zu capturedFaces=%zu pendingFaces=%zu ppiReady=%s",
|
|
context,
|
|
report.width,
|
|
report.height,
|
|
report.layer_count,
|
|
report.frame_count,
|
|
report.captured_face_payloads,
|
|
report.pending_face_payloads,
|
|
report.can_export_ppi ? "true" : "false");
|
|
|
|
LegacyDocumentExportSnapshotReports reports {
|
|
.snapshot = std::move(snapshot.value()),
|
|
};
|
|
if (!report.can_export_ppi) {
|
|
return pp::foundation::Result<LegacyDocumentExportSnapshotReports>::success(std::move(reports));
|
|
}
|
|
|
|
auto readiness = pp::paint_renderer::prepare_document_frame_export_readiness(
|
|
pp::paint_renderer::DocumentFrameCompositeRequest {
|
|
.document = &reports.snapshot.document,
|
|
.frame_index = reports.snapshot.document.active_frame_index(),
|
|
.clear_color = {},
|
|
});
|
|
if (!readiness) {
|
|
LOG("%s document export renderer readiness failed: %s", context, readiness.status().message);
|
|
return pp::foundation::Result<LegacyDocumentExportSnapshotReports>::failure(readiness.status());
|
|
}
|
|
|
|
auto readiness_value = std::move(readiness.value());
|
|
const auto& recorded_upload = readiness_value.recorded_upload;
|
|
const auto& uploaded = recorded_upload.upload;
|
|
LOG(
|
|
"%s document export renderer upload: textures=%zu bytes=%llu transitions=%zu facePayloads=%zu commands=%zu uploadCommands=%zu transitionCommands=%zu",
|
|
context,
|
|
uploaded.texture_count,
|
|
static_cast<unsigned long long>(uploaded.uploaded_bytes),
|
|
uploaded.transition_count,
|
|
uploaded.composite.face_payload_count,
|
|
recorded_upload.command_count,
|
|
recorded_upload.upload_command_count,
|
|
recorded_upload.transition_command_count);
|
|
|
|
LOG(
|
|
"%s document export face PNG export: faces=%zu bytes=%llu facePayloads=%zu compositedLayerFaces=%zu",
|
|
context,
|
|
readiness_value.face_pngs.face_count,
|
|
static_cast<unsigned long long>(readiness_value.face_pngs.encoded_bytes),
|
|
readiness_value.face_pngs.composite.face_payload_count,
|
|
readiness_value.face_pngs.composite.composited_layer_face_count);
|
|
reports.face_pngs = std::move(readiness_value.face_pngs);
|
|
|
|
return pp::foundation::Result<LegacyDocumentExportSnapshotReports>::success(std::move(reports));
|
|
}
|
|
|
|
void prepare_legacy_document_export_snapshot_or_continue(App& app, const char* context)
|
|
{
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app, context);
|
|
if (!prepared) {
|
|
LOG(
|
|
"%s document export snapshot bridge retained legacy export after failure: %s",
|
|
context,
|
|
prepared.status().message);
|
|
}
|
|
}
|
|
|
|
pp::foundation::Status export_cube_faces_from_document_snapshot(
|
|
App& app,
|
|
std::string_view document_name,
|
|
const LegacyDocumentExportSnapshotReports& reports)
|
|
{
|
|
const auto target = pp::app::make_document_cube_face_export_target(app.work_path, document_name);
|
|
if (!target) {
|
|
return target.status();
|
|
}
|
|
if (reports.face_pngs.face_count != pp::document::cube_face_count) {
|
|
return pp::foundation::Status::invalid_argument("document snapshot did not produce all cube face PNGs");
|
|
}
|
|
|
|
std::array<pp::app::DocumentCubeFaceExportPayload, pp::document::cube_face_count> payloads;
|
|
for (std::size_t face_index = 0; face_index < payloads.size(); ++face_index) {
|
|
payloads[face_index].bytes = std::span<const std::byte>(reports.face_pngs.face_pngs[face_index]);
|
|
}
|
|
|
|
LegacyExportWriteServices services(app);
|
|
return pp::app::execute_document_cube_face_export_write(target.value(), payloads, services);
|
|
}
|
|
|
|
pp::foundation::Status export_layers_from_document_snapshot(
|
|
App& app,
|
|
const pp::app::DocumentExportCollectionTarget& target,
|
|
const LegacyDocumentExportSnapshotReports& reports)
|
|
{
|
|
const auto report = pp::app::make_document_canvas_save_snapshot_report(reports.snapshot);
|
|
if (!report.payload_complete) {
|
|
return pp::foundation::Status::invalid_argument(
|
|
"document snapshot layer export still requires renderer payload readback");
|
|
}
|
|
|
|
auto exported = pp::paint_renderer::export_document_layers_equirectangular_pngs(
|
|
pp::paint_renderer::DocumentLayerEquirectangularPngExportRequest {
|
|
.document = &reports.snapshot.document,
|
|
.frame_index = reports.snapshot.document.active_frame_index(),
|
|
.clear_color = {},
|
|
});
|
|
if (!exported) {
|
|
return exported.status();
|
|
}
|
|
|
|
auto exported_value = std::move(exported.value());
|
|
LOG(
|
|
"export-layers document export PNG writer: layers=%zu bytes=%llu activeFrame=%zu",
|
|
exported_value.layer_count,
|
|
static_cast<unsigned long long>(exported_value.encoded_bytes),
|
|
reports.snapshot.document.active_frame_index());
|
|
|
|
std::vector<pp::app::DocumentExportCollectionPngPayload> payloads;
|
|
payloads.reserve(exported_value.layers.size());
|
|
for (const auto& layer : exported_value.layers) {
|
|
payloads.push_back(pp::app::DocumentExportCollectionPngPayload {
|
|
.path_suffix = pp::app::make_document_layer_export_path_suffix(layer.layer_index, layer.layer_name),
|
|
.bytes = std::span<const std::byte>(layer.png.data(), layer.png.size()),
|
|
});
|
|
}
|
|
|
|
LegacyExportWriteServices services(app);
|
|
return pp::app::execute_document_export_collection_write(target, payloads, services);
|
|
}
|
|
|
|
pp::foundation::Status export_animation_frames_from_document_snapshot(
|
|
App& app,
|
|
const pp::app::DocumentExportCollectionTarget& target,
|
|
const LegacyDocumentExportSnapshotReports& reports)
|
|
{
|
|
const auto report = pp::app::make_document_canvas_save_snapshot_report(reports.snapshot);
|
|
if (!report.payload_complete) {
|
|
return pp::foundation::Status::invalid_argument(
|
|
"document snapshot animation-frame export still requires renderer payload readback");
|
|
}
|
|
|
|
auto exported = pp::paint_renderer::export_document_animation_frames_equirectangular_pngs(
|
|
pp::paint_renderer::DocumentAnimationFrameEquirectangularPngExportRequest {
|
|
.document = &reports.snapshot.document,
|
|
.clear_color = {},
|
|
});
|
|
if (!exported) {
|
|
return exported.status();
|
|
}
|
|
|
|
auto exported_value = std::move(exported.value());
|
|
LOG(
|
|
"export-animation-frames document export PNG writer: frames=%zu bytes=%llu",
|
|
exported_value.frame_count,
|
|
static_cast<unsigned long long>(exported_value.encoded_bytes));
|
|
|
|
std::vector<pp::app::DocumentExportCollectionPngPayload> payloads;
|
|
payloads.reserve(exported_value.frames.size());
|
|
for (const auto& frame : exported_value.frames) {
|
|
payloads.push_back(pp::app::DocumentExportCollectionPngPayload {
|
|
.path_suffix = pp::app::make_document_animation_frame_export_path_suffix(frame.frame_index),
|
|
.bytes = std::span<const std::byte>(frame.png.data(), frame.png.size()),
|
|
});
|
|
}
|
|
|
|
LegacyExportWriteServices services(app);
|
|
return pp::app::execute_document_export_collection_write(target, payloads, services);
|
|
}
|
|
|
|
pp::foundation::Status export_equirectangular_png_from_document_snapshot(
|
|
App& app,
|
|
const pp::app::DocumentExportFileTarget& target,
|
|
const LegacyDocumentExportSnapshotReports& reports)
|
|
{
|
|
if (!is_png_export_target(target.path)) {
|
|
return pp::foundation::Status::invalid_argument(
|
|
"document snapshot equirectangular export currently supports PNG targets only");
|
|
}
|
|
|
|
auto exported = pp::paint_renderer::export_document_frame_equirectangular_png(reports.face_pngs.composite);
|
|
if (!exported) {
|
|
return exported.status();
|
|
}
|
|
|
|
auto exported_value = std::move(exported.value());
|
|
LOG(
|
|
"export-equirectangular document export PNG writer: %ux%u bytes=%llu facePayloads=%zu compositedLayerFaces=%zu",
|
|
exported_value.equirectangular_extent.width,
|
|
exported_value.equirectangular_extent.height,
|
|
static_cast<unsigned long long>(exported_value.encoded_bytes),
|
|
exported_value.face_payload_count,
|
|
exported_value.composited_layer_face_count);
|
|
const auto write_status = write_export_binary_file(
|
|
target.path,
|
|
std::span<const std::byte>(exported_value.png.data(), exported_value.png.size()));
|
|
if (!write_status.ok()) {
|
|
return write_status;
|
|
}
|
|
|
|
app.publish_exported_image(target.path);
|
|
return pp::foundation::Status::success();
|
|
}
|
|
|
|
class LegacyDocumentExportServices final : public pp::app::DocumentExportServices {
|
|
public:
|
|
explicit LegacyDocumentExportServices(App& app) noexcept
|
|
: app_(app)
|
|
{
|
|
}
|
|
|
|
bool create_directory(std::string_view directory) override
|
|
{
|
|
return Asset::create_dir(std::string(directory));
|
|
}
|
|
|
|
void export_equirectangular(const pp::app::DocumentExportFileTarget& target) override
|
|
{
|
|
auto* app = &app_;
|
|
#if !__WEB__
|
|
if (is_png_export_target(target.path)) {
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-equirectangular");
|
|
if (prepared) {
|
|
const auto exported = export_equirectangular_png_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);
|
|
} else {
|
|
LOG(
|
|
"export-equirectangular document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
} else
|
|
#endif
|
|
{
|
|
prepare_legacy_document_export_snapshot_or_continue(app_, "export-equirectangular");
|
|
}
|
|
app_.canvas->m_canvas->export_equirectangular(target.path, [app, target] {
|
|
#if __WEB__
|
|
app->ui_task([app, target] {
|
|
app->save_prepared_file(target.path, target.suggested_name, [](const std::string&, bool) { });
|
|
});
|
|
#else
|
|
(void)target;
|
|
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));
|
|
#endif
|
|
});
|
|
}
|
|
|
|
void export_layers_to_stem(const pp::app::DocumentExportStemTarget& target) override
|
|
{
|
|
auto* app = &app_;
|
|
#if !__WEB__
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-layers");
|
|
if (prepared) {
|
|
const auto collection_target = pp::app::DocumentExportCollectionTarget {
|
|
.stem_path = target.stem_path,
|
|
};
|
|
const auto exported = export_layers_from_document_snapshot(app_, collection_target, prepared.value());
|
|
if (exported.ok()) {
|
|
show_export_success_dialog(
|
|
app_,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::layers,
|
|
pp::app::DocumentExportSuccessDestination::path,
|
|
target.stem_path));
|
|
return;
|
|
}
|
|
|
|
LOG("export-layers document export writer retained legacy export after failure: %s", exported.message);
|
|
} else {
|
|
LOG(
|
|
"export-layers document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
#else
|
|
prepare_legacy_document_export_snapshot_or_continue(app_, "export-layers");
|
|
#endif
|
|
app_.canvas->m_canvas->export_layers(target.stem_path, [app, target] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::layers,
|
|
pp::app::DocumentExportSuccessDestination::path,
|
|
target.stem_path));
|
|
});
|
|
}
|
|
|
|
void export_layers_to_collection(const pp::app::DocumentExportCollectionTarget& target) override
|
|
{
|
|
auto* app = &app_;
|
|
#if !__WEB__
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-layers");
|
|
if (prepared) {
|
|
const auto exported = export_layers_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::layers,
|
|
pp::app::DocumentExportSuccessDestination::files_panopainter));
|
|
return;
|
|
}
|
|
|
|
LOG("export-layers document export writer retained legacy export after failure: %s", exported.message);
|
|
} else {
|
|
LOG(
|
|
"export-layers document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
#else
|
|
prepare_legacy_document_export_snapshot_or_continue(app_, "export-layers");
|
|
#endif
|
|
app_.canvas->m_canvas->export_layers(target.stem_path, [app] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::layers,
|
|
pp::app::DocumentExportSuccessDestination::files_panopainter));
|
|
});
|
|
}
|
|
|
|
void export_animation_frames_to_stem(const pp::app::DocumentExportStemTarget& target) override
|
|
{
|
|
auto* app = &app_;
|
|
#if !__WEB__
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-animation-frames");
|
|
if (prepared) {
|
|
const auto collection_target = pp::app::DocumentExportCollectionTarget {
|
|
.stem_path = target.stem_path,
|
|
};
|
|
const auto exported = export_animation_frames_from_document_snapshot(
|
|
app_,
|
|
collection_target,
|
|
prepared.value());
|
|
if (exported.ok()) {
|
|
show_export_success_dialog(
|
|
app_,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::animation_frames,
|
|
pp::app::DocumentExportSuccessDestination::path,
|
|
target.stem_path));
|
|
return;
|
|
}
|
|
|
|
LOG(
|
|
"export-animation-frames document export writer retained legacy export after failure: %s",
|
|
exported.message);
|
|
} else {
|
|
LOG(
|
|
"export-animation-frames document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
#else
|
|
prepare_legacy_document_export_snapshot_or_continue(app_, "export-animation-frames");
|
|
#endif
|
|
app_.canvas->m_canvas->export_anim_frames(target.stem_path, [app, target] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::animation_frames,
|
|
pp::app::DocumentExportSuccessDestination::path,
|
|
target.stem_path));
|
|
});
|
|
}
|
|
|
|
void export_animation_frames_to_collection(const pp::app::DocumentExportCollectionTarget& target) override
|
|
{
|
|
auto* app = &app_;
|
|
#if !__WEB__
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-animation-frames");
|
|
if (prepared) {
|
|
const auto exported = export_animation_frames_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::animation_frames,
|
|
pp::app::DocumentExportSuccessDestination::files_panopainter));
|
|
return;
|
|
}
|
|
|
|
LOG(
|
|
"export-animation-frames document export writer retained legacy export after failure: %s",
|
|
exported.message);
|
|
} else {
|
|
LOG(
|
|
"export-animation-frames document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
#else
|
|
prepare_legacy_document_export_snapshot_or_continue(app_, "export-animation-frames");
|
|
#endif
|
|
app_.canvas->m_canvas->export_anim_frames(target.stem_path, [app] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::animation_frames,
|
|
pp::app::DocumentExportSuccessDestination::files_panopainter));
|
|
});
|
|
}
|
|
|
|
void export_depth(std::string_view document_name) override
|
|
{
|
|
auto* app = &app_;
|
|
#if !__WEB__
|
|
const auto target = pp::app::make_document_depth_export_target(app_.work_path, document_name);
|
|
if (target) {
|
|
LOG(
|
|
"export-depth document export target: image=%s depth=%s",
|
|
target.value().image_path.c_str(),
|
|
target.value().depth_path.c_str());
|
|
} else {
|
|
LOG("export-depth document export target planning failed: %s", target.status().message);
|
|
}
|
|
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-depth");
|
|
if (prepared) {
|
|
const auto plan = pp::paint_renderer::plan_document_depth_export_render(
|
|
pp::paint_renderer::DocumentDepthExportRenderPlanRequest {
|
|
.document = &prepared.value().snapshot.document,
|
|
.frame_index = prepared.value().snapshot.document.active_frame_index(),
|
|
});
|
|
if (plan) {
|
|
LOG(
|
|
"export-depth document export render plan: output=%ux%u mergedFaceDraws=%zu layerDepthDraws=%zu visitedLayers=%zu visibleLayers=%zu facePayloads=%zu requiresRendererReadback=%s",
|
|
plan.value().output_extent.width,
|
|
plan.value().output_extent.height,
|
|
plan.value().merged_face_draw_count,
|
|
plan.value().layer_depth_draw_count,
|
|
plan.value().visited_layer_count,
|
|
plan.value().visible_layer_count,
|
|
plan.value().face_payload_count,
|
|
plan.value().requires_renderer_readback ? "true" : "false");
|
|
} else {
|
|
LOG(
|
|
"export-depth document export render plan retained legacy export after failure: %s",
|
|
plan.status().message);
|
|
}
|
|
} else {
|
|
LOG(
|
|
"export-depth document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
#else
|
|
prepare_legacy_document_export_snapshot_or_continue(app_, "export-depth");
|
|
#endif
|
|
app_.canvas->m_canvas->export_depth(std::string(document_name), [app] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::depth,
|
|
pp::app::document_export_media_platform_destination(),
|
|
app->work_path));
|
|
});
|
|
}
|
|
|
|
void export_cube_faces(std::string_view document_name) override
|
|
{
|
|
auto* app = &app_;
|
|
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-cube-faces");
|
|
if (prepared) {
|
|
const auto exported = export_cube_faces_from_document_snapshot(app_, document_name, prepared.value());
|
|
if (exported.ok()) {
|
|
show_export_success_dialog(
|
|
app_,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::cube_faces,
|
|
pp::app::document_export_media_platform_destination(),
|
|
app_.work_path));
|
|
return;
|
|
}
|
|
|
|
LOG(
|
|
"export-cube-faces document export writer retained legacy export after failure: %s",
|
|
exported.message);
|
|
} else {
|
|
LOG(
|
|
"export-cube-faces document export snapshot bridge retained legacy export after failure: %s",
|
|
prepared.status().message);
|
|
}
|
|
|
|
app_.canvas->m_canvas->export_cube_faces(std::string(document_name), [app] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::cube_faces,
|
|
pp::app::document_export_media_platform_destination(),
|
|
app->work_path));
|
|
});
|
|
}
|
|
|
|
private:
|
|
App& app_;
|
|
};
|
|
|
|
class LegacyDocumentVideoExportServices final : public pp::app::DocumentVideoExportServices {
|
|
public:
|
|
LegacyDocumentVideoExportServices(App& app, bool asynchronous) noexcept
|
|
: app_(app)
|
|
, asynchronous_(asynchronous)
|
|
{
|
|
}
|
|
|
|
void export_animation_mp4(std::string_view path) override
|
|
{
|
|
auto* app = &app_;
|
|
auto path_string = std::string(path);
|
|
if (asynchronous_) {
|
|
Canvas::I->export_anim_mp4(path_string, [app, path_string] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::animation_mp4,
|
|
pp::app::DocumentExportSuccessDestination::path,
|
|
path_string));
|
|
});
|
|
return;
|
|
}
|
|
|
|
Canvas::I->export_anim_mp4(path_string, [app] {
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::animation_mp4,
|
|
pp::app::DocumentExportSuccessDestination::generic_success));
|
|
});
|
|
}
|
|
|
|
void export_timelapse_mp4(std::string_view path) override
|
|
{
|
|
auto* app = &app_;
|
|
auto path_string = std::string(path);
|
|
if (asynchronous_) {
|
|
std::thread([app, path_string] {
|
|
BT_SetTerminate();
|
|
app->rec_export(path_string);
|
|
show_export_success_dialog(
|
|
*app,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::timelapse,
|
|
pp::app::DocumentExportSuccessDestination::path,
|
|
path_string));
|
|
}).detach();
|
|
return;
|
|
}
|
|
|
|
app->rec_export(path_string);
|
|
}
|
|
|
|
void show_animation_export_success(std::string_view path) override
|
|
{
|
|
(void)path;
|
|
}
|
|
|
|
void show_timelapse_export_success(std::string_view path) override
|
|
{
|
|
if (asynchronous_) {
|
|
(void)path;
|
|
} else {
|
|
(void)path;
|
|
show_export_success_dialog(
|
|
app_,
|
|
pp::app::plan_document_export_success_dialog(
|
|
pp::app::DocumentExportSuccessKind::timelapse,
|
|
pp::app::DocumentExportSuccessDestination::generic_success));
|
|
}
|
|
}
|
|
|
|
private:
|
|
App& app_;
|
|
bool asynchronous_ = false;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
pp::foundation::Status execute_legacy_document_export_file(
|
|
App& app,
|
|
const pp::app::DocumentExportFileTarget& target)
|
|
{
|
|
LegacyDocumentExportServices services(app);
|
|
return pp::app::execute_document_export_file(target, services);
|
|
}
|
|
|
|
pp::foundation::Status execute_legacy_document_export_stem(
|
|
App& app,
|
|
pp::app::DocumentExportCollectionKind kind,
|
|
const pp::app::DocumentExportStemTarget& target)
|
|
{
|
|
LegacyDocumentExportServices services(app);
|
|
return pp::app::execute_document_export_stem(kind, target, services);
|
|
}
|
|
|
|
pp::foundation::Status execute_legacy_document_export_collection(
|
|
App& app,
|
|
pp::app::DocumentExportCollectionKind kind,
|
|
const pp::app::DocumentExportCollectionTarget& target)
|
|
{
|
|
LegacyDocumentExportServices services(app);
|
|
return pp::app::execute_document_export_collection(kind, target, services);
|
|
}
|
|
|
|
pp::foundation::Status execute_legacy_document_export_depth(
|
|
App& app,
|
|
std::string_view document_name)
|
|
{
|
|
LegacyDocumentExportServices services(app);
|
|
return pp::app::execute_document_export_depth(document_name, services);
|
|
}
|
|
|
|
pp::foundation::Status execute_legacy_document_export_cube_faces(
|
|
App& app,
|
|
std::string_view document_name)
|
|
{
|
|
LegacyDocumentExportServices services(app);
|
|
return pp::app::execute_document_export_cube_faces(document_name, services);
|
|
}
|
|
|
|
pp::foundation::Status execute_legacy_document_video_export(
|
|
App& app,
|
|
pp::app::DocumentVideoExportKind kind,
|
|
std::string_view path,
|
|
bool asynchronous)
|
|
{
|
|
LegacyDocumentVideoExportServices services(app, asynchronous);
|
|
return pp::app::execute_document_video_export(kind, path, services);
|
|
}
|
|
|
|
} // namespace pp::panopainter
|