#ifndef lint static char sccsid[] = "@(#)mem_shcrv.c 9.2 88/01/19 Copyright 1985 Sun Micro"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- Draw a curve in a memory pixrect. mem_shcrv.c, Tue Mar 4 08:48:09 1986 */ #ifdef REF #include #include #endif #include "shape.h" #include #include #include #include "fract.h" extern mem_rop(); /* * Comment out table for now. It's not used anymore. * static int arclength_table[] = { (int) (1.0000000000 * (1 << 16)), (int) (1.4142135623 * (1 << 16)), (int) (2.2360679774 * (1 << 16)), (int) (3.1622776601 * (1 << 16)), (int) (4.1231056256 * (1 << 16)), (int) (5.0990195135 * (1 << 16)), (int) (6.0827625302 * (1 << 16)), (int) (7.0710678118 * (1 << 16)), (int) (8.0622577482 * (1 << 16)), (int) (9.0553851381 * (1 << 16)), (int) (10.0498756211 * (1 << 16)), (int) (11.0453610171 * (1 << 16)), (int) (12.0415945787 * (1 << 16)), (int) (13.0384048104 * (1 << 16)), (int) (14.0356688476 * (1 << 16)), (int) (15.0332963783 * (1 << 16)), (int) (16.0312195418 * (1 << 16)), (int) (17.0293863659 * (1 << 16)), (int) (18.0277563773 * (1 << 16)), (int) (19.0262975904 * (1 << 16)), (int) (20.0249843945 * (1 << 16)), (int) (21.0237960416 * (1 << 16)), (int) (22.0227155455 * (1 << 16)), (int) (23.0217288664 * (1 << 16)), (int) (24.0208242989 * (1 << 16)), (int) (25.0199920063 * (1 << 16)), (int) (26.0192236625 * (1 << 16)), (int) (27.0185121722 * (1 << 16)), (int) (28.0178514522 * (1 << 16)), (int) (29.0172362570 * (1 << 16)), (int) (30.0166620396 * (1 << 16)), (int) (31.0161248385 * (1 << 16)), * }; */ #define TRUE(x) x #define FALSE(x) #define drawcurve1(check) \ switch((op>>3)&3) { \ case 0: drawcurve0(check, &= ~, setbits, setbit); break; \ case 1: drawcurve0(check, ^=, setbits, setbit); break; \ case 2: break; \ case 3: drawcurve0(check, |=, setbits, setbit); break; \ } #define drawcurve8(check) \ switch((op>>3)&3) { \ case 3: \ case 0: drawcurve0(check, = color, setbytes, setbyte); break;\ case 1: drawcurve0(check, ^= ~0, setbytes, setbyte); break; \ case 2: break; \ } #define drawcurve0(check,op,setmany,setone) \ while (p <= limit) { \ register short ndiff; \ x = *p++; \ ndiff = x - *p; \ x += xoff; \ if ((delta = x - xp) < 0) { \ delta = -delta; \ xp = x; \ } \ else if (delta) \ xp++; \ if (delta <= 1) { \ check( if (left <= xp && xp < right) )\ setone(linep, xp, op); \ } \ else { \ if (ndiff == 0) { /* Found a pimple */ \ delta--; \ if (p[-2] > p[-1]) \ xp++; \ } \ check( if ((ndiff = xp - left) < 0) { \ xp = left; \ delta += ndiff; \ } \ if ((ndiff = xp + delta - right) > 0) \ delta -= ndiff; )\ setmany(linep, xp, delta, op); \ } \ linep += lineinc; \ xp = x; \ } #ifdef sparc #define setbits(l,p,n,op) \ while (n > 0) \ setbit(l,p,op), p++, n--; #else #define setbits(l,p,n,op) \ while (n > 16) \ setwbits(l, p, 16, op), p+=16, n-=16; \ if (n > 0) \ setwbits(l, p, n, op); #endif /* sparc */ #define setwbits(l,p,n,op) *(int *) (((char *) l) + ((p>>3)&~1)) op (((unsigned)((1<<31)>>(n-1)))>>(p&0xF)) #define setbit(l,p,op) l[p>>3] op (1<<7)>>(p&7) #define setbytes(l,p,n,op) \ while (n > 0) \ setbyte(l, p, op), p++, n--; #define setbyte(l,p,op) l[p] op mem_shapecurve(fb, shape, chain, op, texture, phase) struct pixrect *fb; struct shape_dcurve *chain; struct shape *shape; short *texture; { register struct mpr_data *mprd = mpr_d(fb); register short xoff = mprd->md_offset.x; short top, bottom, left, right; char color = PIX_OPCOLOR(op); if (shape == 0) return 0; if (!shape->is_rect) return sh_subdivide_curve(fb, shape, chain, op, texture, phase, shape->trapset); if (texture && *texture) return generic_shapecurve(fb, shape, chain, op, texture, phase); top = max(0, shape->pos.y); left = max(0, shape->pos.x) + xoff; bottom = min(fb->pr_size.y, shape->pos.y + shape->size.y); right = min(fb->pr_size.x, shape->pos.x + shape->size.x) + xoff; if (top >= bottom || left >= right) return 0; for (; chain; chain = chain->next) { register short xp = chain->x0; register short *p = chain->x + 1; short *limit = chain->x + (min(chain->y1, bottom - 1) - chain->y0) + 1; register char *linep; register char *lineincp; register short x; register short delta; short y0 = chain->y0; if ((x = y0 - top) < 0) { p -= x; y0 = top; if (p > limit) continue; xp = p[-1]; } if (xp < *p) xp--; else if (xp > *p) xp++; #define lineinc ((int) lineincp) lineincp = (char *) mprd->md_linebytes; linep = ((char *) mprd->md_image) + pr_product(lineinc, y0 + mprd->md_offset.y); xp += xoff; if (left <= chain->left + xoff && chain->right + xoff < right) { if (fb->pr_depth == 1) { drawcurve1(FALSE); } else { assert(fb->pr_depth == 8); drawcurve8(FALSE); } } else { if (fb->pr_depth == 1) { drawcurve1(TRUE); } else { assert(fb->pr_depth == 8); drawcurve8(TRUE); } } } return 0; }