Add document frame render automation
This commit is contained in:
@@ -727,6 +727,12 @@ struct SimulateDocumentExportArgs {
|
||||
std::uint32_t height = 32;
|
||||
};
|
||||
|
||||
struct SimulateDocumentRenderArgs {
|
||||
std::uint32_t width = 64;
|
||||
std::uint32_t height = 32;
|
||||
std::uint32_t frame = 0;
|
||||
};
|
||||
|
||||
struct SimulateDocumentHistoryArgs {
|
||||
std::uint32_t width = 64;
|
||||
std::uint32_t height = 32;
|
||||
@@ -2431,6 +2437,7 @@ void print_help()
|
||||
<< " save-project --path FILE --width N --height N [--layer-name NAME] [--layer-opacity N] [--blend-mode N] [--alpha-locked] [--hidden] [--layers N] [--frames N] [--frame-duration-ms N] [--include-test-face-payload] [--payload-layer N] [--payload-frame N]\n"
|
||||
<< " simulate-document-edits [--width N] [--height N]\n"
|
||||
<< " simulate-document-export [--width N] [--height N]\n"
|
||||
<< " simulate-document-render [--width N] [--height N] [--frame N]\n"
|
||||
<< " simulate-document-history [--width N] [--height N] [--history N]\n"
|
||||
<< " simulate-app-session [--no-canvas] [--new-document] [--unsaved] [--close-prompt-open] [--save-intent save|save-as|save-version|save-dirty-version]\n"
|
||||
<< " simulate-blend\n"
|
||||
@@ -10600,6 +10607,132 @@ int simulate_document_export(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_simulate_document_render_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
SimulateDocumentRenderArgs& args)
|
||||
{
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
const std::string_view key(argv[i]);
|
||||
if (key == "--width" || key == "--height" || key == "--frame") {
|
||||
if (i + 1 >= argc) {
|
||||
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||
}
|
||||
|
||||
const auto value = pp::foundation::parse_u32(argv[++i]);
|
||||
if (!value) {
|
||||
return value.status();
|
||||
}
|
||||
|
||||
if (key == "--width") {
|
||||
args.width = value.value();
|
||||
} else if (key == "--height") {
|
||||
args.height = value.value();
|
||||
} else {
|
||||
args.frame = value.value();
|
||||
}
|
||||
} else {
|
||||
return pp::foundation::Status::invalid_argument("unknown option");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.width == 0 || args.height == 0) {
|
||||
return pp::foundation::Status::invalid_argument("width and height must be greater than zero");
|
||||
}
|
||||
|
||||
if (args.width < 8 || args.height < 8) {
|
||||
return pp::foundation::Status::out_of_range("width and height must be at least 8 for render simulation");
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool pixel_differs_from_clear(pp::paint::Rgba pixel, pp::paint::Rgba clear) noexcept
|
||||
{
|
||||
return pixel.r != clear.r || pixel.g != clear.g || pixel.b != clear.b || pixel.a != clear.a;
|
||||
}
|
||||
|
||||
int simulate_document_render(int argc, char** argv)
|
||||
{
|
||||
SimulateDocumentRenderArgs args;
|
||||
const auto status = parse_simulate_document_render_args(argc, argv, args);
|
||||
if (!status.ok()) {
|
||||
print_error("simulate-document-render", status.message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto document_result = create_export_sample_document(args.width, args.height);
|
||||
if (!document_result) {
|
||||
print_error("simulate-document-render", document_result.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
constexpr pp::paint::Rgba clear_color {};
|
||||
const auto composited = pp::paint_renderer::composite_document_frame(
|
||||
pp::paint_renderer::DocumentFrameCompositeRequest {
|
||||
.document = &document_result.value(),
|
||||
.frame_index = args.frame,
|
||||
.clear_color = clear_color,
|
||||
});
|
||||
if (!composited) {
|
||||
print_error("simulate-document-render", composited.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto& document = document_result.value();
|
||||
const auto& result = composited.value();
|
||||
std::cout << "{\"ok\":true,\"command\":\"simulate-document-render\""
|
||||
<< ",\"source\":{\"width\":" << document.width()
|
||||
<< ",\"height\":" << document.height()
|
||||
<< ",\"layers\":" << document.layers().size()
|
||||
<< ",\"frames\":" << document.frames().size()
|
||||
<< ",\"facePayloads\":" << document.face_pixel_payload_count()
|
||||
<< "},\"render\":{\"frame\":" << args.frame
|
||||
<< ",\"width\":" << result.extent.width
|
||||
<< ",\"height\":" << result.extent.height
|
||||
<< ",\"faces\":" << result.faces.size()
|
||||
<< ",\"visitedLayers\":" << result.visited_layer_count
|
||||
<< ",\"compositedLayerFaces\":" << result.composited_layer_face_count
|
||||
<< ",\"facePayloads\":" << result.face_payload_count
|
||||
<< ",\"faceSummaries\":[";
|
||||
for (std::size_t face_index = 0; face_index < result.faces.size(); ++face_index) {
|
||||
const auto& face = result.faces[face_index];
|
||||
std::size_t non_clear_pixels = 0;
|
||||
std::size_t first_non_clear = face.pixels.size();
|
||||
for (std::size_t pixel_index = 0; pixel_index < face.pixels.size(); ++pixel_index) {
|
||||
if (!pixel_differs_from_clear(face.pixels[pixel_index], clear_color)) {
|
||||
continue;
|
||||
}
|
||||
if (first_non_clear == face.pixels.size()) {
|
||||
first_non_clear = pixel_index;
|
||||
}
|
||||
++non_clear_pixels;
|
||||
}
|
||||
|
||||
if (face_index != 0U) {
|
||||
std::cout << ",";
|
||||
}
|
||||
std::cout << "{\"face\":" << face_index
|
||||
<< ",\"pixels\":" << face.pixels.size()
|
||||
<< ",\"payloads\":" << face.face_payload_count
|
||||
<< ",\"nonClearPixels\":" << non_clear_pixels;
|
||||
if (first_non_clear != face.pixels.size()) {
|
||||
const auto& pixel = face.pixels[first_non_clear];
|
||||
std::cout << ",\"firstNonClear\":{\"index\":" << first_non_clear
|
||||
<< ",\"x\":" << (first_non_clear % result.extent.width)
|
||||
<< ",\"y\":" << (first_non_clear / result.extent.width)
|
||||
<< ",\"r\":" << pixel.r
|
||||
<< ",\"g\":" << pixel.g
|
||||
<< ",\"b\":" << pixel.b
|
||||
<< ",\"a\":" << pixel.a
|
||||
<< "}";
|
||||
}
|
||||
std::cout << "}";
|
||||
}
|
||||
std::cout << "]}}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_simulate_document_history_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
@@ -11736,6 +11869,10 @@ int main(int argc, char** argv)
|
||||
return simulate_document_export(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "simulate-document-render") {
|
||||
return simulate_document_render(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "simulate-document-history") {
|
||||
return simulate_document_history(argc, argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user