int guac_common_rect_expand_to_grid()

in src/common/rect.c [80:172]


int guac_common_rect_expand_to_grid(int cell_size, guac_common_rect* rect,
                                    const guac_common_rect* max_rect) {

    /* Invalid cell_size received */
    if (cell_size <= 0)
        return -1;

    /* Nothing to do */
    if (cell_size == 1)
        return 0;

    /* Calculate how much the rectangle must be adjusted to fit within the
     * given cell size. */
    int dw = cell_size - rect->width % cell_size;
    int dh = cell_size - rect->height % cell_size;

    int dx = dw / 2;
    int dy = dh / 2;

    /* Set initial extents of adjusted rectangle. */
    int top = rect->y - dy;
    int left = rect->x - dx;
    int bottom = top + rect->height + dh;
    int right = left + rect->width + dw;

    /* The max rectangle */
    int max_left   = max_rect->x;
    int max_top    = max_rect->y;
    int max_right  = max_left + max_rect->width;
    int max_bottom = max_top  + max_rect->height;

    /* If the adjusted rectangle has sides beyond the max rectangle, or is larger
     * in any direction; shift or adjust the rectangle while trying to fit in
     * the grid */

    /* Adjust left/right */
    if (right > max_right) {

        /* shift to left */
        dw = right - max_right;
        right -= dw;
        left -= dw;

        /* clamp left if too far */
        if (left < max_left) {
            left = max_left;
        }
    }
    else if (left < max_left) {

        /* shift to right */
        dw = max_left - left;
        left += dw;
        right += dw;

        /* clamp right if too far */
        if (right > max_right) {
            right = max_right;
        }
    }

    /* Adjust top/bottom */
    if (bottom > max_bottom) {

        /* shift up */
        dh = bottom - max_bottom;
        bottom -= dh;
        top -= dh;

        /* clamp top if too far */
        if (top < max_top) {
            top = max_top;
        }
    }
    else if (top < max_top) {

        /* shift down */
        dh = max_top - top;
        top += dh;
        bottom += dh;

        /* clamp bottom if too far */
        if (bottom > max_bottom) {
            bottom = max_bottom;
        }
    }

    /* Commit rect */
    guac_common_rect_init(rect, left, top, right - left, bottom - top);

    return 0;

}