diff --git a/src/modules/Image/polyfill.c b/src/modules/Image/polyfill.c index ddd8d238fb5d5dccbb23b11580dbb0844c36dd21..fce9f355f0e5cac804d546bd9b025010b228c978 100644 --- a/src/modules/Image/polyfill.c +++ b/src/modules/Image/polyfill.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: polyfill.c,v 1.23 1998/04/09 02:01:18 mirar Exp $"); +RCSID("$Id: polyfill.c,v 1.24 1998/04/19 19:14:23 mirar Exp $"); /* Prototypes are needed for these */ extern double floor(double); @@ -32,7 +32,7 @@ extern double floor(double); /* **! module Image **! note -**! $Id: polyfill.c,v 1.23 1998/04/09 02:01:18 mirar Exp $ +**! $Id: polyfill.c,v 1.24 1998/04/19 19:14:23 mirar Exp $ **! class image */ @@ -184,11 +184,11 @@ static void add_vertices(struct line_list **first, ins=first; #ifdef POLYDEBUG - fprintf(stderr," insert %g,%g - %g,%g %g,%g - %g,%g\n", - what->above->x,what->above->y, - what->below->x,what->below->y, + fprintf(stderr," insert %g,%g - %g,%g [%g,%g - %g,%g]\n", what->xmin,what->yxmin, - what->xmax,what->yxmax); + what->xmax,what->yxmax, + what->above->x,what->above->y, + what->below->x,what->below->y); #endif /* fast jump vectorgroups on the left */ @@ -207,6 +207,28 @@ static void add_vertices(struct line_list **first, if ((*ins)->xmin>=what->xmax) break; /* place left of */ + /* case: -what- */ + /* <-ins- */ + + if ((*ins)->xmin==what->xmin && + (*ins)->yxmin==what->yxmin) + { + BECAUSE("ins is above (left exact) what"); + if (VY((*ins),what->xmax)>what->yxmax) break; + else { ins=&((*ins)->next); continue; } + } + + /* case: -what- */ + /* -ins-> */ + + if ((*ins)->xmax==what->xmax && + (*ins)->yxmax==what->yxmax) + { + BECAUSE("ins is above (right exact) what"); + if (VY((*ins),what->xmin)>what->yxmin) break; + else { ins=&((*ins)->next); continue; } + } + /* case: -what- */ /* <-ins- */ if ((*ins)->xmin>what->xmin) @@ -243,11 +265,11 @@ static void add_vertices(struct line_list **first, #ifdef POLYDEBUG if (*ins) - fprintf(stderr," before %g,%g - %g,%g %g,%g - %g,%g because %s\n", - (*ins)->above->x,(*ins)->above->y, - (*ins)->below->x,(*ins)->below->y, + fprintf(stderr," before %g,%g - %g,%g [%g,%g - %g,%g] because %s\n", (*ins)->xmin,(*ins)->yxmin, (*ins)->xmax,(*ins)->yxmax, + (*ins)->above->x,(*ins)->above->y, + (*ins)->below->x,(*ins)->below->y, why); #endif @@ -362,7 +384,7 @@ static int polyfill_event(float xmin, int mtog; #ifdef POLYDEBUG - fprintf(stderr," event %g,%g - %g,%g tog=%d\n",xmin,yp,xmax,yp+1.0,tog); + fprintf(stderr," event %g,%g - %g,%g tog=%d\n",xmin,yp,xmax,yp+1.0,tog); #endif /* toggle for lines ended at xmin,yp */ @@ -383,6 +405,7 @@ static int polyfill_event(float xmin, c=c->next; } +#if 0 /* sanity check */ c=ll; while (c && c->next) @@ -400,7 +423,13 @@ static int polyfill_event(float xmin, struct line_list *l1; /* resort */ #ifdef POLYDEBUG - fprintf(stderr," !!! resort !!!\n"); + fprintf(stderr," !!! internal resort !!!\n"); + fprintf(stderr," on pair: %g,%g - %g,%g [%g,%g - %g,%g]\n %g,%g - %g,%g [%g,%g - %g,%g]\n", + c->xmin,c->yxmin,c->xmax,c->yxmax, + c->above->x,c->above->y,c->below->x,c->below->y, + c->next->xmin,c->next->yxmin,c->next->xmax,c->next->yxmax, + c->next->above->x,c->next->above->y, + c->next->below->x,c->next->below->y); #endif l1=NULL; add_vertices(&l1,ll,yp); @@ -417,6 +446,7 @@ static int polyfill_event(float xmin, } c=c->next; } +#endif /* paint if needed */ if (tog) @@ -477,7 +507,7 @@ static void polyfill_some(struct image *img, rgb_group *d; #ifdef POLYDEBUG - fprintf(stderr,"line %d..%d\n",y,y+1); + fprintf(stderr,"\nline %d..%d\n",y,y+1); #endif /* update values for current lines */ @@ -518,8 +548,50 @@ static void polyfill_some(struct image *img, /* begin with zeros */ for (i=0; i<img->xsize; i++) buf[i]=0.0; + /* sanity check */ + c=ll; + while (c && c->next) + { + if (c->xmin > c->next->xmax || + c->xmax > c->next->xmin || + ( c->xmin!=c->xmax && + c->next->xmin!=c->next->xmax && + c->next->xmax>=c->xmin && + c->next->xmin<=c->xmin && + VY(c,c->xmin)>VY(c->next,c->xmin))) + { + struct line_list *l1; + struct line_list *pll; + /* resort */ +#ifdef POLYDEBUG + fprintf(stderr," !!! resort !!!\n"); +#endif + l1=NULL; + add_vertices(&l1,ll,yp); + + while ((c=ll)) + { + ll=c->next; + free(c); + } + + ll=l1; + + break; + } + c=c->next; + } + + /* find first horisintal event */ + xmin=ll->xmin; + c=ll; + while (c) + { + if (c->xmin<xmin) xmin=c->xmin; + c=c->next; + } + /* loop through all horisontal events */ - xmin=ll->xmin-1.0; while (xmin<ixmax) { xmax=1e10; diff --git a/src/modules/Image/testsuite.in.in b/src/modules/Image/testsuite.in.in index 11c6ad75ea0ffc10ef496939337cb4d987ebc461..4f437b2518f86cc026ccebc52ffce54da2e37f64 100644 --- a/src/modules/Image/testsuite.in.in +++ b/src/modules/Image/testsuite.in.in @@ -118,6 +118,13 @@ ->setpixel(4,4,3,2,1) ->max())) fail("erranous (4)"); + if (!equal( ({17,42,36}), + Image.image(10,10,0,0,0) + ->setpixel(2,2,17,2,3) + ->setpixel(3,3,2,42,5) + ->setpixel(4,4,3,2,36) + ->max())) + fail("erranous (5)"); ok(); //----------------------------------------------------------------------- @@ -146,11 +153,11 @@ img->line(100,50-z,50,50,255,255,255); } object img1=Image.GIF.decode(MIME.decode_base64( - "R0lGODlhZABkAIAAAAAAAP///ywAAAAAZABkAAAC/wxwCGaq/l6UktZ6Mdat9sdsmziOpWl6WPMp\r\nYZrCcTxLLfLdi07Tve9brFQeXjB4RIKGQ5tQqYRGccTN7TWdZlPXWNeo1Wq7zqoLLBYjyWZXUa1W\r\ns526Kzoeby5H2L37npfn5kcUEGDY1icoqEe10qL4dMbIaFXW9pcIWBkFacknOTjJWenZaHWoSSpo\r\narO50yr0uvrpeBmkmDNLe1s3FhqayquUc0osLLozjEuIs4va+8xZfJt3SO28bIKdzNjXgaxdNTcd\r\nDi4dB+6qbT4qbhu73J79rt7Mjnwubt9dn99Pip+yd48GhVvF4h5BEPYOlrIFbOEbRw6tQUTH6xpF\r\njP9N9En0ISyhN3gfj1FkRbKkSVkcqQhUiSthRWYsWpZMxQDdC5swcUaksROmtxC7ggodKovmwKMP\r\nNQKNxJTVtTs+o9KaygWq1aEzYfHcuq2iU7D4IHUlG9DcV7RP3bElqPUtO7k36X5ca9fL2byl9vKV\r\nivfvo8CCXREu7CwuYjFEFwdM6rjpz8i/FFOO+eTwX5Ga+XK+nO4kaMaiR3cSOdn0NlGd6fJrLfe1\r\namKsZ2O+aBsoIdhoufEm6zu3l93Cwzb7bTUe8qjKi9eCmFp4c+fr7i0XSi767OzXe2LqrpI7dbfQ\r\noUs3pn20L0y511c7zx488+fjFaaHz74+D/lH99cJR2+efqD890ABADs=")); + "R0lGODlhZABkAIAAAAAAAP///ywAAAAAZABkAAAC/wxwCGaq/l6UktZ6Mdat9sdsmziOpWl6WPMpYZrCcTxLLfLdi07Tve9brFQeXjB4RIKGQ5tQqYRGccTN7TWdZlPXWNeo1Wq7zqoLLBYjyWZXUa1Ws526Kzoeby5H2L37npfn5kcUEGDY1icoqEe10qL4dMbIaFXW9pcIWBkFacknOTjJWenZaHWoSSpoarO50yr0uvrpeBmkmDNLe1s3FhqayquUc0osLLozjEuIs4va+8xZfJt3SO28bIKdzNjXgaxdNTcdDi4dB+6qbT4qbhu73J79rt7Mjnwubt9dn99Pip+yd48GhVvF4h5BEPYOlrIFbOEbRw6tQUTH6xpFjP9N9En0ISyhN3gfj1FkRbKkSVkcqQhUiSthRWYsWpZMxQDdC5swcUaksROmtxC7ggodKovmwKMPNQKNxJTVtTs+o9KaygWq1aEzYfHcuq2iU7D4IHUlG9DcV7RP3bElqPUtO7k36X5ca9fL2byl9vKVivfvo8CCXREu7CwuYjFEFwdM6rjpz8i/FFOO+eTwX5Ga+XK+nO4kaMaiR3cSOdn0NlGd6fJrLfe1amKsZ2O+aBsoIdhoufEm6zu3l93Cwzb7bTUe8qjKi9eCmFp4c+fr7i0XSi767OzXe2LqrpI7dbfQoUs3pn20L0y511c7zx488+fjFaaHz74+D/lH99cJR2+efqD890ABADs=")); if (img!=img1) fail("differ"); ok(); -#test Image.image->line color 1 +#test Image.image->line color object img=Image.image(100,100,0,0,0); img->line(40,0,0,40); if (!equal( ({0,0,0}), img->max() )) fail("differ (reset)"); @@ -161,3 +168,97 @@ if (!equal( ({200,19,99}), img->max() )) fail("differ (setcolor)"); ok(); +#test Image.image->polyfill 1 (right triangle 0.0, 0.2) + object img=Image.image(100,100,0,0,0); + float x=0,y=0.2; + img->setcolor(255,254,253); + img->polygone(({10+x,15+y,15+x,10+y,15+x,15+y}), + ({20+x,15+y,25+x,15+y,20+x,10+y}), + ({10+x,20+y,15+x,20+y,15+x,25+y}), + ({20+x,25+y,25+x,20+y,20+x,20+y}), + + ({30+2*10+x,15+y,30+2*15+x,10+y,30+2*15+x,15+y}), + ({30+2*20+x,15+y,30+2*25+x,15+y,30+2*20+x,10+y}), + ({30+2*10+x,20+y,30+2*15+x,20+y,30+2*15+x,25+y}), + ({30+2*20+x,25+y,30+2*25+x,20+y,30+2*20+x,20+y}), + + ({10+x,30+2*15+y,15+x,30+2*10+y,15+x,30+2*15+y}), + ({20+x,30+2*15+y,25+x,30+2*15+y,20+x,30+2*10+y}), + ({10+x,30+2*20+y,15+x,30+2*20+y,15+x,30+2*25+y}), + ({20+x,30+2*25+y,25+x,30+2*20+y,20+x,30+2*20+y})); + + object img1=Image.GIF.decode(MIME.decode_base64( + "R0lGODlhZABkAMQAAAAAAAICAgUFBQoKChYWFigoKC0tLTAwMDIyMjMyMj8/P1lYWFFRUHJycXp5eYyLi6OioaWlpK2srLW0s8vLyszLytbV1Ojn5vTz8vn49/z7+v/+/QAAAAAAAAAAAAAAACwAAAAAZABkAAQF/yAAiONYmiaapivLuu8byzJd1zeO6/ve+z5gMDgkEo3HY1KpZDabTyhUOp1WrVZsNrvlcr3fb1gsJpfLZzRafWSw3Osd4bF7EOLtDCsDx6fmGBs7Gxh2fjgMGYIpG3yHAIAbG4s1k4SGjyaJkyyTjnGRlpQyopd3j5ucjJ59X6Glg6WmhwYICLYst7cGaAW6uro7wMAIBZmZx8jIysvLzc7O0GUOFBTVLNbWDmgKE9nZ1jvg4BMKhwISlp2TEgJrAw0XsrGiFw0DmeiqJuzuePDy1OGod8+Zvk7tMgHcR2qDPXzRAKBjkXAZwB0PI6bwZ4KjM4g1QGrUOJIkSZMnT+6mVKmSZcuWL2HClDlzZk2bNnHmzLmTJ0+fP38GFSqUaNGiR5EiVbp0aVOnTqFGjTqV6hdjKbBadRaBRdetywpoYKFBK9hDEUYB2PD1rB+xajeUdesnbVy2dOPAvTs3bxm7d/H6vapBIL9JfQdbARxYsOIpBxIkkMxi8uQDjx9n1qyZc+fOn0GDFj169CMI4LBlg2D6yAJR6yYtaE0kgAXDIyxZCECbyGuGa2X3rn377u7hvoELRx7EdtzjzIO87jQ7enMLLKBb91HdRPftO3inEA8efHnz5tGnT7+ePXv379/Hly+ffv369/HjPxQCADs=")); + if (img-img1>16) fail("differ too much"); + if (!equal(img->max(),({255,254,253}))) fail("wrong maxcolor"); + ok(); + +#test Image.image->polyfill 2 (right triangle -0.2, -0.2) + object img=Image.image(100,100,0,0,0); + float x=-0.2,y=-0.2; + img->setcolor(255,254,253); + img->polygone(({10+x,15+y,15+x,10+y,15+x,15+y}), + ({20+x,15+y,25+x,15+y,20+x,10+y}), + ({10+x,20+y,15+x,20+y,15+x,25+y}), + ({20+x,25+y,25+x,20+y,20+x,20+y}), + + ({30+2*10+x,15+y,30+2*15+x,10+y,30+2*15+x,15+y}), + ({30+2*20+x,15+y,30+2*25+x,15+y,30+2*20+x,10+y}), + ({30+2*10+x,20+y,30+2*15+x,20+y,30+2*15+x,25+y}), + ({30+2*20+x,25+y,30+2*25+x,20+y,30+2*20+x,20+y}), + + ({10+x,30+2*15+y,15+x,30+2*10+y,15+x,30+2*15+y}), + ({20+x,30+2*15+y,25+x,30+2*15+y,20+x,30+2*10+y}), + ({10+x,30+2*20+y,15+x,30+2*20+y,15+x,30+2*25+y}), + ({20+x,30+2*25+y,25+x,30+2*20+y,20+x,30+2*20+y})); + + object img1=Image.GIF.decode(MIME.decode_base64( + "R0lGODlhZABkANUAAAAAAAICAgUFBQcHBwoKChQUFBYWFh4eHiMjIyYmJS0tLTAwMDMyMigoKFFRUFlYWHp5eX9+fnJycYyLi56dnDIyMqOioaWlpMHBwMvLyszLytHQz9bV1Orp6Ojn5vTz8vz7+v/+/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAZABkAAUG/0AAQDgcFo1GZDK5ZDKdz2dUKqVWq1csVrvddr1ecDg8JpPN53NarWa32284XD6f1+12fD6/5/P9f3+BgoKEhYVqAkmKiGQEWAMBjW0FFEkMEZNYBhMYWBUcD5KaWwUbGZchmaRGnB8hqFUVISGho6xJprCpqqyutLuywLWiuEO6wUMMwKuIv8OxUrPDxLeTAhQZGRkWSQ3b2w6FAQ8Y4ODcWN/o4BYNxsbw8fHz9PT29/f5ggIMDP7vjBD49w/BuAUECf4LKGWgQoUHWEUAFg3AMlodFCBqcAEEtWRPplHzIOGRRFoVL2bUxNEjxU8jS9KbmDLESlYtUcKkRdLkvf8IKW8aa1mRyaye+pKIM4JAo74GELAkkJk0aVWrVrFmzbqVK1evX7+GFSuWbNmyZ9GiVbt2bVu3buHGjTuXLl27d+/m1auXb9++fwEDFjx4cGHDhvlYs5b43oMkCxg2jmfAkxEGFybfm5AShGTNmgx8qJkZNKsJIJd5Nh36Vc0QpVkjQp2a1mrZgkTrvAwsNu48tGvb/vxbDQFz27oZWbctavHiz6FDlz59enXr1rFnz152QIUK3yUTAA8+AfczATi85A1MwvkzD9YrA+bB5/st6XfPp+X+Ppn4wtXnHxn5vdbfgGHEV5OACIaRXk0HNujFAykxKKEXASinTIQXbiEk2QH2ddihiCOOWKKJJqKYYoorssiiiy++GKOMMtJYY4034hYEADs=")); + if (img-img1>16) fail("differ too much"); + if (!equal(img->max(),({255,254,253}))) fail("wrong maxcolor"); + ok(); + + +#test Image.image->polyfill 2 (hollow stars) + object img=Image.image(100,100,0,0,0); + int i; + + array a=({}),b=({}); + foreach (({0,1,2,3,4}),i) + { + a+=({ 50+50*sin(i*2*3.1415926535/5+0.11), + 50+50*cos(i*2*3.1415926535/5+0.11) }); + a+=({ 50+19*sin((i+0.5)*2*3.1415926535/5+0.11), + 50+19*cos((i+0.5)*2*3.1415926535/5+0.11) }); + b+=({ 50+19*sin(i*2*3.1415926535/5+0.1), + 50+19*cos(i*2*3.1415926535/5+0.1) }); + b+=({ 50+0.5*5*sin((i+0.5)*2*3.1415926535/5+0.1), + 50+0.5*5*cos((i+0.5)*2*3.1415926535/5+0.1) }); + } + + img->setcolor(128,0,16); + img->polyfill(a,b); + + a=({}),b=({}); + foreach (({0,1,2,3,4,5,6}),i) + { + a+=({ 50+50*sin(i*2*3.1415926535/7+0.11), + 50+50*cos(i*2*3.1415926535/7+0.11) }); + a+=({ 50+19*sin((i+0.5)*2*3.1415926535/7+0.11), + 50+19*cos((i+0.5)*2*3.1415926535/7+0.11) }); + b+=({ 50+0.9*50*sin(i*2*3.1415926535/7+0.1), + 50+0.9*50*cos(i*2*3.1415926535/7+0.1) }); + b+=({ 50+0.5*19*sin((i+0.5)*2*3.1415926535/7+0.1), + 50+0.5*19*cos((i+0.5)*2*3.1415926535/7+0.1) }); + } + + img->setcolor(255,128,0); + img->polyfill(a,b); + + object img1=Image.GIF.decode(MIME.decode_base64( + "R0lGODlhZABkAPcAAAAAAAEAAAIAAAMAAAMBAAQAAAUAAAYAAAQCAAUCAAYDAAIBAAcAAAcDAAgEAAgAAQkAAQoAAQsAAQwAAAwAAQkDAAkEAAoFAAsFAAwGAA0AARAAAhEAAhIAAhQAAg8AARUAAhYAAhcAARcAAhgAAxoAAxsAAw0GAA4HAA8HABAIABEIABIJABMKABMJABYLABQKABgMABkMABkNABoNABsNAA4AARwAAx0AAx4AAyEABCIABB8AAyIIASAABCQABCUABCYABCcABCkABSgABSoABSsABSwABS0ABSwBBC4ABTAABi8ABTEABjIABjMABjYABjUABjgABzkABzoABzoBBjsABzwABz0ABz4ABx0PAB0OAB4PAB8PACEOACEQACIRACMRACAQACQSACUSACcMACgMASYTACgTACgUACkUACkVACoVADcABjELAjQKAy4UACwWAC0WAC0XADAYADEYADIZADMaADQaADYbADcbADkcADgcADweAD0eAD4fAEEABkUACEoACUsACFEAClYAClYACV4AC0YACGQAC2cADG4ADXMADXQMCncADnsADkIVAUEgAEUiAEgjAFIIBk4mAFMpAFUqAGwTB3AYBWQfAl4uAGQxAGk0AGs1AHI1AH0AD34AD38AD4AAD4AAEIABD4EBD4ICD4QED4MDD4cGDogHDooKDY0MDowSC5AQDZISDZYUDZcXDJgYDJgRDZocC54dDKAdC6AiCqYkC6gkCqsrCq4tCrMxCbU1Cbc2CHU6AHc9AHs/AIJCAIdAAYxHAJVDApdMAIhEAJ9NAaVJAqtXALw8B7xMBbRbALxeAcJCB8VEB8ZMBcxMBcpaAtNUBdhYBNxdA8NiAMlmANJqANlsAdpnAelqAuJyAOl2AZFJAO53AO9xAfFxAfJyAfJzAfN1APV1AfB4APB4APF5APR6APN6APV7APZ3Afd4APh5APh6APl6APh7APp7APd3Afh8APd8APl9APt9APt9APx+AP1+AO93AP5/AP+AACwAAAAAZABkAAcI/wABABA4cGBBgwYRJky4kCFDDw4dRpQokWLFihcxYtTIsFCEjRtBhgw5kiRJjI6ynJQYYOVKly9fGuxAylEBmQMRbMKJk2dPh0dIkXLSUxiwnz+R9kQkdBFONvZ2Jk06deUhoaSAvCSQ7Z8k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")); + + if (img-img1>16) fail("differ too much"); + if (!equal(img->max(),({255,128,16}))) fail("wrong maxcolor"); + ok(); +