Add paint renderer compositor tests
This commit is contained in:
65
src/paint_renderer/compositor.cpp
Normal file
65
src/paint_renderer/compositor.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "paint_renderer/compositor.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace pp::paint_renderer {
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] pp::foundation::Result<std::size_t> expected_pixel_count(pp::renderer::Extent2D extent) noexcept
|
||||
{
|
||||
const auto extent_status = pp::renderer::validate_extent(extent);
|
||||
if (!extent_status.ok()) {
|
||||
return pp::foundation::Result<std::size_t>::failure(extent_status);
|
||||
}
|
||||
|
||||
const auto width = static_cast<std::uint64_t>(extent.width);
|
||||
const auto height = static_cast<std::uint64_t>(extent.height);
|
||||
if (width > std::numeric_limits<std::uint64_t>::max() / height) {
|
||||
return pp::foundation::Result<std::size_t>::failure(
|
||||
pp::foundation::Status::out_of_range("pixel count overflows uint64"));
|
||||
}
|
||||
|
||||
const auto count = width * height;
|
||||
if (count > static_cast<std::uint64_t>(std::numeric_limits<std::size_t>::max())) {
|
||||
return pp::foundation::Result<std::size_t>::failure(
|
||||
pp::foundation::Status::out_of_range("pixel count exceeds addressable memory"));
|
||||
}
|
||||
|
||||
return pp::foundation::Result<std::size_t>::success(static_cast<std::size_t>(count));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pp::foundation::Status composite_layer(
|
||||
std::span<pp::paint::Rgba> destination,
|
||||
pp::renderer::Extent2D extent,
|
||||
LayerCompositeView layer) noexcept
|
||||
{
|
||||
const auto pixel_count = expected_pixel_count(extent);
|
||||
if (!pixel_count) {
|
||||
return pixel_count.status();
|
||||
}
|
||||
|
||||
if (destination.size() != pixel_count.value() || layer.pixels.size() != pixel_count.value()) {
|
||||
return pp::foundation::Status::invalid_argument("composite buffers must match the render extent");
|
||||
}
|
||||
|
||||
if (layer.opacity < 0.0F || layer.opacity > 1.0F) {
|
||||
return pp::foundation::Status::out_of_range("layer opacity must be between 0 and 1");
|
||||
}
|
||||
|
||||
if (!layer.visible || layer.opacity == 0.0F) {
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < destination.size(); ++i) {
|
||||
auto stroke = layer.pixels[i];
|
||||
stroke.a *= layer.opacity;
|
||||
destination[i] = pp::paint::blend_pixels(destination[i], stroke, layer.blend_mode);
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user