#include "assets/ppi_header.h" #include "document/document.h" #include "document/ppi_export.h" #include "document/ppi_import.h" #include "test_harness.h" #include #include #include using pp::document::AnimationFrame; using pp::document::CanvasDocument; using pp::document::DocumentLayerConfig; using pp::document::DocumentSnapshotConfig; using pp::document::LayerFacePixels; using pp::document::export_ppi_project_document; using pp::foundation::StatusCode; namespace { void exports_document_metadata_and_face_payloads(pp::tests::Harness& h) { std::vector red_pixel { 255, 0, 0, 255 }; std::vector blue_pixel { 0, 0, 255, 128 }; const AnimationFrame root_frames[] { { .duration_ms = 100, .face_pixels = {} }, { .duration_ms = 250, .face_pixels = {} }, }; const AnimationFrame base_frames[] { { .duration_ms = 100, .face_pixels = { LayerFacePixels { .face_index = 0, .x = 2, .y = 3, .width = 1, .height = 1, .rgba8 = red_pixel, }, }, }, { .duration_ms = 250, .face_pixels = {} }, }; const AnimationFrame paint_frames[] { { .duration_ms = 333, .face_pixels = { LayerFacePixels { .face_index = 5, .x = 4, .y = 5, .width = 1, .height = 1, .rgba8 = blue_pixel, }, }, }, }; const DocumentLayerConfig layers[] { { .name = "Base", .visible = true, .alpha_locked = false, .opacity = 1.0F, .blend_mode = pp::paint::BlendMode::normal, .frames = std::span(base_frames, 2), }, { .name = "Paint", .visible = false, .alpha_locked = true, .opacity = 0.5F, .blend_mode = pp::paint::BlendMode::overlay, .frames = std::span(paint_frames, 1), }, }; const auto document = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig { .width = 64, .height = 32, .layers = std::span(layers, 2), .frames = std::span(root_frames, 2), .selection_masks = {}, }); PP_EXPECT(h, document.ok()); const auto exported = export_ppi_project_document(document.value()); PP_EXPECT(h, exported.ok()); const auto decoded = pp::assets::decode_ppi_project_images(exported.value()); PP_EXPECT(h, decoded.ok()); PP_EXPECT(h, decoded.value().project.body.summary.width == 64U); PP_EXPECT(h, decoded.value().project.body.summary.height == 32U); PP_EXPECT(h, decoded.value().project.body.summary.layer_count == 2U); PP_EXPECT(h, decoded.value().project.body.summary.declared_frame_count == 3U); PP_EXPECT(h, decoded.value().project.body.summary.dirty_face_count == 2U); PP_EXPECT(h, decoded.value().project.body.layers[0].name == "Base"); PP_EXPECT(h, decoded.value().project.body.layers[0].frames.size() == 2U); PP_EXPECT(h, decoded.value().project.body.layers[0].frames[1].duration_ms == 250U); PP_EXPECT(h, decoded.value().project.body.layers[1].name == "Paint"); PP_EXPECT(h, decoded.value().project.body.layers[1].opacity == 0.5F); PP_EXPECT(h, decoded.value().project.body.layers[1].blend_mode == 4U); PP_EXPECT(h, decoded.value().project.body.layers[1].alpha_locked); PP_EXPECT(h, !decoded.value().project.body.layers[1].visible); PP_EXPECT(h, decoded.value().faces.size() == 2U); PP_EXPECT(h, decoded.value().faces[0].layer_index == 0U); PP_EXPECT(h, decoded.value().faces[0].frame_index == 0U); PP_EXPECT(h, decoded.value().faces[0].face_index == 0U); PP_EXPECT(h, decoded.value().faces[0].descriptor.x0 == 2U); PP_EXPECT(h, decoded.value().faces[0].image.pixels[0] == 255U); PP_EXPECT(h, decoded.value().faces[1].layer_index == 1U); PP_EXPECT(h, decoded.value().faces[1].frame_index == 0U); PP_EXPECT(h, decoded.value().faces[1].face_index == 5U); PP_EXPECT(h, decoded.value().faces[1].descriptor.y0 == 5U); PP_EXPECT(h, decoded.value().faces[1].image.pixels[2] == 255U); PP_EXPECT(h, decoded.value().faces[1].image.pixels[3] == 128U); const auto imported = pp::document::import_ppi_project_document(decoded.value()); PP_EXPECT(h, imported.ok()); PP_EXPECT(h, imported.value().layers().size() == 2U); PP_EXPECT(h, imported.value().layers()[1].alpha_locked); PP_EXPECT(h, imported.value().face_pixel_payload_count() == 2U); } void rejects_snapshot_payload_that_cannot_export(pp::tests::Harness& h) { const AnimationFrame root_frames[] { { .duration_ms = 100, .face_pixels = {} }, }; const AnimationFrame bad_frames[] { { .duration_ms = 100, .face_pixels = { LayerFacePixels { .face_index = 0, .x = 0, .y = 0, .width = 1, .height = 1, .rgba8 = {}, }, }, }, }; const DocumentLayerConfig layers[] { { .name = "Bad", .visible = true, .alpha_locked = false, .opacity = 1.0F, .blend_mode = pp::paint::BlendMode::normal, .frames = std::span(bad_frames, 1), }, }; const auto document = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig { .width = 64, .height = 32, .layers = std::span(layers, 1), .frames = std::span(root_frames, 1), .selection_masks = {}, }); PP_EXPECT(h, !document.ok()); PP_EXPECT(h, document.status().code == StatusCode::invalid_argument); } } int main() { pp::tests::Harness harness; harness.run("exports_document_metadata_and_face_payloads", exports_document_metadata_and_face_payloads); harness.run("rejects_snapshot_payload_that_cannot_export", rejects_snapshot_payload_that_cannot_export); return harness.finish(); }