chiark / gitweb /
Revise the printing colour framework so that we can explicitly
authorSimon Tatham <anakin@pobox.com>
Mon, 7 Apr 2008 17:13:29 +0000 (17:13 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 7 Apr 2008 17:13:29 +0000 (17:13 +0000)
request either of hatching or halftoning, and also choose which to
supply as a fallback when printing in colour.

[originally from svn r7976]

devel.but
drawing.c
galaxies.c
map.c
nullfe.c
ps.c
puzzles.h
solo.c
windows.c

index cf06656db60c470186c29a19556d4dfa41bdb02d..1df57cff1e3217054a97482bb7b21ef72755275b 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -1991,7 +1991,7 @@ black; if \c{grey} is 1, the colour is white.
 
 \S{print-grey-colour} \cw{print_grey_colour()}
 
-\c int print_grey_colour(drawing *dr, int hatch, float grey);
+\c int print_grey_colour(drawing *dr, float grey);
 
 This function allocates a colour index for a grey-scale colour
 during printing.
@@ -1999,18 +1999,17 @@ during printing.
 \c{grey} may be any number between 0 (black) and 1 (white); for
 example, 0.5 indicates a medium grey.
 
-If printing in black and white only, the \c{grey} value will not be
-used; instead, regions shaded in this colour will be hatched with
-parallel lines. The \c{hatch} parameter defines what type of
-hatching should be used in place of this colour:
+The chosen colour will be rendered to the limits of the printer's
+halftoning capability.
 
-\dt \cw{HATCH_SOLID}
+\S{print-hatched-colour} \cw{print_hatched_colour()}
 
-\dd In black and white, this colour will be replaced by solid black.
+\c int print_hatched_colour(drawing *dr, int hatch);
 
-\dt \cw{HATCH_CLEAR}
-
-\dd In black and white, this colour will be replaced by solid white.
+This function allocates a colour index which does not represent a
+literal \e{colour}. Instead, regions shaded in this colour will be
+hatched with parallel lines. The \c{hatch} parameter defines what
+type of hatching should be used in place of this colour:
 
 \dt \cw{HATCH_SLASH}
 
@@ -2039,29 +2038,59 @@ vertical lines.
 
 \dd This colour will be hatched by criss-crossing diagonal lines.
 
-Colours defined to use hatching may not be used for drawing lines;
-they may only be used for filling areas. That is, they may be used
-as the \c{fillcolour} parameter to \cw{draw_circle()} and
+Colours defined to use hatching may not be used for drawing lines or
+text; they may only be used for filling areas. That is, they may be
+used as the \c{fillcolour} parameter to \cw{draw_circle()} and
 \cw{draw_polygon()}, and as the colour parameter to
 \cw{draw_rect()}, but may not be used as the \c{outlinecolour}
 parameter to \cw{draw_circle()} or \cw{draw_polygon()}, or with
-\cw{draw_line()}.
+\cw{draw_line()} or \cw{draw_text()}.
+
+\S{print-rgb-mono-colour} \cw{print_rgb_mono_colour()}
+
+\c int print_rgb_mono_colour(drawing *dr, float r, float g,
+\c                           float b, float grey);
+
+This function allocates a colour index for a fully specified RGB
+colour during printing.
+
+\c{r}, \c{g} and \c{b} may each be anywhere in the range from 0 to 1.
+
+If printing in black and white only, these values will be ignored,
+and either pure black or pure white will be used instead, according
+to the \q{grey} parameter. (The fallback colour is the same as the
+one which would be allocated by \cw{print_mono_colour(grey)}.)
 
-\S{print-rgb-colour} \cw{print_rgb_colour()}
+\S{print-rgb-grey-colour} \cw{print_rgb_grey_colour()}
 
-\c int print_rgb_colour(drawing *dr, int hatch,
-\c                      float r, float g, float b);
+\c int print_rgb_grey_colour(drawing *dr, float r, float g,
+\c                           float b, float grey);
 
 This function allocates a colour index for a fully specified RGB
 colour during printing.
 
 \c{r}, \c{g} and \c{b} may each be anywhere in the range from 0 to 1.
 
-If printing in black and white only, these values will not be used;
-instead, regions shaded in this colour will be hatched with parallel
-lines. The \c{hatch} parameter defines what type of hatching should
-be used in place of this colour; see \k{print-grey-colour} for its
-definition.
+If printing in black and white only, these values will be ignored,
+and a shade of grey given by the \c{grey} parameter will be used
+instead. (The fallback colour is the same as the one which would be
+allocated by \cw{print_grey_colour(grey)}.)
+
+\S{print-rgb-hatched-colour} \cw{print_rgb_hatched_colour()}
+
+\c int print_rgb_hatched_colour(drawing *dr, float r, float g,
+\c                              float b, float hatched);
+
+This function allocates a colour index for a fully specified RGB
+colour during printing.
+
+\c{r}, \c{g} and \c{b} may each be anywhere in the range from 0 to 1.
+
+If printing in black and white only, these values will be ignored,
+and a form of cross-hatching given by the \c{hatch} parameter will
+be used instead; see \k{print-hatched-colour} for the possible
+values of this parameter. (The fallback colour is the same as the
+one which would be allocated by \cw{print_hatched_colour(hatch)}.)
 
 \S{print-line-width} \cw{print_line_width()}
 
@@ -2395,20 +2424,27 @@ the front end.
 
 \S{drawing-print-get-colour} \cw{print_get_colour()}
 
-\c void print_get_colour(drawing *dr, int colour, int *hatch,
-\c                       float *r, float *g, float *b)
+\c void print_get_colour(drawing *dr, int colour, int printincolour,
+\c                       int *hatch, float *r, float *g, float *b)
 
 This function is called by the implementations of the drawing API
 functions when they are called in a printing context. It takes a
 colour index as input, and returns the description of the colour as
 requested by the back end.
 
-\c{*r}, \c{*g} and \c{*b} are filled with the RGB values of the
-desired colour if printing in colour.
+\c{printincolour} is \cw{TRUE} iff the implementation is printing in
+colour. This will alter the results returned if the colour in
+question was specified with a black-and-white fallback value.
+
+If the colour should be rendered by hatching, \c{*hatch} is filled
+with the type of hatching desired. See \k{print-grey-colour} for
+details of the values this integer can take.
 
-\c{*hatch} is filled with the type of hatching (or not) desired if
-printing in black and white. See \k{print-grey-colour} for details
-of the values this integer can take.
+If the colour should be rendered as solid colour, \c{*hatch} is
+given a negative value, and \c{*r}, \c{*g} and \c{*b} are filled
+with the RGB values of the desired colour (if printing in colour),
+or all filled with the grey-scale value (if printing in black and
+white).
 
 \C{midend} The API provided by the mid-end
 
index 4204c4cf00196ef0ff7a65d5c13da1d0ffe080e8..9dbcea930ae33beb65d3f39e2e7e99aecbca02b6 100644 (file)
--- a/drawing.c
+++ b/drawing.c
@@ -33,7 +33,9 @@
 
 struct print_colour {
     int hatch;
+    int hatch_when;                   /* 0=never 1=only-in-b&w 2=always */
     float r, g, b;
+    float grey;
 };
 
 struct drawing {
@@ -199,17 +201,27 @@ void print_end_doc(drawing *dr)
     dr->api->end_doc(dr->handle);
 }
 
-void print_get_colour(drawing *dr, int colour, int *hatch,
-                     float *r, float *g, float *b)
+void print_get_colour(drawing *dr, int colour, int printing_in_colour,
+                     int *hatch, float *r, float *g, float *b)
 {
     assert(colour >= 0 && colour < dr->ncolours);
-    *hatch = dr->colours[colour].hatch;
-    *r = dr->colours[colour].r;
-    *g = dr->colours[colour].g;
-    *b = dr->colours[colour].b;
+    if (dr->colours[colour].hatch_when == 2 ||
+       (dr->colours[colour].hatch_when == 1 && !printing_in_colour)) {
+       *hatch = dr->colours[colour].hatch;
+    } else {
+       *hatch = -1;
+       if (printing_in_colour) {
+           *r = dr->colours[colour].r;
+           *g = dr->colours[colour].g;
+           *b = dr->colours[colour].b;
+       } else {
+           *r = *g = *b = dr->colours[colour].grey;
+       }
+    }
 }
 
-int print_rgb_colour(drawing *dr, int hatch, float r, float g, float b)
+static int print_generic_colour(drawing *dr, float r, float g, float b,
+                               float grey, int hatch, int hatch_when)
 {
     if (dr->ncolours >= dr->coloursize) {
        dr->coloursize = dr->ncolours + 16;
@@ -217,21 +229,42 @@ int print_rgb_colour(drawing *dr, int hatch, float r, float g, float b)
                              struct print_colour);
     }
     dr->colours[dr->ncolours].hatch = hatch;
+    dr->colours[dr->ncolours].hatch_when = hatch_when;
     dr->colours[dr->ncolours].r = r;
     dr->colours[dr->ncolours].g = g;
     dr->colours[dr->ncolours].b = b;
+    dr->colours[dr->ncolours].grey = grey;
     return dr->ncolours++;
 }
 
-int print_grey_colour(drawing *dr, int hatch, float grey)
+int print_mono_colour(drawing *dr, int grey)
 {
-    return print_rgb_colour(dr, hatch, grey, grey, grey);
+    return print_generic_colour(dr, grey, grey, grey, grey, -1, 0);
 }
 
-int print_mono_colour(drawing *dr, int grey)
+int print_grey_colour(drawing *dr, float grey)
+{
+    return print_generic_colour(dr, grey, grey, grey, grey, -1, 0);
+}
+
+int print_hatched_colour(drawing *dr, int hatch)
+{
+    return print_generic_colour(dr, 0, 0, 0, 0, hatch, 2);
+}
+
+int print_rgb_mono_colour(drawing *dr, float r, float g, float b, int grey)
+{
+    return print_generic_colour(dr, r, g, b, grey, -1, 0);
+}
+
+int print_rgb_grey_colour(drawing *dr, float r, float g, float b, float grey)
+{
+    return print_generic_colour(dr, r, g, b, grey, -1, 0);
+}
+
+int print_rgb_hatched_colour(drawing *dr, float r, float g, float b, int hatch)
 {
-    return print_rgb_colour(dr, grey ? HATCH_CLEAR : HATCH_SOLID,
-                           grey, grey, grey);
+    return print_generic_colour(dr, r, g, b, 0, hatch, 1);
 }
 
 void print_line_width(drawing *dr, int width)
index 5e75981f6eab8e57e48462b0827936cfd03a9711..45d183599135799f88923f0637a95c911225f312 100644 (file)
@@ -3252,9 +3252,9 @@ static void game_print(drawing *dr, game_state *state, int sz)
     game_drawstate ads, *ds = &ads;
     ds->tilesize = sz;
 
-    white = print_grey_colour(dr, HATCH_CLEAR, 1.0F);
-    black = print_grey_colour(dr, HATCH_SOLID, 0.0F);
-    blackish = print_grey_colour(dr, HATCH_X, 0.5F);
+    white = print_mono_colour(dr, 1);
+    black = print_mono_colour(dr, 0);
+    blackish = print_hatched_colour(dr, HATCH_X);
 
     /*
      * Get the completion information.
diff --git a/map.c b/map.c
index da3c4bacb2dd013fc377905e033b5e5a34847a87..4e9bdd616491933d677090d780282c634e961a3e 100644 (file)
--- a/map.c
+++ b/map.c
@@ -2977,8 +2977,9 @@ static void game_print(drawing *dr, game_state *state, int tilesize)
 
     ink = print_mono_colour(dr, 0);
     for (i = 0; i < FOUR; i++)
-       c[i] = print_rgb_colour(dr, map_hatching[i], map_colours[i][0],
-                               map_colours[i][1], map_colours[i][2]);
+       c[i] = print_rgb_hatched_colour(dr, map_colours[i][0],
+                                       map_colours[i][1], map_colours[i][2],
+                                       map_hatching[i]);
 
     coordsize = 0;
     coords = NULL;
index cdca93a4478b5689cb3491623868261397389b20..2ecd238ffdd792d901ea05c3ffa9ab853bf60c38 100644 (file)
--- a/nullfe.c
+++ b/nullfe.c
@@ -27,8 +27,13 @@ void blitter_free(drawing *dr, blitter *bl) {}
 void blitter_save(drawing *dr, blitter *bl, int x, int y) {}
 void blitter_load(drawing *dr, blitter *bl, int x, int y) {}
 int print_mono_colour(drawing *dr, int grey) { return 0; }
-int print_grey_colour(drawing *dr, int hatch, float grey) { return 0; }
-int print_rgb_colour(drawing *dr, int hatch, float r, float g, float b)
+int print_grey_colour(drawing *dr, float grey) { return 0; }
+int print_hatched_colour(drawing *dr, int hatch) { return 0; }
+int print_rgb_mono_colour(drawing *dr, float r, float g, float b, int grey)
+{ return 0; }
+int print_rgb_grey_colour(drawing *dr, float r, float g, float b, float grey)
+{ return 0; }
+int print_rgb_hatched_colour(drawing *dr, float r, float g, float b, int hatch)
 { return 0; }
 void print_line_width(drawing *dr, int width) {}
 void midend_supersede_game_desc(midend *me, char *desc, char *privdesc) {}
diff --git a/ps.c b/ps.c
index a1f21d6e92877896a0da350e73f0caf18ce7b8ca..9f2c17f0e5bb02d075da5ccb0c29a8c06753361c 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)
index ba8c4f591e2260c595c17d656cde730c4d5b0877..11acb1f206ddca99817cee6f981913b51827a1e7 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -110,14 +110,12 @@ typedef struct psdata psdata;
 #define FONT_VARIABLE 1
 
 /* For printing colours */
-#define HATCH_SOLID 0
-#define HATCH_CLEAR 1
-#define HATCH_SLASH 2
-#define HATCH_BACKSLASH 3
-#define HATCH_HORIZ 4
-#define HATCH_VERT 5
-#define HATCH_PLUS 6
-#define HATCH_X 7
+#define HATCH_SLASH     1
+#define HATCH_BACKSLASH 2
+#define HATCH_HORIZ     3
+#define HATCH_VERT      4
+#define HATCH_PLUS      5
+#define HATCH_X         6
 
 /*
  * Structure used to pass configuration data between frontend and
@@ -205,11 +203,15 @@ void print_begin_puzzle(drawing *dr, float xm, float xc,
 void print_end_puzzle(drawing *dr);
 void print_end_page(drawing *dr, int number);
 void print_end_doc(drawing *dr);
-void print_get_colour(drawing *dr, int colour, int *hatch,
-                     float *r, float *g, float *b);
+void print_get_colour(drawing *dr, int colour, int printing_in_colour,
+                     int *hatch, float *r, float *g, float *b);
 int print_mono_colour(drawing *dr, int grey); /* 0==black, 1==white */
-int print_grey_colour(drawing *dr, int hatch, float grey);
-int print_rgb_colour(drawing *dr, int hatch, float r, float g, float b);
+int print_grey_colour(drawing *dr, float grey);
+int print_hatched_colour(drawing *dr, int hatch);
+int print_rgb_mono_colour(drawing *dr, float r, float g, float b, float mono);
+int print_rgb_grey_colour(drawing *dr, float r, float g, float b, float grey);
+int print_rgb_hatched_colour(drawing *dr, float r, float g, float b,
+                            int hatch);
 void print_line_width(drawing *dr, int width);
 
 /*
diff --git a/solo.c b/solo.c
index bac51aabdd1c0467d6a516e13dad7fb3750b7e9b..7b168e58a8f7169c79a1d14a1860ddd0af29f6bf 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -3719,7 +3719,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize)
      */
     if (state->xtype) {
        int i;
-       int xhighlight = print_grey_colour(dr, HATCH_SLASH, 0.90F);
+       int xhighlight = print_grey_colour(dr, 0.90F);
 
        for (i = 0; i < cr; i++)
            draw_rect(dr, BORDER + i*TILE_SIZE, BORDER + i*TILE_SIZE,
index 3c2c2f1009fb773299b1900ac8ac068aeb46c2ad..32c3322bf4a75a1e7e79f8a8b1d45dd4a08ab8ca 100644 (file)
--- a/windows.c
+++ b/windows.c
@@ -398,12 +398,14 @@ static void win_text_colour(frontend *fe, int colour)
     if (fe->drawstatus == PRINTING) {
        int hatch;
        float r, g, b;
-       print_get_colour(fe->dr, colour, &hatch, &r, &g, &b);
-       if (fe->printcolour)
-           SetTextColor(fe->hdc, RGB(r * 255, g * 255, b * 255));
-       else
-           SetTextColor(fe->hdc,
-                        hatch == HATCH_CLEAR ? RGB(255,255,255) : RGB(0,0,0));
+       print_get_colour(fe->dr, colour, fe->printcolour, &hatch, &r, &g, &b);
+
+       /*
+        * Displaying text in hatched colours is not permitted.
+        */
+       assert(hatch < 0);
+
+       SetTextColor(fe->hdc, RGB(r * 255, g * 255, b * 255));
     } else {
        SetTextColor(fe->hdc, fe->colours[colour]);
     }
@@ -417,14 +419,10 @@ static void win_set_brush(frontend *fe, int colour)
     if (fe->drawstatus == PRINTING) {
        int hatch;
        float r, g, b;
-       print_get_colour(fe->dr, colour, &hatch, &r, &g, &b);
+       print_get_colour(fe->dr, colour, fe->printcolour, &hatch, &r, &g, &b);
 
-       if (fe->printcolour) {
+       if (hatch < 0) {
            br = CreateSolidBrush(RGB(r * 255, g * 255, b * 255));
-       } else if (hatch == HATCH_SOLID) {
-           br = CreateSolidBrush(RGB(0,0,0));
-       } else if (hatch == HATCH_CLEAR) {
-           br = CreateSolidBrush(RGB(255,255,255));
        } else {
 #ifdef _WIN32_WCE
            /*
@@ -469,18 +467,12 @@ static void win_set_pen(frontend *fe, int colour, int thin)
        float r, g, b;
        int width = thin ? 0 : fe->linewidth;
 
-       print_get_colour(fe->dr, colour, &hatch, &r, &g, &b);
-       if (fe->printcolour)
-           pen = CreatePen(PS_SOLID, width,
-                           RGB(r * 255, g * 255, b * 255));
-       else if (hatch == HATCH_SOLID)
-           pen = CreatePen(PS_SOLID, width, RGB(0, 0, 0));
-       else if (hatch == HATCH_CLEAR)
-           pen = CreatePen(PS_SOLID, width, RGB(255,255,255));
-       else {
-           assert(!"This shouldn't happen");
-           pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
-       }
+       print_get_colour(fe->dr, colour, fe->printcolour, &hatch, &r, &g, &b);
+       /*
+        * Stroking in hatched colours is not permitted.
+        */
+       assert(hatch < 0);
+       pen = CreatePen(PS_SOLID, width, RGB(r * 255, g * 255, b * 255));
     } else {
        pen = fe->pens[colour];
     }