chiark / gitweb /
Tents: mark squares as non-tents with {Shift,Control}-cursor keys.
[sgt-puzzles.git] / ps.c
diff --git a/ps.c b/ps.c
index a2fd6190b308c42a450d835159546dcb2444093b..2394cc5e8e07499949ec69264a138bde632dff4b 100644 (file)
--- a/ps.c
+++ b/ps.c
@@ -35,12 +35,13 @@ static void ps_fill(psdata *ps, int colour)
     int hatch;
     float r, g, b;
 
-    print_get_colour(ps->drawing, colour, &hatch, &r, &g, &b);
+    print_get_colour(ps->drawing, colour, ps->colour, &hatch, &r, &g, &b);
 
-    if (ps->colour) {
-       ps_printf(ps, "%g %g %g setrgbcolor fill\n", r, g, b);
-    } else if (hatch == HATCH_SOLID || hatch == HATCH_CLEAR) {
-       ps_printf(ps, "%d setgray fill\n", hatch == HATCH_CLEAR);
+    if (hatch < 0) {
+       if (ps->colour)
+           ps_printf(ps, "%g %g %g setrgbcolor fill\n", r, g, b);
+       else
+           ps_printf(ps, "%g setgray fill\n", r);
     } else {
        /* Clip to the region. */
        ps_printf(ps, "gsave clip\n");
@@ -77,20 +78,17 @@ static void ps_setcolour_internal(psdata *ps, int colour, char *suffix)
     int hatch;
     float r, g, b;
 
-    print_get_colour(ps->drawing, colour, &hatch, &r, &g, &b);
+    print_get_colour(ps->drawing, colour, ps->colour, &hatch, &r, &g, &b);
 
-    if (ps->colour) {
-       if (r != g || r != b)
-           ps_printf(ps, "%g %g %g setrgbcolor%s\n", r, g, b, suffix);
-       else
-           ps_printf(ps, "%g setgray%s\n", r, suffix);
-    } else {
-       /*
-        * Stroking in hatched colours is not permitted.
-        */
-       assert(hatch == HATCH_SOLID || hatch == HATCH_CLEAR);
-       ps_printf(ps, "%d setgray%s\n", hatch == HATCH_CLEAR, suffix);
-    }
+    /*
+     * Stroking in hatched colours is not permitted.
+     */
+    assert(hatch < 0);
+    
+    if (ps->colour)
+       ps_printf(ps, "%g %g %g setrgbcolor%s\n", r, g, b, suffix);
+    else
+       ps_printf(ps, "%g setgray%s\n", r, suffix);
 }
 
 static void ps_setcolour(psdata *ps, int colour)
@@ -111,8 +109,8 @@ static void ps_draw_text(void *handle, int x, int y, int fonttype,
     y = ps->ytop - y;
     ps_setcolour(ps, colour);
     ps_printf(ps, "/%s findfont %d scalefont setfont\n",
-             fonttype == FONT_FIXED ? "Courier" : "Helvetica",
-             fontsize, x, y);
+             fonttype == FONT_FIXED ? "Courier-L1" : "Helvetica-L1",
+             fontsize);
     if (align & ALIGN_VCENTRE) {
        ps_printf(ps, "newpath 0 0 moveto (X) true charpath flattenpath"
                  " pathbbox\n"
@@ -233,6 +231,60 @@ static void ps_line_width(void *handle, float width)
     ps_printf(ps, "%g setlinewidth\n", width);
 }
 
+static void ps_line_dotted(void *handle, int dotted)
+{
+    psdata *ps = (psdata *)handle;
+
+    if (dotted) {
+       ps_printf(ps, "[ currentlinewidth 3 mul ] 0 setdash\n");
+    } else {
+       ps_printf(ps, "[ ] 0 setdash\n");
+    }
+}
+
+static char *ps_text_fallback(void *handle, const char *const *strings,
+                             int nstrings)
+{
+    /*
+     * We can handle anything in ISO 8859-1, and we'll manually
+     * translate it out of UTF-8 for the purpose.
+     */
+    int i, maxlen;
+    char *ret;
+
+    maxlen = 0;
+    for (i = 0; i < nstrings; i++) {
+       int len = strlen(strings[i]);
+       if (maxlen < len) maxlen = len;
+    }
+
+    ret = snewn(maxlen + 1, char);
+
+    for (i = 0; i < nstrings; i++) {
+       const char *p = strings[i];
+       char *q = ret;
+
+       while (*p) {
+           int c = (unsigned char)*p++;
+           if (c < 0x80) {
+               *q++ = c;              /* ASCII */
+           } else if ((c == 0xC2 || c == 0xC3) && (*p & 0xC0) == 0x80) {
+               *q++ = (c << 6) | (*p++ & 0x3F);   /* top half of 8859-1 */
+           } else {
+               break;
+           }
+       }
+
+       if (!*p) {
+           *q = '\0';
+           return ret;
+       }
+    }
+
+    assert(!"Should never reach here");
+    return NULL;
+}
+
 static void ps_begin_doc(void *handle, int pages)
 {
     psdata *ps = (psdata *)handle;
@@ -250,6 +302,34 @@ static void ps_begin_doc(void *handle, int pages)
     fputs("%%IncludeResource: font Helvetica\n", ps->fp);
     fputs("%%IncludeResource: font Courier\n", ps->fp);
     fputs("%%EndSetup\n", ps->fp);
+    fputs("%%BeginProlog\n", ps->fp);
+    /*
+     * Re-encode Helvetica and Courier into ISO-8859-1, which gives
+     * us times and divide signs - and also (according to the
+     * Language Reference Manual) a bonus in that the ASCII '-' code
+     * point now points to a minus sign instead of a hyphen.
+     */
+    fputs("/Helvetica findfont " /* get the font dictionary */
+         "dup maxlength dict dup begin " /* create and open a new dict */
+         "exch " /* move the original font to top of stack */
+         "{1 index /FID ne {def} {pop pop} ifelse} forall "
+                                      /* copy everything except FID */
+         "/Encoding ISOLatin1Encoding def "
+                             /* set the thing we actually wanted to change */
+         "/FontName /Helvetica-L1 def " /* set a new font name */
+         "FontName end exch definefont" /* and define the font */
+         "\n", ps->fp);
+    fputs("/Courier findfont " /* get the font dictionary */
+         "dup maxlength dict dup begin " /* create and open a new dict */
+         "exch " /* move the original font to top of stack */
+         "{1 index /FID ne {def} {pop pop} ifelse} forall "
+                                      /* copy everything except FID */
+         "/Encoding ISOLatin1Encoding def "
+                             /* set the thing we actually wanted to change */
+         "/FontName /Courier-L1 def " /* set a new font name */
+         "FontName end exch definefont" /* and define the font */
+         "\n", ps->fp);
+    fputs("%%EndProlog\n", ps->fp);
 }
 
 static void ps_begin_page(void *handle, int number)
@@ -323,6 +403,8 @@ static const struct drawing_api ps_drawing = {
     ps_end_page,
     ps_end_doc,
     ps_line_width,
+    ps_line_dotted,
+    ps_text_fallback,
 };
 
 psdata *ps_init(FILE *outfile, int colour)
@@ -334,7 +416,7 @@ psdata *ps_init(FILE *outfile, int colour)
     ps->ytop = 0;
     ps->clipped = FALSE;
     ps->hatchthick = ps->hatchspace = ps->gamewidth = ps->gameheight = 0;
-    ps->drawing = drawing_init(&ps_drawing, ps);
+    ps->drawing = drawing_new(&ps_drawing, NULL, ps);
 
     return ps;
 }