/* * draw a line between two given points in the current color. * * Called by: * Cont_abs() in ../lib/Cont_abs.c */ #include #include #include "pngdriver.h" static void store_xy(double x, double y) { int xi = (int) floor(x); int yi = (int) floor(y); if (x < png.clip_left || x >= png.clip_rite || y < png.clip_top || y >= png.clip_bot) return; png.grid[yi * png.width + xi] = png.current_color; } static void swap(double *a, double *b) { double t = *a; *a = *b; *b = t; } static void draw_line(double x1, double y1, double x2, double y2) { double x, y; double dx, dy; if (fabs(y1 - y2) > fabs(x1 - x2)) { if (y1 > y2) { swap(&y1, &y2); swap(&x1, &x2); } dy = y2 - y1; dx = x2 - x1; for (y = floor(y1) + 0.5; y < y2; y++) { x = x1 + (y - y1) * dx / dy; store_xy(x, y); } } else { if (x1 > x2) { swap(&x1, &x2); swap(&y1, &y2); } dx = x2 - x1; dy = y2 - y1; for (x = floor(x1) + 0.5; x < x2; x++) { y = y1 + (x - x1) * dy / dx; store_xy(x, y); } } } void png_draw_line(double x1, double y1, double x2, double y2) { struct path path; struct vertex vertices[5]; double k = png.linewidth / 2; int dx, dy; if (png.linewidth <= 1) { draw_line(x1, y1, x2, y2); png.modified = 1; return; } path.vertices = vertices; path.count = 0; path.alloc = 5; path.start = -1; if (dy > dx) { path_move(&path, x1 - k, y1); path_cont(&path, x1 + k, y1); path_cont(&path, x2 + k, y2); path_cont(&path, x2 - k, y2); path_close(&path); } else { path_move(&path, x1, y1 - k); path_cont(&path, x1, y1 + k); path_cont(&path, x2, y2 + k); path_cont(&path, x2, y2 - k); path_close(&path); } png_polygon(&path); }