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,
int fillcolour, int outlinecolour)
{
# define USE_CAIRO
#endif
+/* #undef USE_CAIRO */
+/* #define NO_THICK_LINE */
#ifdef DEBUGGING
static FILE *debug_fp = NULL;
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,
int fillcolour, int outlinecolour)
{
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,
int fillcolour, int outlinecolour)
{
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,
int fillcolour, int outlinecolour)
{
#else
NULL,
#endif
+#ifdef NO_THICK_LINE
+ NULL,
+#else
+ gtk_draw_thick_line,
+#endif
};
static void destroy(GtkWidget *widget, gpointer data)
if (draw_faint_lines)
draw_line(dr, x1, y1, x2, y2, line_colour);
} else {
- /* (dx, dy) points roughly from (x1, y1) to (x2, y2).
- * The line is then "fattened" in a (roughly) perpendicular
- * direction to create a thin rectangle. */
- int dx = (x1 > x2) ? -1 : ((x1 < x2) ? 1 : 0);
- 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);
+ draw_thick_line(dr, 3.0,
+ x1 + 0.5, y1 + 0.5,
+ x2 + 0.5, y2 + 0.5,
+ line_colour);
}
if (ds->started) {
/* Draw dots at ends of the line */
return ret;
}
-static void draw_thick_line(drawing *dr, int x1, int y1, int x2, int y2,
- int colour)
+static void draw_filled_line(drawing *dr, int x1, int y1, int x2, int y2,
+ int colour)
{
draw_line(dr, x1-1, y1, x2-1, y2, COL_WIRE);
draw_line(dr, x1+1, y1, x2+1, y2, COL_WIRE);
ex = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * X(dir);
ey = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * Y(dir);
MATMUL(tx, ty, matrix, ex, ey);
- draw_thick_line(dr, bx+(int)cx, by+(int)cy,
- bx+(int)(cx+tx), by+(int)(cy+ty),
- COL_WIRE);
+ draw_filled_line(dr, bx+(int)cx, by+(int)cy,
+ bx+(int)(cx+tx), by+(int)(cy+ty),
+ COL_WIRE);
}
}
for (dir = 1; dir < 0x10; dir <<= 1) {
return ret;
}
-static void draw_thick_line(drawing *dr, int x1, int y1, int x2, int y2,
- int colour)
+static void draw_filled_line(drawing *dr, int x1, int y1, int x2, int y2,
+ int colour)
{
draw_line(dr, x1-1, y1, x2-1, y2, COL_WIRE);
draw_line(dr, x1+1, y1, x2+1, y2, COL_WIRE);
if (tile & dir) {
ex = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * X(dir);
ey = (TILE_SIZE - TILE_BORDER - 1.0F) / 2.0F * Y(dir);
- draw_thick_line(dr, bx+(int)cx, by+(int)cy,
- bx+(int)(cx+ex), by+(int)(cy+ey),
- COL_WIRE);
+ draw_filled_line(dr, bx+(int)cx, by+(int)cy,
+ bx+(int)(cx+ex), by+(int)(cy+ey),
+ COL_WIRE);
}
}
for (dir = 1; dir < 0x10; dir <<= 1) {
int align, int colour, char *text) {}
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_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,
int fillcolour, int outlinecolour) {}
void draw_circle(drawing *dr, int cx, int cy, int radius,
int fillcolour, int outlinecolour);
void draw_circle(drawing *dr, int cx, int cy, int radius,
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 unclip(drawing *dr);
void start_draw(drawing *dr);
void (*line_dotted)(void *handle, int dotted);
char *(*text_fallback)(void *handle, const char *const *strings,
int nstrings);
+ void (*draw_thick_line)(void *handle, float thickness,
+ float x1, float y1, float x2, float y2,
+ int colour);
};
/*