mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 02:16:19 +03:00
Rewrite of the ImagingDrawWideLine function
The previous version of the function didn't generate correct wide lines of even width. The most notable changes are: * Make variable names far more descriptive about the process. * Corrected the width calculation; we should deduct one pixel from the width because the pixels at the center of the line doesn't count for the triangles. * Now we calculate *two* ratios, one for left/top displacement (dxmin) and one for right/bottom (dxmax), this fix the behavior with lines of even width. It can probably be optimized.
This commit is contained in:
parent
cd332fc38a
commit
be09da6507
|
@ -588,11 +588,6 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
DRAW* draw;
|
DRAW* draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
|
|
||||||
Edge e[4];
|
|
||||||
|
|
||||||
int dx, dy;
|
|
||||||
double d;
|
|
||||||
|
|
||||||
DRAWINIT();
|
DRAWINIT();
|
||||||
|
|
||||||
if (width <= 1) {
|
if (width <= 1) {
|
||||||
|
@ -600,23 +595,34 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = x1-x0;
|
int dx = x1-x0;
|
||||||
dy = y1-y0;
|
int dy = y1-y0;
|
||||||
|
|
||||||
if (dx == 0 && dy == 0) {
|
if (dx == 0 && dy == 0) {
|
||||||
draw->point(im, x0, y0, ink);
|
draw->point(im, x0, y0, ink);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = width / sqrt((float) (dx*dx + dy*dy)) / 2.0;
|
double big_hypotenuse = sqrt((double) (dx*dx + dy*dy));
|
||||||
|
double small_hypotenuse = (width - 1) / 2.0;
|
||||||
|
double ratio_max = ROUND_UP(small_hypotenuse) / big_hypotenuse;
|
||||||
|
double ratio_min = ROUND_DOWN(small_hypotenuse) / big_hypotenuse;
|
||||||
|
|
||||||
dx = (int) floor(d * (y1-y0) + 0.5);
|
int dxmin = ROUND_DOWN(ratio_min * dy);
|
||||||
dy = (int) floor(d * (x1-x0) + 0.5);
|
int dxmax = ROUND_DOWN(ratio_max * dy);
|
||||||
|
int dymin = ROUND_DOWN(ratio_min * dx);
|
||||||
|
int dymax = ROUND_DOWN(ratio_max * dx);
|
||||||
|
int vertices[4][2] = {
|
||||||
|
{x0 - dxmin, y0 + dymax},
|
||||||
|
{x1 - dxmin, y1 + dymax},
|
||||||
|
{x1 + dxmax, y1 - dymin},
|
||||||
|
{x0 + dxmax, y0 - dymin}
|
||||||
|
};
|
||||||
|
|
||||||
add_edge(e+0, x0 - dx, y0 + dy, x1 - dx, y1 + dy);
|
Edge e[4];
|
||||||
add_edge(e+1, x1 - dx, y1 + dy, x1 + dx, y1 - dy);
|
add_edge(e+0, vertices[0][0], vertices[0][1], vertices[1][0], vertices[1][1]);
|
||||||
add_edge(e+2, x1 + dx, y1 - dy, x0 + dx, y0 - dy);
|
add_edge(e+1, vertices[1][0], vertices[1][1], vertices[2][0], vertices[2][1]);
|
||||||
add_edge(e+3, x0 + dx, y0 - dy, x0 - dx, y0 + dy);
|
add_edge(e+2, vertices[2][0], vertices[2][1], vertices[3][0], vertices[3][1]);
|
||||||
|
add_edge(e+3, vertices[3][0], vertices[3][1], vertices[0][0], vertices[0][1]);
|
||||||
|
|
||||||
draw->polygon(im, 4, e, ink, 0);
|
draw->polygon(im, 4, e, ink, 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user