Load PPI metadata into documents

This commit is contained in:
2026-06-01 13:00:14 +02:00
parent 7319cb9aa9
commit c16cab87bd
8 changed files with 388 additions and 26 deletions

View File

@@ -8,6 +8,9 @@ using pp::paint::BlendMode;
using pp::document::CanvasDocument;
using pp::document::DocumentHistory;
using pp::document::DocumentConfig;
using pp::document::DocumentLayerConfig;
using pp::document::DocumentSnapshotConfig;
using pp::document::AnimationFrame;
using pp::document::max_document_history_entries;
using pp::document::max_canvas_dimension;
using pp::document::max_frame_count;
@@ -106,11 +109,13 @@ void updates_layer_metadata(pp::tests::Harness& h)
PP_EXPECT(h, document.rename_layer(1, "Ink").ok());
PP_EXPECT(h, document.set_layer_visible(1, false).ok());
PP_EXPECT(h, document.set_layer_alpha_locked(1, true).ok());
PP_EXPECT(h, document.set_layer_opacity(1, 0.25F).ok());
PP_EXPECT(h, document.set_layer_blend_mode(1, BlendMode::multiply).ok());
PP_EXPECT(h, document.layers()[1].name == std::string_view("Ink"));
PP_EXPECT(h, !document.layers()[1].visible);
PP_EXPECT(h, document.layers()[1].alpha_locked);
PP_EXPECT(h, std::fabs(document.layers()[1].opacity - 0.25F) < 0.0001F);
PP_EXPECT(h, document.layers()[1].blend_mode == BlendMode::multiply);
}
@@ -129,6 +134,7 @@ void rejects_invalid_layer_metadata(pp::tests::Harness& h)
const auto bad_opacity_high = document.set_layer_opacity(0, 1.1F);
const auto bad_opacity_nan = document.set_layer_opacity(0, std::nanf(""));
const auto missing_visible = document.set_layer_visible(2, true);
const auto missing_alpha_lock = document.set_layer_alpha_locked(2, true);
const auto missing_blend = document.set_layer_blend_mode(2, BlendMode::normal);
const auto bad_blend = document.set_layer_blend_mode(0, static_cast<BlendMode>(255));
const auto bad_add_layer = document.add_layer(std::string(max_layer_name_length + 1U, 'x'));
@@ -147,6 +153,8 @@ void rejects_invalid_layer_metadata(pp::tests::Harness& h)
PP_EXPECT(h, bad_opacity_nan.code == StatusCode::out_of_range);
PP_EXPECT(h, !missing_visible.ok());
PP_EXPECT(h, missing_visible.code == StatusCode::out_of_range);
PP_EXPECT(h, !missing_alpha_lock.ok());
PP_EXPECT(h, missing_alpha_lock.code == StatusCode::out_of_range);
PP_EXPECT(h, !missing_blend.ok());
PP_EXPECT(h, missing_blend.code == StatusCode::out_of_range);
PP_EXPECT(h, !bad_blend.ok());
@@ -155,6 +163,88 @@ void rejects_invalid_layer_metadata(pp::tests::Harness& h)
PP_EXPECT(h, bad_add_layer.status().code == StatusCode::out_of_range);
}
void creates_document_from_snapshot_metadata(pp::tests::Harness& h)
{
const DocumentLayerConfig layers[] {
{
.name = "Ink",
.visible = false,
.alpha_locked = true,
.opacity = 0.5F,
.blend_mode = BlendMode::screen,
},
{
.name = "Glaze",
.visible = true,
.alpha_locked = false,
.opacity = 0.75F,
.blend_mode = BlendMode::overlay,
},
};
const AnimationFrame frames[] {
{ .duration_ms = 100 },
{ .duration_ms = 250 },
};
const auto document_result = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig {
.width = 128,
.height = 64,
.layers = layers,
.frames = frames,
});
PP_EXPECT(h, document_result.ok());
PP_EXPECT(h, document_result.value().layers().size() == 2U);
PP_EXPECT(h, document_result.value().layers()[0].name == std::string_view("Ink"));
PP_EXPECT(h, !document_result.value().layers()[0].visible);
PP_EXPECT(h, document_result.value().layers()[0].alpha_locked);
PP_EXPECT(h, document_result.value().layers()[0].blend_mode == BlendMode::screen);
PP_EXPECT(h, document_result.value().frames().size() == 2U);
PP_EXPECT(h, document_result.value().animation_duration_ms() == 350U);
}
void rejects_invalid_snapshot_metadata(pp::tests::Harness& h)
{
const DocumentLayerConfig layers[] { { .name = "Ink" } };
const AnimationFrame frames[] { { .duration_ms = 100 } };
const AnimationFrame bad_frames[] { { .duration_ms = 0 } };
const DocumentLayerConfig bad_layers[] { { .name = "" } };
const auto no_layers = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig {
.width = 64,
.height = 64,
.layers = {},
.frames = frames,
});
const auto no_frames = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig {
.width = 64,
.height = 64,
.layers = layers,
.frames = {},
});
const auto bad_frame = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig {
.width = 64,
.height = 64,
.layers = layers,
.frames = bad_frames,
});
const auto bad_layer = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig {
.width = 64,
.height = 64,
.layers = bad_layers,
.frames = frames,
});
PP_EXPECT(h, !no_layers.ok());
PP_EXPECT(h, no_layers.status().code == StatusCode::invalid_argument);
PP_EXPECT(h, !no_frames.ok());
PP_EXPECT(h, no_frames.status().code == StatusCode::invalid_argument);
PP_EXPECT(h, !bad_frame.ok());
PP_EXPECT(h, bad_frame.status().code == StatusCode::invalid_argument);
PP_EXPECT(h, !bad_layer.ok());
PP_EXPECT(h, bad_layer.status().code == StatusCode::invalid_argument);
}
void manages_animation_frames_and_duration(pp::tests::Harness& h)
{
auto document_result = CanvasDocument::create(
@@ -366,6 +456,8 @@ int main()
harness.run("moves_layers_and_preserves_active_layer_identity", moves_layers_and_preserves_active_layer_identity);
harness.run("updates_layer_metadata", updates_layer_metadata);
harness.run("rejects_invalid_layer_metadata", rejects_invalid_layer_metadata);
harness.run("creates_document_from_snapshot_metadata", creates_document_from_snapshot_metadata);
harness.run("rejects_invalid_snapshot_metadata", rejects_invalid_snapshot_metadata);
harness.run("manages_animation_frames_and_duration", manages_animation_frames_and_duration);
harness.run("moves_frames_and_preserves_active_frame_identity", moves_frames_and_preserves_active_frame_identity);
harness.run("rejects_invalid_animation_frame_operations", rejects_invalid_animation_frame_operations);