+ /*
+ * Scan the grid to find the limits of the region within which
+ * any rectangle containing this point must fall. This will
+ * save us trawling the inside of every rectangle later on to
+ * see if it contains any used squares.
+ */
+ top = scratch;
+ bottom = scratch + params->w;
+ for (dy = -1; dy <= +1; dy += 2) {
+ int *array = (dy == -1 ? top : bottom);
+ for (dx = -1; dx <= +1; dx += 2) {
+ for (x = sx; x >= 0 && x < params->w; x += dx) {
+ array[x] = -2 * params->h * dy;
+ for (y = sy; y >= 0 && y < params->h; y += dy) {
+ if (index(params, grid, x, y) == -1 &&
+ (x == sx || dy*y <= dy*array[x-dx]))
+ array[x] = y;
+ else
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Now scan again to work out the largest rectangles we can fit
+ * in the grid, so that we can terminate the following loops
+ * early once we get down to not having much space left in the
+ * grid.
+ */
+ realmaxarea = 0;
+ for (x = 0; x < params->w; x++) {
+ int x2;
+
+ rh = bottom[x] - top[x] + 1;
+ if (rh <= 0)
+ continue; /* no rectangles can start here */
+
+ dx = (x > sx ? -1 : +1);
+ for (x2 = x; x2 >= 0 && x2 < params->w; x2 += dx)
+ if (bottom[x2] < bottom[x] || top[x2] > top[x])
+ break;
+
+ rw = abs(x2 - x);
+ if (realmaxarea < rw * rh)
+ realmaxarea = rw * rh;
+ }
+
+ if (realmaxarea > maxarea)
+ realmaxarea = maxarea;
+
+ /*
+ * Rectangles which go right the way across the grid are
+ * boring, although they can't be helped in the case of
+ * extremely small grids. (Also they might be generated later
+ * on by the singleton-removal process; we can't help that.)
+ */
+ mw = params->w - 1;
+ if (mw < 3) mw++;
+ mh = params->h - 1;
+ if (mh < 3) mh++;
+
+ for (rw = 1; rw <= mw; rw++)
+ for (rh = 1; rh <= mh; rh++) {
+ if (rw * rh > realmaxarea)