From 60aa1c7413ef8ba2c4889628170f00bf180039f0 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 7 Apr 2008 17:13:29 +0000 Subject: [PATCH] Revise the printing colour framework so that we can explicitly request either of hatching or halftoning, and also choose which to supply as a fallback when printing in colour. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@7976 cda61777-01e9-0310-a592-d414129be87e --- devel.but | 94 +++++++++++++++++++++++++++++++++++++++++++------------------- drawing.c | 57 +++++++++++++++++++++++++++++-------- galaxies.c | 6 ++-- map.c | 5 ++-- nullfe.c | 9 ++++-- ps.c | 34 +++++++++++------------ puzzles.h | 26 +++++++++-------- solo.c | 2 +- windows.c | 40 +++++++++++--------------- 9 files changed, 170 insertions(+), 103 deletions(-) diff --git a/devel.but b/devel.but index cf06656..1df57cf 100644 --- 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 diff --git a/drawing.c b/drawing.c index 4204c4c..9dbcea9 100644 --- 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) diff --git a/galaxies.c b/galaxies.c index 5e75981..45d1835 100644 --- a/galaxies.c +++ b/galaxies.c @@ -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 da3c4ba..4e9bdd6 100644 --- 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; diff --git a/nullfe.c b/nullfe.c index cdca93a..2ecd238 100644 --- 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 a1f21d6..9f2c17f 100644 --- 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) diff --git a/puzzles.h b/puzzles.h index ba8c4f5..11acb1f 100644 --- 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 bac51aa..7b168e5 100644 --- 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, diff --git a/windows.c b/windows.c index 3c2c2f1..32c3322 100644 --- 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]; } -- 2.11.0