9e58e72bf6
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.
82 lines
3.1 KiB
C++
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;
|
|
}
|