picture inner_shadow (picture pic, color c, double dx, double dy) { true_color col (c); raster<true_color> r= as_raster<true_color> (pic); raster<double> alpha = get_alpha (r); raster<double> ashift= shift (alpha, dx, dy); raster<double> compat= change_extents (ashift, r->w, r->h, r->ox, r->oy); raster<double> cshift= ((double) 1) - compat; raster<double> shad = min (alpha, cshift); raster<true_color> appl= apply_alpha (col, shad); return raster_picture (appl); }
picture gaussian_pen_picture (double rx, double ry, double phi) { raster<double> ras= gaussian_pen<double> (rx, ry, phi); return raster_picture (apply_alpha (true_color (0, 0, 0, 1), ras)); }
picture rectangular_pen_picture (double rx, double ry, double phi) { raster<double> ras= rectangular_pen<double> (rx, ry, phi); return raster_picture (apply_alpha (true_color (0, 0, 0, 1), ras)); }
picture motion_pen_picture (double dx, double dy) { raster<double> ras= motion_pen<double> (dx, dy); return raster_picture (apply_alpha (true_color (0, 0, 0, 1), ras)); }
static void polyfill_some(struct image *img, struct vertex *v, double *buf) { struct line_list *ll=NULL; int y=0; double ixmax = (double)img->xsize; struct vertex *to_add=v,*to_loose=v; /* beat row for row */ if (y+1.0+1e-10<v->y) y = DOUBLE_TO_INT(v->y); while (y<img->ysize && (to_loose||to_add) ) { double yp = y; struct line_list *c; double xmin, xmax; rgb_group *d; int tog=0; int i; #ifdef POLYDEBUG fprintf(stderr,"\nline %d..%d\n",y,y+1); #endif /* update values for current lines */ c=ll; while (c) { c->xmin=line_xmin(c,yp,&c->yxmin); c->xmax=line_xmax(c,yp,&c->yxmax); c=c->next; } /* add any new vertices */ while (to_add && to_add->y<yp+1.0) { struct vertex *vx=to_add; to_add=to_add->next; add_vertices(&ll,vx->below,yp); } #ifdef POLYDEBUG c=ll; while (c) { fprintf(stderr," line %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=c->next; } #endif if (!ll) { y++; continue; } /* 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; /* 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 */ while (xmin<ixmax) { xmax=1e10; c=ll; while (c) { /* each line has two events: beginning and end */ if (c->xmin<xmax && c->xmin>xmin) xmax=c->xmin; if (c->xmax<xmax && c->xmax>xmin) xmax=c->xmax; c=c->next; } if (xmax==1e10) break; /* no more events */ if (xmax>ixmax) xmax=ixmax; tog=polyfill_event(xmin,xmax,yp,buf,&ll,tog); /* shift to get next event */ xmin = xmax; xmax = DO_NOT_WARN(xmin - 1.0); } /* remove any old vertices */ while (to_loose!=to_add && to_loose->y<yp+1.0-1e-10) { struct vertex *vx=to_loose; to_loose=to_loose->next; sub_vertices(&ll,vx,yp); } /* write this row */ d=img->img+img->xsize*y; if(THIS->alpha) { for (i=0; i<img->xsize; i++) { #ifdef POLYDEBUG fprintf(stderr,"%3.2f ",buf[i]); #endif #define apply_alpha(x,y,alpha) \ ((unsigned char)((y*(255L-(alpha))+x*(alpha))/255L)) d->r = apply_alpha( d->r, DOUBLE_TO_COLORTYPE((d->r*(1.0-buf[i]))+ (img->rgb.r*buf[i])), THIS->alpha ); d->g = apply_alpha( d->g, DOUBLE_TO_COLORTYPE((d->g*(1.0-buf[i]))+ (img->rgb.g*buf[i])), THIS->alpha ); d->b = apply_alpha( d->b, DOUBLE_TO_COLORTYPE((d->b*(1.0-buf[i]))+ (img->rgb.b*buf[i])), THIS->alpha ); d++; } #ifdef POLYDEBUG fprintf(stderr,"\n"); #endif } else { for (i=0; i<img->xsize; i++) { #ifdef POLYDEBUG fprintf(stderr,"%3.2f ",buf[i]); #endif d->r = DOUBLE_TO_COLORTYPE((d->r*(1.0-buf[i]))+(img->rgb.r*buf[i])); d->g = DOUBLE_TO_COLORTYPE((d->g*(1.0-buf[i]))+(img->rgb.g*buf[i])); d->b = DOUBLE_TO_COLORTYPE((d->b*(1.0-buf[i]))+(img->rgb.b*buf[i])); d++; } #ifdef POLYDEBUG fprintf(stderr,"\n"); #endif } y++; } while (ll) { struct line_list *c; ll=(c=ll)->next; free(c); } }