15b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/*
25b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey * Some utility functions on VTermRect structures
35b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey */
45b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
55b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#define STRFrect "(%d,%d-%d,%d)"
65b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#define ARGSrect(r) (r).start_row, (r).start_col, (r).end_row, (r).end_col
75b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
85b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/* Expand dst to contain src as well */
95b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void rect_expand(VTermRect *dst, VTermRect *src)
105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->start_row > src->start_row) dst->start_row = src->start_row;
125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->start_col > src->start_col) dst->start_col = src->start_col;
135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->end_row   < src->end_row)   dst->end_row   = src->end_row;
145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->end_col   < src->end_col)   dst->end_col   = src->end_col;
155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/* Clip the dst to ensure it does not step outside of bounds */
185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void rect_clip(VTermRect *dst, VTermRect *bounds)
195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->start_row < bounds->start_row) dst->start_row = bounds->start_row;
215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->start_col < bounds->start_col) dst->start_col = bounds->start_col;
225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->end_row   > bounds->end_row)   dst->end_row   = bounds->end_row;
235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->end_col   > bounds->end_col)   dst->end_col   = bounds->end_col;
245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  /* Ensure it doesn't end up negatively-sized */
255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->end_row < dst->start_row) dst->end_row = dst->start_row;
265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(dst->end_col < dst->start_col) dst->end_col = dst->start_col;
275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/* True if the two rectangles are equal */
305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic int rect_equal(VTermRect *a, VTermRect *b)
315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return (a->start_row == b->start_row) &&
335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey         (a->start_col == b->start_col) &&
345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey         (a->end_row   == b->end_row)   &&
355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey         (a->end_col   == b->end_col);
365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/* True if small is contained entirely within big */
395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic int rect_contains(VTermRect *big, VTermRect *small)
405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(small->start_row < big->start_row) return 0;
425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(small->start_col < big->start_col) return 0;
435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(small->end_row   > big->end_row)   return 0;
445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(small->end_col   > big->end_col)   return 0;
455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return 1;
465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/* True if the rectangles overlap at all */
495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic int rect_intersects(VTermRect *a, VTermRect *b)
505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(a->start_row > b->end_row || b->start_row > a->end_row)
525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 0;
535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(a->start_col > b->end_col || b->start_col > a->end_col)
545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 0;
555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return 1;
565b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
57