Fixed tests

This commit is contained in:
Stanislau Tsitsianok 2020-06-29 22:49:11 +03:00
parent 96f69eb287
commit 9a9d3a050a
No known key found for this signature in database
GPG Key ID: 349CB26B2ED6E0C0
19 changed files with 97 additions and 51 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 B

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 405 B

View File

@ -196,13 +196,11 @@ def helper_chord(mode, bbox, start, end):
def test_chord1(): def test_chord1():
for mode in ["RGB", "L"]: for mode in ["RGB", "L"]:
helper_chord(mode, BBOX1, 0, 180) helper_chord(mode, BBOX1, 0, 180)
helper_chord(mode, BBOX1, 0.5, 180.4)
def test_chord2(): def test_chord2():
for mode in ["RGB", "L"]: for mode in ["RGB", "L"]:
helper_chord(mode, BBOX2, 0, 180) helper_chord(mode, BBOX2, 0, 180)
helper_chord(mode, BBOX2, 0.5, 180.4)
def test_chord_width(): def test_chord_width():
@ -465,13 +463,13 @@ def helper_pieslice(bbox, start, end):
def test_pieslice1(): def test_pieslice1():
helper_pieslice(BBOX1, -90, 45) helper_pieslice(BBOX1, -92, 46)
helper_pieslice(BBOX1, -90.5, 45.4) helper_pieslice(BBOX1, -92.2, 46.2)
def test_pieslice2(): def test_pieslice2():
helper_pieslice(BBOX2, -90, 45) helper_pieslice(BBOX2, -92, 46)
helper_pieslice(BBOX2, -90.5, 45.4) helper_pieslice(BBOX2, -92.2, 46.2)
def test_pieslice_width(): def test_pieslice_width():

View File

@ -119,7 +119,7 @@ class ImageDraw:
fill = self.draw.draw_ink(fill) fill = self.draw.draw_ink(fill)
return ink, fill return ink, fill
def arc(self, xy, start, end, fill=None, width=0): def arc(self, xy, start, end, fill=None, width=1):
"""Draw an arc.""" """Draw an arc."""
ink, fill = self._getink(fill) ink, fill = self._getink(fill)
if ink is not None: if ink is not None:

View File

@ -1150,6 +1150,30 @@ typedef struct {
typedef void (*clip_ellipse_init)(clip_ellipse_state*, int32_t, int32_t, int32_t, float, float); typedef void (*clip_ellipse_init)(clip_ellipse_state*, int32_t, int32_t, int32_t, float, float);
void debug_clip_tree(clip_node* root, int space) {
if (root == NULL) {
return;
}
if (root->type == CT_CLIP) {
int t = space;
while (t--) {
fputc(' ', stderr);
}
fprintf(stderr, "clip %+fx%+fy%+f > 0\n", root->a, root->b, root->c);
} else {
debug_clip_tree(root->l, space + 2);
int t = space;
while (t--) {
fputc(' ', stderr);
}
fprintf(stderr, "%s\n", root->type == CT_AND ? "and" : "or");
debug_clip_tree(root->r, space + 2);
}
if (space == 0) {
fputc('\n', stderr);
}
}
// Resulting angles will satisfy 0 <= al < 360, al <= ar <= al + 360 // Resulting angles will satisfy 0 <= al < 360, al <= ar <= al + 360
void normalize_angles(float* al, float* ar) { void normalize_angles(float* al, float* ar) {
if (*ar - *al >= 360) { if (*ar - *al >= 360) {
@ -1162,10 +1186,10 @@ void normalize_angles(float* al, float* ar) {
} }
// An arc with caps orthogonal to the ellipse curve. // An arc with caps orthogonal to the ellipse curve.
void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float _al, float _ar) { void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) {
if (a < b) { if (a < b) {
// transpose the coordinate system // transpose the coordinate system
arc_init(s, b, a, w, 90 - _ar, 90 - _al); arc_init(s, b, a, w, 90 - ar, 90 - al);
ellipse_init(&s->st, a, b, w); ellipse_init(&s->st, a, b, w);
clip_tree_transpose(s->root); clip_tree_transpose(s->root);
} else { } else {
@ -1175,8 +1199,6 @@ void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float _al,
s->head = NULL; s->head = NULL;
s->node_count = 0; s->node_count = 0;
int32_t al = round(_al), ar = round(_ar);
// building clipping tree, a lot of different cases // building clipping tree, a lot of different cases
if (ar == al + 360) { if (ar == al + 360) {
s->root = NULL; s->root = NULL;
@ -1191,25 +1213,12 @@ void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float _al,
rc->a = a * sin(ar * M_PI / 180.0); rc->a = a * sin(ar * M_PI / 180.0);
rc->b = -b * cos(ar * M_PI / 180.0); rc->b = -b * cos(ar * M_PI / 180.0);
rc->c = (b * b - a * a) * sin(ar * M_PI / 90.0) / 2.0; rc->c = (b * b - a * a) * sin(ar * M_PI / 90.0) / 2.0;
if (al % 180 == 0 || ar % 180 == 0 || al == ar) { if (fmod(al, 180) == 0 || fmod(ar, 180) == 0) {
s->root = s->nodes + s->node_count++; s->root = s->nodes + s->node_count++;
s->root->l = lc; s->root->l = lc;
s->root->r = rc; s->root->r = rc;
s->root->type = ar - al < 180 ? CT_AND : CT_OR; s->root->type = ar - al < 180 ? CT_AND : CT_OR;
if (al == ar) { } else if (((int)(al / 180) + (int)(ar / 180)) % 2 == 1) {
lc = s->nodes + s->node_count++;
lc->l = lc->r = NULL;
lc->type = CT_CLIP;
lc->a = al == 0 ? 1 : al == 180 ? -1 : 0;
lc->b = al % 180 ? (al < 180 ? 1 : -1) : 0;
lc->c = 0;
rc = s->root;
s->root = s->nodes + s->node_count++;
s->root->l = lc;
s->root->r = rc;
s->root->type = CT_AND;
}
} else if ((al / 180 + ar / 180) % 2 == 1) {
s->root = s->nodes + s->node_count++; s->root = s->nodes + s->node_count++;
s->root->l = s->nodes + s->node_count++; s->root->l = s->nodes + s->node_count++;
s->root->l->l = s->nodes + s->node_count++; s->root->l->l = s->nodes + s->node_count++;
@ -1226,8 +1235,8 @@ void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float _al,
s->root->r->l->l = s->root->r->l->r = NULL; s->root->r->l->l = s->root->r->l->r = NULL;
s->root->l->l->a = s->root->l->l->c = 0; s->root->l->l->a = s->root->l->l->c = 0;
s->root->r->l->a = s->root->r->l->c = 0; s->root->r->l->a = s->root->r->l->c = 0;
s->root->l->l->b = (al / 180) % 2 == 0 ? 1 : -1; s->root->l->l->b = (int)(al / 180) % 2 == 0 ? 1 : -1;
s->root->r->l->b = (ar / 180) % 2 == 0 ? 1 : -1; s->root->r->l->b = (int)(ar / 180) % 2 == 0 ? 1 : -1;
} else { } else {
s->root = s->nodes + s->node_count++; s->root = s->nodes + s->node_count++;
s->root->l = s->nodes + s->node_count++; s->root->l = s->nodes + s->node_count++;
@ -1268,6 +1277,48 @@ void chord_line_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, flo
s->root->r->c = 2 * w * sqrt(pow(s->root->l->a, 2.0) + pow(s->root->l->b, 2.0)) - s->root->l->c; s->root->r->c = 2 * w * sqrt(pow(s->root->l->a, 2.0) + pow(s->root->l->b, 2.0)) - s->root->l->c;
} }
// Pie side.
void pie_side_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float _) {
ellipse_init(&s->st, a, b, a + b + 1);
s->head = NULL;
s->node_count = 0;
double xl = a * cos(al * M_PI / 180.0);
double yl = b * sin(al * M_PI / 180.0);
double a1 = -yl;
double b1 = xl;
double c1 = w * sqrt(a1 * a1 + b1 * b1);
s->root = s->nodes + s->node_count++;
s->root->type = CT_AND;
s->root->l = s->nodes + s->node_count++;
s->root->l->type = CT_AND;
clip_node* cnode;
cnode = s->nodes + s->node_count++;
cnode->l = cnode->r = NULL;
cnode->type = CT_CLIP;
cnode->a = a1;
cnode->b = b1;
cnode->c = c1;
s->root->l->l = cnode;
cnode = s->nodes + s->node_count++;
cnode->l = cnode->r = NULL;
cnode->type = CT_CLIP;
cnode->a = -a1;
cnode->b = -b1;
cnode->c = c1;
s->root->l->r = cnode;
cnode = s->nodes + s->node_count++;
cnode->l = cnode->r = NULL;
cnode->type = CT_CLIP;
cnode->a = b1;
cnode->b = -a1;
cnode->c = 0;
s->root->r = cnode;
}
// A chord. // A chord.
void chord_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) { void chord_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) {
ellipse_init(&s->st, a, b, w); ellipse_init(&s->st, a, b, w);
@ -1384,12 +1435,13 @@ clipEllipseNew(Imaging im, int x0, int y0, int x1, int y1,
int a = x1 - x0; int a = x1 - x0;
int b = y1 - y0; int b = y1 - y0;
if (a < 0 || b < 0 || start == end) { if (a < 0 || b < 0) {
return 0; return 0;
} }
clip_ellipse_state st; clip_ellipse_state st;
init(&st, a, b, width, start, end); init(&st, a, b, width, start, end);
// debug_clip_tree(st.root, 0);
int32_t X0, Y, X1; int32_t X0, Y, X1;
int next_code; int next_code;
while ((next_code = clip_ellipse_next(&st, &X0, &Y, &X1)) >= 0) { while ((next_code = clip_ellipse_next(&st, &X0, &Y, &X1)) >= 0) {
@ -1425,9 +1477,17 @@ chordLineNew(Imaging im, int x0, int y0, int x1, int y1,
static int static int
pieNew(Imaging im, int x0, int y0, int x1, int y1, pieNew(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, float start, float end,
const void* ink_, int op) const void* ink_, int width, int op)
{ {
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, x1 + y1 - x0 - y0, op, pie_init); return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, pie_init);
}
static int
pieSideNew(Imaging im, int x0, int y0, int x1, int y1,
float start,
const void* ink_, int width, int op)
{
return clipEllipseNew(im, x0, y0, x1, y1, start, 0, ink_, width, op, pie_side_init);
} }
int int
@ -1483,38 +1543,26 @@ ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int fill, float start, float end, const void* ink, int fill,
int width, int op) int width, int op)
{ {
//fprintf(stderr, "P (%d %d) (%d %d) %f-%f %08X f%d w%d o%d\n", x0, y0, x1, y1, start, end, *(int*)ink, fill, width, op); // fprintf(stderr, "P (%d %d) (%d %d) %f-%f %08X f%d w%d o%d\n", x0, y0, x1, y1, start, end, *(int*)ink, fill, width, op);
normalize_angles(&start, &end); normalize_angles(&start, &end);
if (start + 360 == end) { if (start + 360 == end) {
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, fill, width, op); return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
} }
if (start == end) { if (start == end) {
return 0; return 0;
} }
if (fill) { if (fill) {
return pieNew(im, x0, y0, x1, y1, start, end, ink, op); return pieNew(im, x0, y0, x1, y1, start, end, ink, x1 + y1 - x0 - y0, op);
} else { } else {
float xc = x0 + (x1 - x0) / 2.0, yc = y0 + (y1 - y0) / 2.0; if (pieSideNew(im, x0, y0, x1, y1, start, ink, width, op)) {
float al = start * M_PI / 180.0, ar = end * M_PI / 180.0;
int32_t xa = xc + (x1 - x0 - width) * cos(al) / 2, ya = yc + (y1 - y0 - width) * sin(al) / 2;
int32_t xb = xc + (x1 - x0 - width) * cos(ar) / 2, yb = yc + (y1 - y0 - width) * sin(ar) / 2;
int32_t xt, yt;
if (ImagingDrawWideLine(im, xc, yc, xa, ya, ink, width, op) < 0) {
return -1; return -1;
} }
if (ImagingDrawWideLine(im, xc, yc, xb, yb, ink, width, op) < 0) { if (pieSideNew(im, x0, y0, x1, y1, end, ink, width, op)) {
return -1; return -1;
} }
xt = xc - width / 2; float xc = round((x0 + x1 - width) / 2.0), yc = round((y0 + y1 - width) / 2.0);
yt = yc - width / 2; ellipseNew(im, xc, yc, xc + width - 1, yc + width - 1, ink, 1, 0, op);
ellipseNew(im, xt, yt, xt + width, yt + width, ink, 1, 0, op); return pieNew(im, x0, y0, x1, y1, start, end, ink, width, op);
xt = xa - width / 2;
yt = ya - width / 2;
ellipseNew(im, xt, yt, xt + width, yt + width, ink, 1, 0, op);
xt = xb - width / 2;
yt = yb - width / 2;
ellipseNew(im, xt, yt, xt + width, yt + width, ink, 1, 0, op);
return arcNew(im, x0, y0, x1, y1, start, end, ink, width, op);
} }
} }