// 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 #include 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; }