Author:ptrace Comitter:ptrace Date:2026-08-24 15:26:29 UTC

Math: added rect scaling with discrete origins

diff --git a/0x2_Math.jai b/0x2_Math.jai index 7469a26..5b4c2c8 100644 --- a/0x2_Math.jai +++ b/0x2_Math.jai @@ -1,6 +1,25 @@ // TODO: Need module param for cringe xyz ordering Rect_Origin :: enum_flags {     NONE;     /** XY */     MID;     /** X */     LEFT;     RIGHT;     /** Y */     TOP;     BOTTOM; } roundf :: inline (x: float) -> float {     return floor(x + 0.5); } @@ -9,11 +28,65 @@ round :: inline (x: float) -> int {     return xx floor(x + 0.5); } /** Assumes:     x = LEFT to RIGHT     y = TOP  to BOTTOM */ rect_scale :: (rect: *$T/interface Rectangle, scale: Vector2, origin: Rect_Origin = .NONE) {     rect.* = rect_scale(rect.*, scale, origin); } /** Assumes:     x = LEFT to RIGHT     y = TOP  to BOTTOM */ rect_scale :: (rect: $T/interface Rectangle, scale: Vector2, origin: Rect_Origin = .NONE) -> T {     using new: T;     if !origin || origin == .NONE then origin = .MID;     if origin & .LEFT {         width = rect.width * scale.x;         x = rect.x;     }     else if origin & .RIGHT {         width = rect.width * scale.x;         x = (rect.x + rect.width) - width;     }     else if origin & .MID {         width = rect.width * scale.x;         x = (rect.x + rect.width / 2.0) - width / 2.0;     }     if origin & .TOP {         height = rect.height * scale.y;         y = rect.y;     }     else if origin & .BOTTOM {         height = rect.height * scale.y;         y = (rect.y + rect.height) - height;     }     else if origin & .MID {         height = rect.height * scale.y;         y = (rect.y + rect.height / 2.0) - height / 2.0;     }     return new; } #scope_file using, only(floor) Math :: #import "Math"; Rectangle :: struct {     x:      float;  /** top-left corner position x */     y:      float;  /** top-left corner position y */     width:  float;     height: float; } using, only(floor, Vector2) Math :: #import "Math"; /* diff --git a/tests/assertion.jai b/tests/assertion.jai index b5b32e2..7f3c5de 100644 --- a/tests/assertion.jai +++ b/tests/assertion.jai @@ -17,20 +17,20 @@ ass :: (comp: bool, loc := #caller_location) #expand {     } } ass :: (a: $T, b: T, loc := #caller_location) #expand { ass :: (a: $T, b: T, $code := ASS_CODE, loc := #caller_location) #expand {     if a != b {         #insert,scope() ASS_CODE;         #insert,scope() code;     } } /** Cannot use `[]$T, []T` here, because Jai cannot resolve the overloads then */ ass :: (a: []int, b: []int, loc := #caller_location) #expand { ass :: (a: []int, b: []int, $code := ASS_CODE, loc := #caller_location) #expand {     if a.count != b.count {         #insert,scope() ASS_CODE;         #insert,scope() code;     }     for a  if it != b[it_index] {         #insert,scope() ASS_CODE;         #insert,scope() code;     } } diff --git a/tests/math.jai b/tests/math.jai new file mode 100644 index 0000000..96b8f57 --- /dev/null +++ b/tests/math.jai @@ -0,0 +1,81 @@ ROOT :: Rectangle.{     0.0,     0.0,     100.0,     100.0, }; TESTS :: Test.[     { "top left",   ROOT, { 2.0, 2.0 }, .TOP    | .LEFT,  { 0.0, 0.0, 200.0, 200.0 } },     { "top right",  ROOT, { 2.0, 2.0 }, .TOP    | .RIGHT, { -100.0, 0.0, 200.0, 200.0 } },     { "top mid",    ROOT, { 2.0, 2.0 }, .TOP    | .MID,   { -50.0, 0.0, 200.0, 200.0 } },     { "mid left",   ROOT, { 2.0, 2.0 }, .MID    | .LEFT,  { 0.0, -50.0, 200.0, 200.0 } },     { "mid right",  ROOT, { 2.0, 2.0 }, .MID    | .RIGHT, { -100.0, -50.0, 200.0, 200.0 } },     { "mid (none)", ROOT, { 2.0, 2.0 }, .NONE,            { -50.0, -50.0, 200.0, 200.0 } },     { "mid",        ROOT, { 2.0, 2.0 }, .MID,             { -50.0, -50.0, 200.0, 200.0 } },     { "bot left",   ROOT, { 2.0, 2.0 }, .BOTTOM | .LEFT,  { 0.0, -100.0, 200.0, 200.0 } },     { "bot right",  ROOT, { 2.0, 2.0 }, .BOTTOM | .RIGHT, { -100.0, -100.0, 200.0, 200.0 } },     { "bot mid",    ROOT, { 2.0, 2.0 }, .BOTTOM | .MID,   { -50.0, -100.0, 200.0, 200.0 } }, ]; MY_ASS_CODE :: #code {     log_error("\n%: Test failed: '%'", loc, `it.label);     log_error("-------------------");     log_error(":Given\n%\n\n", a);     log_error(":Expected\n%\n\n", b);     `return false; } Rectangle :: struct {     x:      float;  /** top-left corner position x */     y:      float;  /** top-left corner position y */     width:  float;     height: float; } Test :: struct {     label: string;     root: Rectangle;     scale: Vector2;     origin: Rect_Origin;     expected: Rectangle; } operator == :: (a: Rectangle, b: Rectangle) -> bool {     result := true;     result &= a.x == b.x;     result &= a.y == b.y;     result &= a.width == b.width;     result &= a.height == b.height;     return result; } run :: () -> bool {     for TESTS {         new := rect_scale(it.root, it.scale, it.origin);         #if false then log_vars(it.label, new);         ass(new, it.expected, MY_ASS_CODE);     }     /** Test with pointer */     root := ROOT;     test :: TESTS[TESTS.count-1];     rect_scale(*root, test.scale, test.origin);     ass(root == test.expected);     return true; } #import "Basic"; #import "Print_Vars"; #import "Math"; #import,file "../0x2_Math.jai"; #load "assertion.jai"; diff --git a/tests/run_tests.jai b/tests/run_tests.jai index 6b55590..1287fab 100644 --- a/tests/run_tests.jai +++ b/tests/run_tests.jai @@ -46,6 +46,7 @@ main :: () {         ok &= df.run();         ok &= sp.run();         ok &= lx.run();         ok &= mt.run();     }     log("\n---------------------------------------------------------"); @@ -65,6 +66,7 @@ sp :: #import,file "string.jai"; lx :: #import,file "lexer.jai"; sc :: #import,file "seccomp.jai"; lk :: #import,file "landlock.jai"; mt :: #import,file "math.jai"; #import,file "../0x2_Qtrace.jai"; crash :: #import,file "../0x2_Crashed.jai";