Files
slate32/test/round_rect_test.cpp
T
evan 9e58e72bf6 build: add a format target and one shared editor config
clang-format had no config here, so adopting the submodule's puts both repos
on the same pointer alignment. .editorconfig is what lua-language-server reads
on save, which is why the Lua tree had drifted between tabs and two widths.
2026-08-04 13:20:08 -04:00

82 lines
3.1 KiB
C++

// Build & run: c++ -std=c++17 test/round_rect_test.cpp -o /tmp/round_rect_test
// && /tmp/round_rect_test
#include "../src/gfx/round_rect.h"
#include <cassert>
#include <cstdio>
using namespace gfx;
static float cornerCoverage(int w, int h, float radius, int column, int row) {
float halfWidth = w * 0.5f, halfHeight = h * 0.5f;
return coverage(roundRectDistance(column + 0.5f - halfWidth,
row + 0.5f - halfHeight, halfWidth,
halfHeight, radius));
}
int main() {
const int w = 296, h = 24;
const float radius = 6;
// A straight edge is pixel aligned, so it must be fully lit; a fringe there
// would show up as a washed-out border down the sides of every button.
assert(cornerCoverage(w, h, radius, 0, h / 2) == 1.0f);
assert(cornerCoverage(w, h, radius, w - 1, h / 2) == 1.0f);
assert(cornerCoverage(w, h, radius, w / 2, 0) == 1.0f);
// Well inside is solid, well outside the corner is empty.
assert(cornerCoverage(w, h, radius, w / 2, h / 2) == 1.0f);
assert(cornerCoverage(w, h, radius, 0, 0) == 0.0f);
// The corner is a real arc: partial pixels exist, and coverage grows
// monotonically along the diagonal instead of stepping like the old integer
// inset did.
bool sawPartial = false;
float previous = -1.0f;
for (int i = 0; i < (int)radius; i++) {
float value = cornerCoverage(w, h, radius, i, i);
if (value > 0.0f && value < 1.0f)
sawPartial = true;
assert(value >= previous);
previous = value;
}
assert(sawPartial && "an anti-aliased corner must produce partial coverage");
// The arc must stay within the radius: the pixel just past it is already
// solid.
assert(cornerCoverage(w, h, radius, (int)radius, (int)radius) == 1.0f);
// Symmetry across both axes, so no corner is fatter than another.
for (int row = 0; row < (int)radius; row++) {
for (int column = 0; column < (int)radius; column++) {
float topLeft = cornerCoverage(w, h, radius, column, row);
assert(topLeft == cornerCoverage(w, h, radius, w - 1 - column, row));
assert(topLeft == cornerCoverage(w, h, radius, column, h - 1 - row));
assert(topLeft ==
cornerCoverage(w, h, radius, w - 1 - column, h - 1 - row));
}
}
// radius 0 keeps square corners fully lit, which is what the mono theme pins.
assert(cornerCoverage(w, h, 0, 0, 0) == 1.0f);
// Blending endpoints must be exact, or repeated repaints would drift the
// colour.
const uint16_t black = 0x0000, white = 0xFFFF;
assert(blend565(black, white, 0.0f) == black);
assert(blend565(black, white, 1.0f) == white);
uint16_t half = blend565(black, white, 0.5f);
assert(half > black && half < white);
assert(blend565(white, white, 0.5f) == white);
// A gradient must reach both stops exactly, so a button's edges match its
// theme.
assert(lerp565(black, white, 0, h - 1) == black);
assert(lerp565(black, white, h - 1, h - 1) == white);
assert(lerp565(black, white, 1, 0) ==
black); // degenerate height must not divide by zero
printf("ok\n");
return 0;
}