From 2499eb47fa4e0c86bc1b6100b4922026670b2ad8 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 2 Apr 2023 14:30:30 +0100 Subject: [PATCH] hat-test: more scaling and clipping options. This adds the ability to turn off hat-test's normal scaling of the bounding box to fit on an A4 page, which I intended for printing test patches (but never actually found a need to print one). The --unscaled mode seems more useful if you're planning to turn the output into an image, e.g. to use as a desktop background. Also added --clip, which generates a rectangle completely covered in hats (i.e. shows any hat that overlaps the output rectangle at all), as opposed to the normal mode which omits any hat that doesn't fit _entirely_ in the output rectangle (more similar to what Loopy wants). Actually generating a desktop background by this method is still a bit fiddly to get right, but it's better than before. --- auxiliary/hat-test.c | 64 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/auxiliary/hat-test.c b/auxiliary/hat-test.c index 4f25cc7..e41a53a 100644 --- a/auxiliary/hat-test.c +++ b/auxiliary/hat-test.c @@ -377,6 +377,7 @@ typedef struct drawctx { psbbox *bbox; KiteEnum *kiteenum; FourColourMap fourcolourmap[KE_NKEEP]; + bool natural_scale, clip; } drawctx; static void bbox_add_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords) @@ -396,24 +397,59 @@ static void header(drawctx *ctx) { switch (ctx->outfmt) { case OF_POSTSCRIPT: { - float xext = ctx->bbox->tr.x - ctx->bbox->bl.x; - float yext = ctx->bbox->tr.y - ctx->bbox->bl.y; - float ext = (xext > yext ? xext : yext); - float scale = 500 / ext; - float ox = 287 - scale * (ctx->bbox->bl.x + ctx->bbox->tr.x) / 2; - float oy = 421 - scale * (ctx->bbox->bl.y + ctx->bbox->tr.y) / 2; + float scale, ox, oy; + + /* Optionally clip to an inner rectangle that guarantees + * the whole visible area is covered in hats. */ + if (ctx->clip) { + ctx->bbox->bl.x += 9; + ctx->bbox->tr.x -= 9; + ctx->bbox->bl.y += 12 * sqrt(0.75); + ctx->bbox->tr.y -= 12 * sqrt(0.75); + } + + if (!ctx->natural_scale) { + /* Scale the output to fit on an A4 page, for test prints. */ + float w = 595, h = 842, margin = 12; + float xext = ctx->bbox->tr.x - ctx->bbox->bl.x; + float yext = ctx->bbox->tr.y - ctx->bbox->bl.y; + float xscale = (w - 2*margin) / xext; + float yscale = (h - 2*margin) / yext; + scale = xscale < yscale ? xscale : yscale; + ox = (w - scale * (ctx->bbox->bl.x + ctx->bbox->tr.x)) / 2; + oy = (h - scale * (ctx->bbox->bl.y + ctx->bbox->tr.y)) / 2; + } else { + /* Leave the patch at its natural scale. */ + scale = 1.0; + + /* And translate the lower left corner of the bounding box to 0. */ + ox = -ctx->bbox->bl.x; + oy = -ctx->bbox->bl.y; + } printf("%%!PS-Adobe-2.0\n%%%%Creator: hat-test from Simon Tatham's " "Portable Puzzle Collection\n%%%%Pages: 1\n" "%%%%BoundingBox: %f %f %f %f\n" "%%%%EndComments\n%%%%Page: 1 1\n", - ox + scale * ctx->bbox->bl.x - 20, - oy + scale * ctx->bbox->bl.y - 20, - ox + scale * ctx->bbox->tr.x + 20, - oy + scale * ctx->bbox->tr.y + 20); + ox + scale * ctx->bbox->bl.x, + oy + scale * ctx->bbox->bl.y, + ox + scale * ctx->bbox->tr.x, + oy + scale * ctx->bbox->tr.y); + if (ctx->clip) { + printf("%f %f moveto %f %f lineto %f %f lineto %f %f lineto " + "closepath clip\n", + ox + scale * ctx->bbox->bl.x, + oy + scale * ctx->bbox->bl.y, + ox + scale * ctx->bbox->bl.x, + oy + scale * ctx->bbox->tr.y, + ox + scale * ctx->bbox->tr.x, + oy + scale * ctx->bbox->tr.y, + ox + scale * ctx->bbox->tr.x, + oy + scale * ctx->bbox->bl.y); + } printf("%f %f translate %f dup scale\n", ox, oy, scale); - printf("%f setlinewidth\n", scale * 0.03); + printf("%f setlinewidth\n", 0.06); printf("0 setgray 1 setlinejoin 1 setlinecap\n"); break; } @@ -533,6 +569,8 @@ int main(int argc, char **argv) dctx->outfmt = OF_POSTSCRIPT; dctx->colourmode = CM_SEMANTIC; + dctx->natural_scale = false; + dctx->clip = false; dctx->kiteenum = s; while (--argc > 0) { @@ -549,6 +587,10 @@ int main(int argc, char **argv) dctx->outfmt = OF_PYTHON; } else if (!strcmp(arg, "--fourcolour")) { dctx->colourmode = CM_FOURCOLOUR; + } else if (!strcmp(arg, "--unscaled")) { + dctx->natural_scale = true; + } else if (!strcmp(arg, "--clip")) { + dctx->clip = true; } else if (!strncmp(arg, "--seed=", 7)) { random_seed = arg+7; } else if (arg[0] == '-') {