Harden stroke sampler edge tests
This commit is contained in:
@@ -95,7 +95,8 @@ Known local toolchain state:
|
|||||||
decode, PPI header/layout, settings document, document
|
decode, PPI header/layout, settings document, document
|
||||||
snapshot/per-layer-frame/move/duration/face-pixel/PPI export coverage,
|
snapshot/per-layer-frame/move/duration/face-pixel/PPI export coverage,
|
||||||
snapshot-embedded face-payload rejection, paint brush/final-blend/
|
snapshot-embedded face-payload rejection, paint brush/final-blend/
|
||||||
stroke-alpha-blend/stroke/stroke-script coverage, renderer shader descriptor and OpenGL capability coverage, UI
|
stroke-alpha-blend/stroke spacing/stroke stress/stroke-script coverage,
|
||||||
|
renderer shader descriptor and OpenGL capability coverage, UI
|
||||||
color parsing, and layout XML parse coverage.
|
color parsing, and layout XML parse coverage.
|
||||||
- `pano_cli inspect-image` reports PNG IHDR metadata as JSON and is covered by
|
- `pano_cli inspect-image` reports PNG IHDR metadata as JSON and is covered by
|
||||||
`pano_cli_inspect_png_metadata_smoke` with a tiny IHDR fixture.
|
`pano_cli_inspect_png_metadata_smoke` with a tiny IHDR fixture.
|
||||||
|
|||||||
@@ -320,7 +320,8 @@ corrupt/truncated/unsupported, extreme-dimension, and key/value limit tests.
|
|||||||
`pp_paint` has started with pure brush parameter validation/stamp evaluation,
|
`pp_paint` has started with pure brush parameter validation/stamp evaluation,
|
||||||
CPU reference math for the five current final RGBA shader blend modes plus the
|
CPU reference math for the five current final RGBA shader blend modes plus the
|
||||||
shader-style stroke-alpha blend modes used by pattern/dual-brush mixing, and deterministic
|
shader-style stroke-alpha blend modes used by pattern/dual-brush mixing, and deterministic
|
||||||
stroke spacing/interpolation plus a pure text stroke-script parser.
|
stroke spacing/interpolation plus duplicate-segment, non-finite, sample-limit,
|
||||||
|
and 1001-sample stress coverage, plus a pure text stroke-script parser.
|
||||||
`pp_document` has
|
`pp_document` has
|
||||||
started with a pure canvas/layer/frame model, alpha-lock metadata, snapshot
|
started with a pure canvas/layer/frame model, alpha-lock metadata, snapshot
|
||||||
construction, per-layer frame metadata, layer metadata operations, frame
|
construction, per-layer frame metadata, layer metadata operations, frame
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using pp::foundation::StatusCode;
|
using pp::foundation::StatusCode;
|
||||||
using pp::paint::StrokePoint;
|
using pp::paint::StrokePoint;
|
||||||
@@ -76,6 +77,50 @@ void can_skip_endpoint_and_clamps_pressure(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, near(result.value()[2].distance, 4.0F));
|
PP_EXPECT(h, near(result.value()[2].distance, 4.0F));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skips_zero_length_segments_without_resetting_spacing(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const std::array points {
|
||||||
|
StrokePoint { .x = 0.0F, .y = 0.0F, .pressure = 0.2F },
|
||||||
|
StrokePoint { .x = 0.0F, .y = 0.0F, .pressure = 0.8F },
|
||||||
|
StrokePoint { .x = 6.0F, .y = 0.0F, .pressure = 0.8F },
|
||||||
|
StrokePoint { .x = 6.0F, .y = 0.0F, .pressure = 0.1F },
|
||||||
|
StrokePoint { .x = 6.0F, .y = 4.0F, .pressure = 0.1F },
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto result = sample_stroke(points, StrokeSamplingConfig { .spacing = 3.0F });
|
||||||
|
PP_EXPECT(h, result.ok());
|
||||||
|
PP_EXPECT(h, result.value().size() == 5U);
|
||||||
|
PP_EXPECT(h, near(result.value()[1].x, 3.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[1].y, 0.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[2].x, 6.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[2].y, 0.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[3].x, 6.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[3].y, 3.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[4].distance, 10.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
void samples_large_stroke_with_deterministic_count(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const std::array points {
|
||||||
|
StrokePoint { .x = 0.0F, .y = 0.0F, .pressure = 0.0F },
|
||||||
|
StrokePoint { .x = 1000.0F, .y = 0.0F, .pressure = 1.0F },
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto result = sample_stroke(
|
||||||
|
points,
|
||||||
|
StrokeSamplingConfig {
|
||||||
|
.spacing = 1.0F,
|
||||||
|
.max_samples = 1001U,
|
||||||
|
});
|
||||||
|
PP_EXPECT(h, result.ok());
|
||||||
|
PP_EXPECT(h, result.value().size() == 1001U);
|
||||||
|
PP_EXPECT(h, near(result.value()[0].distance, 0.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[500].x, 500.0F));
|
||||||
|
PP_EXPECT(h, near(result.value()[500].pressure, 0.5F));
|
||||||
|
PP_EXPECT(h, near(result.value().back().x, 1000.0F));
|
||||||
|
PP_EXPECT(h, near(result.value().back().distance, 1000.0F));
|
||||||
|
}
|
||||||
|
|
||||||
void rejects_invalid_sampling_inputs(pp::tests::Harness& h)
|
void rejects_invalid_sampling_inputs(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
const std::array one_point {
|
const std::array one_point {
|
||||||
@@ -89,6 +134,10 @@ void rejects_invalid_sampling_inputs(pp::tests::Harness& h)
|
|||||||
StrokePoint { .x = 0.0F, .y = 0.0F },
|
StrokePoint { .x = 0.0F, .y = 0.0F },
|
||||||
StrokePoint { .x = std::nanf(""), .y = 1.0F },
|
StrokePoint { .x = std::nanf(""), .y = 1.0F },
|
||||||
};
|
};
|
||||||
|
const std::array non_finite_pressure {
|
||||||
|
StrokePoint { .x = 0.0F, .y = 0.0F },
|
||||||
|
StrokePoint { .x = 1.0F, .y = 1.0F, .pressure = std::nanf("") },
|
||||||
|
};
|
||||||
const std::array valid {
|
const std::array valid {
|
||||||
StrokePoint { .x = 0.0F, .y = 0.0F },
|
StrokePoint { .x = 0.0F, .y = 0.0F },
|
||||||
StrokePoint { .x = 10.0F, .y = 0.0F },
|
StrokePoint { .x = 10.0F, .y = 0.0F },
|
||||||
@@ -96,21 +145,29 @@ void rejects_invalid_sampling_inputs(pp::tests::Harness& h)
|
|||||||
|
|
||||||
const auto missing_points = sample_stroke(one_point, StrokeSamplingConfig {});
|
const auto missing_points = sample_stroke(one_point, StrokeSamplingConfig {});
|
||||||
const auto bad_spacing = sample_stroke(valid, StrokeSamplingConfig { .spacing = 0.0F });
|
const auto bad_spacing = sample_stroke(valid, StrokeSamplingConfig { .spacing = 0.0F });
|
||||||
|
const auto infinite_spacing = sample_stroke(
|
||||||
|
valid,
|
||||||
|
StrokeSamplingConfig { .spacing = std::numeric_limits<float>::infinity() });
|
||||||
const auto bad_limit = sample_stroke(valid, StrokeSamplingConfig { .max_samples = max_stroke_samples + 1U });
|
const auto bad_limit = sample_stroke(valid, StrokeSamplingConfig { .max_samples = max_stroke_samples + 1U });
|
||||||
const auto no_distance = sample_stroke(zero_length, StrokeSamplingConfig {});
|
const auto no_distance = sample_stroke(zero_length, StrokeSamplingConfig {});
|
||||||
const auto bad_point = sample_stroke(non_finite, StrokeSamplingConfig {});
|
const auto bad_point = sample_stroke(non_finite, StrokeSamplingConfig {});
|
||||||
|
const auto bad_pressure = sample_stroke(non_finite_pressure, StrokeSamplingConfig {});
|
||||||
const auto too_many = sample_stroke(valid, StrokeSamplingConfig { .spacing = 1.0F, .max_samples = 2U });
|
const auto too_many = sample_stroke(valid, StrokeSamplingConfig { .spacing = 1.0F, .max_samples = 2U });
|
||||||
|
|
||||||
PP_EXPECT(h, !missing_points.ok());
|
PP_EXPECT(h, !missing_points.ok());
|
||||||
PP_EXPECT(h, missing_points.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, missing_points.status().code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !bad_spacing.ok());
|
PP_EXPECT(h, !bad_spacing.ok());
|
||||||
PP_EXPECT(h, bad_spacing.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, bad_spacing.status().code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !infinite_spacing.ok());
|
||||||
|
PP_EXPECT(h, infinite_spacing.status().code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !bad_limit.ok());
|
PP_EXPECT(h, !bad_limit.ok());
|
||||||
PP_EXPECT(h, bad_limit.status().code == StatusCode::out_of_range);
|
PP_EXPECT(h, bad_limit.status().code == StatusCode::out_of_range);
|
||||||
PP_EXPECT(h, !no_distance.ok());
|
PP_EXPECT(h, !no_distance.ok());
|
||||||
PP_EXPECT(h, no_distance.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, no_distance.status().code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !bad_point.ok());
|
PP_EXPECT(h, !bad_point.ok());
|
||||||
PP_EXPECT(h, bad_point.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, bad_point.status().code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !bad_pressure.ok());
|
||||||
|
PP_EXPECT(h, bad_pressure.status().code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !too_many.ok());
|
PP_EXPECT(h, !too_many.ok());
|
||||||
PP_EXPECT(h, too_many.status().code == StatusCode::out_of_range);
|
PP_EXPECT(h, too_many.status().code == StatusCode::out_of_range);
|
||||||
}
|
}
|
||||||
@@ -123,6 +180,8 @@ int main()
|
|||||||
harness.run("samples_straight_line_at_fixed_spacing", samples_straight_line_at_fixed_spacing);
|
harness.run("samples_straight_line_at_fixed_spacing", samples_straight_line_at_fixed_spacing);
|
||||||
harness.run("carries_spacing_across_segments", carries_spacing_across_segments);
|
harness.run("carries_spacing_across_segments", carries_spacing_across_segments);
|
||||||
harness.run("can_skip_endpoint_and_clamps_pressure", can_skip_endpoint_and_clamps_pressure);
|
harness.run("can_skip_endpoint_and_clamps_pressure", can_skip_endpoint_and_clamps_pressure);
|
||||||
|
harness.run("skips_zero_length_segments_without_resetting_spacing", skips_zero_length_segments_without_resetting_spacing);
|
||||||
|
harness.run("samples_large_stroke_with_deterministic_count", samples_large_stroke_with_deterministic_count);
|
||||||
harness.run("rejects_invalid_sampling_inputs", rejects_invalid_sampling_inputs);
|
harness.run("rejects_invalid_sampling_inputs", rejects_invalid_sampling_inputs);
|
||||||
return harness.finish();
|
return harness.finish();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user