Project legacy canvas metadata into documents

This commit is contained in:
2026-06-05 17:54:45 +02:00
parent a9ef2c598c
commit d0412e3bf9
11 changed files with 580 additions and 4 deletions

View File

@@ -3,8 +3,15 @@
#include "legacy_document_canvas_services.h"
#include "app.h"
#include "canvas.h"
#include "legacy_history_services.h"
#include <algorithm>
#include <cstdint>
#include <span>
#include <string>
#include <vector>
namespace pp::panopainter {
namespace {
@@ -58,6 +65,20 @@ private:
App& app_;
};
[[nodiscard]] std::uint32_t legacy_u32_or_zero(int value) noexcept
{
return value <= 0 ? 0U : static_cast<std::uint32_t>(value);
}
[[nodiscard]] std::size_t pending_face_payload_count(const Layer& layer) noexcept
{
const auto frame_count = layer.frames_count();
if (frame_count <= 0) {
return 0U;
}
return static_cast<std::size_t>(frame_count) * pp::document::cube_face_count;
}
} // namespace
bool legacy_document_canvas_available(const App& app) noexcept
@@ -65,6 +86,61 @@ bool legacy_document_canvas_available(const App& app) noexcept
return app.canvas != nullptr && app.canvas->m_canvas != nullptr;
}
pp::foundation::Result<pp::app::DocumentCanvasSnapshotResult> capture_legacy_canvas_document_snapshot(
const Canvas& canvas)
{
std::vector<std::string> layer_names;
std::vector<std::vector<std::uint32_t>> layer_frame_durations;
std::vector<pp::app::DocumentCanvasLayerSnapshotInput> layers;
layer_names.reserve(canvas.m_layers.size());
layer_frame_durations.reserve(canvas.m_layers.size());
layers.reserve(canvas.m_layers.size());
for (const auto& legacy_layer : canvas.m_layers) {
if (!legacy_layer) {
continue;
}
layer_names.push_back(legacy_layer->m_name);
auto& durations = layer_frame_durations.emplace_back();
const auto frame_count = legacy_layer->frames_count();
durations.reserve(static_cast<std::size_t>(std::max(frame_count, 0)));
for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
durations.push_back(legacy_u32_or_zero(legacy_layer->frame_duration(frame_index)));
}
layers.push_back(pp::app::DocumentCanvasLayerSnapshotInput {
.name = layer_names.back(),
.visible = legacy_layer->m_visible,
.alpha_locked = legacy_layer->m_alpha_locked,
.opacity = legacy_layer->m_opacity,
.blend_mode = legacy_layer->m_blend_mode,
.frame_durations_ms = std::span<const std::uint32_t>(durations),
.pending_face_payloads = pending_face_payload_count(*legacy_layer),
});
}
return pp::app::plan_document_canvas_snapshot(pp::app::DocumentCanvasSnapshotInput {
.has_canvas = true,
.width = legacy_u32_or_zero(canvas.m_width),
.height = legacy_u32_or_zero(canvas.m_height),
.active_layer_index = static_cast<std::size_t>(std::max(canvas.m_current_layer_idx, 0)),
.active_frame_index = static_cast<std::size_t>(std::max(canvas.m_anim_frame, 0)),
.layers = std::span<const pp::app::DocumentCanvasLayerSnapshotInput>(layers),
});
}
pp::foundation::Result<pp::app::DocumentCanvasSnapshotResult> capture_legacy_canvas_document_snapshot(
const App& app)
{
if (!legacy_document_canvas_available(app)) {
return pp::foundation::Result<pp::app::DocumentCanvasSnapshotResult>::failure(
pp::foundation::Status::invalid_argument("legacy document canvas snapshot requires a canvas"));
}
return capture_legacy_canvas_document_snapshot(*app.canvas->m_canvas);
}
pp::foundation::Status execute_legacy_document_canvas_clear_plan(
App& app,
const pp::app::DocumentCanvasClearPlan& plan)