mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Patch from Mark Wooding to introduce a draw_thick_line() function in
the drawing API, for use by Loopy. It's optional: drawing.c will construct an acceptable alternative using a filled polygon if the front end doesn't provide it. Net and Netslide previously had static functions called draw_thick_line(), whose claim to the name is less justified and so they've been renamed. [originally from svn r8962]
This commit is contained in:
28
drawing.c
28
drawing.c
@ -87,6 +87,34 @@ void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour)
|
|||||||
dr->api->draw_line(dr->handle, x1, y1, x2, y2, colour);
|
dr->api->draw_line(dr->handle, x1, y1, x2, y2, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_thick_line(drawing *dr, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2, int colour)
|
||||||
|
{
|
||||||
|
if (dr->api->draw_thick_line) {
|
||||||
|
dr->api->draw_thick_line(dr->handle, thickness,
|
||||||
|
x1, y1, x2, y2, colour);
|
||||||
|
} else {
|
||||||
|
/* We'll fake it up with a filled polygon. The tweak to the
|
||||||
|
* thickness empirically compensates for rounding errors, because
|
||||||
|
* polygon rendering uses integer coordinates.
|
||||||
|
*/
|
||||||
|
float len = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
|
||||||
|
float tvhatx = (x2 - x1)/len * (thickness/2 - 0.2);
|
||||||
|
float tvhaty = (y2 - y1)/len * (thickness/2 - 0.2);
|
||||||
|
int p[8];
|
||||||
|
|
||||||
|
p[0] = x1 - tvhaty;
|
||||||
|
p[1] = y1 + tvhatx;
|
||||||
|
p[2] = x2 - tvhaty;
|
||||||
|
p[3] = y2 + tvhatx;
|
||||||
|
p[4] = x2 + tvhaty;
|
||||||
|
p[5] = y2 - tvhatx;
|
||||||
|
p[6] = x1 + tvhaty;
|
||||||
|
p[7] = y1 - tvhatx;
|
||||||
|
dr->api->draw_polygon(dr->handle, p, 4, colour, colour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void draw_polygon(drawing *dr, int *coords, int npoints,
|
void draw_polygon(drawing *dr, int *coords, int npoints,
|
||||||
int fillcolour, int outlinecolour)
|
int fillcolour, int outlinecolour)
|
||||||
{
|
{
|
||||||
|
46
gtk.c
46
gtk.c
@ -40,6 +40,8 @@
|
|||||||
# define USE_CAIRO
|
# define USE_CAIRO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* #undef USE_CAIRO */
|
||||||
|
/* #define NO_THICK_LINE */
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
static FILE *debug_fp = NULL;
|
static FILE *debug_fp = NULL;
|
||||||
|
|
||||||
@ -297,6 +299,18 @@ static void do_draw_line(frontend *fe, int x1, int y1, int x2, int y2)
|
|||||||
cairo_stroke(fe->cr);
|
cairo_stroke(fe->cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_draw_thick_line(frontend *fe, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2)
|
||||||
|
{
|
||||||
|
cairo_save(fe->cr);
|
||||||
|
cairo_set_line_width(fe->cr, thickness);
|
||||||
|
cairo_new_path(fe->cr);
|
||||||
|
cairo_move_to(fe->cr, x1, y1);
|
||||||
|
cairo_line_to(fe->cr, x2, y2);
|
||||||
|
cairo_stroke(fe->cr);
|
||||||
|
cairo_restore(fe->cr);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_draw_poly(frontend *fe, int *coords, int npoints,
|
static void do_draw_poly(frontend *fe, int *coords, int npoints,
|
||||||
int fillcolour, int outlinecolour)
|
int fillcolour, int outlinecolour)
|
||||||
{
|
{
|
||||||
@ -518,6 +532,25 @@ static void do_draw_line(frontend *fe, int x1, int y1, int x2, int y2)
|
|||||||
gdk_draw_line(fe->pixmap, fe->gc, x1, y1, x2, y2);
|
gdk_draw_line(fe->pixmap, fe->gc, x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_draw_thick_line(frontend *fe, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2)
|
||||||
|
{
|
||||||
|
GdkGCValues save;
|
||||||
|
|
||||||
|
gdk_gc_get_values(fe->gc, &save);
|
||||||
|
gdk_gc_set_line_attributes(fe->gc,
|
||||||
|
thickness,
|
||||||
|
GDK_LINE_SOLID,
|
||||||
|
GDK_CAP_BUTT,
|
||||||
|
GDK_JOIN_BEVEL);
|
||||||
|
gdk_draw_line(fe->pixmap, fe->gc, x1, y1, x2, y2);
|
||||||
|
gdk_gc_set_line_attributes(fe->gc,
|
||||||
|
save.line_width,
|
||||||
|
save.line_style,
|
||||||
|
save.cap_style,
|
||||||
|
save.join_style);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_draw_poly(frontend *fe, int *coords, int npoints,
|
static void do_draw_poly(frontend *fe, int *coords, int npoints,
|
||||||
int fillcolour, int outlinecolour)
|
int fillcolour, int outlinecolour)
|
||||||
{
|
{
|
||||||
@ -850,6 +883,14 @@ void gtk_draw_line(void *handle, int x1, int y1, int x2, int y2, int colour)
|
|||||||
do_draw_line(fe, x1, y1, x2, y2);
|
do_draw_line(fe, x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gtk_draw_thick_line(void *handle, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2, int colour)
|
||||||
|
{
|
||||||
|
frontend *fe = (frontend *)handle;
|
||||||
|
set_colour(fe, colour);
|
||||||
|
do_draw_thick_line(fe, thickness, x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
void gtk_draw_poly(void *handle, int *coords, int npoints,
|
void gtk_draw_poly(void *handle, int *coords, int npoints,
|
||||||
int fillcolour, int outlinecolour)
|
int fillcolour, int outlinecolour)
|
||||||
{
|
{
|
||||||
@ -955,6 +996,11 @@ const struct drawing_api gtk_drawing = {
|
|||||||
#else
|
#else
|
||||||
NULL,
|
NULL,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NO_THICK_LINE
|
||||||
|
NULL,
|
||||||
|
#else
|
||||||
|
gtk_draw_thick_line,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void destroy(GtkWidget *widget, gpointer data)
|
static void destroy(GtkWidget *widget, gpointer data)
|
||||||
|
19
loopy.c
19
loopy.c
@ -3543,21 +3543,10 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
if (draw_faint_lines)
|
if (draw_faint_lines)
|
||||||
draw_line(dr, x1, y1, x2, y2, line_colour);
|
draw_line(dr, x1, y1, x2, y2, line_colour);
|
||||||
} else {
|
} else {
|
||||||
/* (dx, dy) points roughly from (x1, y1) to (x2, y2).
|
draw_thick_line(dr, 3.0,
|
||||||
* The line is then "fattened" in a (roughly) perpendicular
|
x1 + 0.5, y1 + 0.5,
|
||||||
* direction to create a thin rectangle. */
|
x2 + 0.5, y2 + 0.5,
|
||||||
int dx = (x1 > x2) ? -1 : ((x1 < x2) ? 1 : 0);
|
line_colour);
|
||||||
int dy = (y1 > y2) ? -1 : ((y1 < y2) ? 1 : 0);
|
|
||||||
int points[8];
|
|
||||||
points[0] = x1 + dy;
|
|
||||||
points[1] = y1 - dx;
|
|
||||||
points[2] = x1 - dy;
|
|
||||||
points[3] = y1 + dx;
|
|
||||||
points[4] = x2 - dy;
|
|
||||||
points[5] = y2 + dx;
|
|
||||||
points[6] = x2 + dy;
|
|
||||||
points[7] = y2 - dx;
|
|
||||||
draw_polygon(dr, points, 4, line_colour, line_colour);
|
|
||||||
}
|
}
|
||||||
if (ds->started) {
|
if (ds->started) {
|
||||||
/* Draw dots at ends of the line */
|
/* Draw dots at ends of the line */
|
||||||
|
4
net.c
4
net.c
@ -2377,7 +2377,7 @@ static float *game_colours(frontend *fe, int *ncolours)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_thick_line(drawing *dr, int x1, int y1, int x2, int y2,
|
static void draw_filled_line(drawing *dr, int x1, int y1, int x2, int y2,
|
||||||
int colour)
|
int colour)
|
||||||
{
|
{
|
||||||
draw_line(dr, x1-1, y1, x2-1, y2, COL_WIRE);
|
draw_line(dr, x1-1, y1, x2-1, y2, COL_WIRE);
|
||||||
@ -2514,7 +2514,7 @@ static void draw_tile(drawing *dr, game_state *state, game_drawstate *ds,
|
|||||||
ex = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * X(dir);
|
ex = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * X(dir);
|
||||||
ey = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * Y(dir);
|
ey = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * Y(dir);
|
||||||
MATMUL(tx, ty, matrix, ex, ey);
|
MATMUL(tx, ty, matrix, ex, ey);
|
||||||
draw_thick_line(dr, bx+(int)cx, by+(int)cy,
|
draw_filled_line(dr, bx+(int)cx, by+(int)cy,
|
||||||
bx+(int)(cx+tx), by+(int)(cy+ty),
|
bx+(int)(cx+tx), by+(int)(cy+ty),
|
||||||
COL_WIRE);
|
COL_WIRE);
|
||||||
}
|
}
|
||||||
|
@ -1307,7 +1307,7 @@ static float *game_colours(frontend *fe, int *ncolours)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_thick_line(drawing *dr, int x1, int y1, int x2, int y2,
|
static void draw_filled_line(drawing *dr, int x1, int y1, int x2, int y2,
|
||||||
int colour)
|
int colour)
|
||||||
{
|
{
|
||||||
draw_line(dr, x1-1, y1, x2-1, y2, COL_WIRE);
|
draw_line(dr, x1-1, y1, x2-1, y2, COL_WIRE);
|
||||||
@ -1420,7 +1420,7 @@ static void draw_tile(drawing *dr, game_drawstate *ds, game_state *state,
|
|||||||
if (tile & dir) {
|
if (tile & dir) {
|
||||||
ex = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * X(dir);
|
ex = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * X(dir);
|
||||||
ey = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * Y(dir);
|
ey = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * Y(dir);
|
||||||
draw_thick_line(dr, bx+(int)cx, by+(int)cy,
|
draw_filled_line(dr, bx+(int)cx, by+(int)cy,
|
||||||
bx+(int)(cx+ex), by+(int)(cy+ey),
|
bx+(int)(cx+ex), by+(int)(cy+ey),
|
||||||
COL_WIRE);
|
COL_WIRE);
|
||||||
}
|
}
|
||||||
|
2
nullfe.c
2
nullfe.c
@ -13,6 +13,8 @@ void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
|
|||||||
int align, int colour, char *text) {}
|
int align, int colour, char *text) {}
|
||||||
void draw_rect(drawing *dr, int x, int y, int w, int h, int colour) {}
|
void draw_rect(drawing *dr, int x, int y, int w, int h, int colour) {}
|
||||||
void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour) {}
|
void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour) {}
|
||||||
|
void draw_thick_line(drawing *dr, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2, int colour) {}
|
||||||
void draw_polygon(drawing *dr, int *coords, int npoints,
|
void draw_polygon(drawing *dr, int *coords, int npoints,
|
||||||
int fillcolour, int outlinecolour) {}
|
int fillcolour, int outlinecolour) {}
|
||||||
void draw_circle(drawing *dr, int cx, int cy, int radius,
|
void draw_circle(drawing *dr, int cx, int cy, int radius,
|
||||||
|
@ -184,6 +184,8 @@ void draw_polygon(drawing *dr, int *coords, int npoints,
|
|||||||
int fillcolour, int outlinecolour);
|
int fillcolour, int outlinecolour);
|
||||||
void draw_circle(drawing *dr, int cx, int cy, int radius,
|
void draw_circle(drawing *dr, int cx, int cy, int radius,
|
||||||
int fillcolour, int outlinecolour);
|
int fillcolour, int outlinecolour);
|
||||||
|
void draw_thick_line(drawing *dr, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2, int colour);
|
||||||
void clip(drawing *dr, int x, int y, int w, int h);
|
void clip(drawing *dr, int x, int y, int w, int h);
|
||||||
void unclip(drawing *dr);
|
void unclip(drawing *dr);
|
||||||
void start_draw(drawing *dr);
|
void start_draw(drawing *dr);
|
||||||
@ -519,6 +521,9 @@ struct drawing_api {
|
|||||||
void (*line_dotted)(void *handle, int dotted);
|
void (*line_dotted)(void *handle, int dotted);
|
||||||
char *(*text_fallback)(void *handle, const char *const *strings,
|
char *(*text_fallback)(void *handle, const char *const *strings,
|
||||||
int nstrings);
|
int nstrings);
|
||||||
|
void (*draw_thick_line)(void *handle, float thickness,
|
||||||
|
float x1, float y1, float x2, float y2,
|
||||||
|
int colour);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user