#ifndef KARLOS_RECT_H #define KARLOS_RECT_H #include /* --> x * | * V y */ struct rect { int x, y, xend, yend; }; #define RECT_XYWH(x, y, w, h) (struct rect){ (x), (y), (x + w), (y + h) } #define RECT_WIDTH(r) ((r).xend - (r).x) #define RECT_HEIGHT(r) ((r).yend - (r).y) #define RECT_XEND(r) ((r).xend) #define RECT_YEND(r) ((r).yend) // Moves `rect`. void rect_translate(struct rect *rect, int delta_x, int delta_y); // Clamps the rectangle `rect` to `boundary`. // The rect is cut off at the edges of `boundary`. // If there is no overlap, either width or height of the rect will be `0`. void rect_clamp(struct rect *rect, const struct rect *boundary); // Grows `rect` so that it encompasses both its original dimensions and `additional`. void rect_union(struct rect *rect, const struct rect *additional); // Example: // struct rect rect = RECT_XYWH(5, 10, 100, 100); // struct rect surrounding = RECT_XYWH(200, 200, 50, 500); // rect_local_to_global(&rect, &surrounding); // ASSERT(rect.x == 205 && rect.y == 210); // ASSERT(RECT_WIDTH(rect) == 45 && RECT_HEIGHT(rect) == 100); void rect_local_to_global(struct rect *rect, const struct rect *surrounding); unsigned int rect_area(struct rect *rect); bool rect_isempty(const struct rect *rect); #endif