예제 #1
0
/* Check for interrupts before a return. */
int
gs_return_check_interrupt(const gs_memory_t *mem, int code)
{
    if (code < 0)
        return code;
    {
        int icode = gp_check_interrupts(mem);

        return (icode == 0 ? code :
                gs_note_error((icode > 0 ? gs_error_interrupt : icode)));
    }
}
예제 #2
0
/* Draw a one-pixel-wide line. */
int
gz_draw_line_fixed(fixed ixf, fixed iyf, fixed itoxf, fixed itoyf,
  const gx_device_color *pdevc, gs_state *pgs)
{	int ix = fixed2int_var(ixf);
	int iy = fixed2int_var(iyf);
	int itox = fixed2int_var(itoxf);
	int itoy = fixed2int_var(itoyf);
	gx_device *dev;
	gp_check_interrupts();
	if ( itoy == iy )		/* horizontal line */
	  { return (ix <= itox ?
		    gz_fill_rectangle(ix, iy, itox - ix + 1, 1, pdevc, pgs) :
		    gz_fill_rectangle(itox, iy, ix - itox + 1, 1, pdevc, pgs)
		    );
	  }
	if ( itox == ix )		/* vertical line */
	  { return (iy <= itoy ?
		    gz_fill_rectangle(ix, iy, 1, itoy - iy + 1, pdevc, pgs) :
		    gz_fill_rectangle(ix, itoy, 1, iy - itoy + 1, pdevc, pgs)
		    );
	  }
	if ( color_is_pure(pdevc) &&
	    (dev = pgs->device->info,
	     (*dev->procs->draw_line)(dev, ix, iy, itox, itoy,
				      pdevc->color1)) >= 0 )
	  return 0;
	{ fixed h = itoyf - iyf;
	  fixed w = itoxf - ixf;
	  fixed tf;
#define fswap(a, b) tf = a, a = b, b = tf
	  if ( (w < 0 ? -w : w) <= (h < 0 ? -h : h) )
	    { if ( h < 0 )
		fswap(ixf, itoxf), fswap(iyf, itoyf),
		h = -h;
	      return gz_fill_trapezoid_fixed(ixf - fixed_half, fixed_1, iyf,
					     itoxf - fixed_half, fixed_1, h,
					     0, pdevc, pgs);
	    }
	  else
	    { if ( w < 0 )
		fswap(ixf, itoxf), fswap(iyf, itoyf),
		w = -w;
	      return gz_fill_trapezoid_fixed(iyf - fixed_half, fixed_1, ixf,
					     itoyf - fixed_half, fixed_1, w,
					     1, pdevc, pgs);
	    }
#undef fswap
	}
}
예제 #3
0
int
gz_fill_trapezoid_fixed(fixed fx0, fixed fw0, fixed fy0,
  fixed fx1, fixed fw1, fixed fh, int swap_axes,
  const gx_device_color *pdevc, gs_state *pgs)
{	const fixed ymin = fixed_rounded(fy0) + fixed_half;
	const fixed ymax = fixed_rounded(fy0 + fh);
	int iy = fixed2int_var(ymin);
	const int iy1 = fixed2int_var(ymax);
	if ( iy >= iy1 ) return 0;	/* no scan lines to sample */
   {	trap_line l, r;
	int rxl, rxr, ry;
	const fixed dxl = fx1 - fx0;
	const fixed dxr = dxl + fw1 - fw0;
	const fixed yline = ymin - fy0;	/* partial pixel offset to */
					/* first line to sample */
	int fill_direct = color_is_pure(pdevc);
	gx_color_index cindex;
	gx_device *dev;
	dev_proc_fill_rectangle((*fill_rect));
	int code;
	
	if_debug2('z', "[z]y=[%d,%d]\n", iy, iy1);

	if ( fill_direct )
	  cindex = pdevc->color1,
	  dev = pgs->device->info,
	  fill_rect = dev->procs->fill_rectangle;
	gp_check_interrupts();
	r.x = (l.x = fx0 + fixed_half) + fw0;
	ry = iy;

	/* If the rounded X values are the same on both sides, */
	/* we can save ourselves a *lot* of work. */
	if ( fixed_truncated(l.x) == fixed_rounded(fx1) &&
	     fixed_truncated(r.x) == fixed_rounded(fx1 + fw1)
	   )
	{	rxl = fixed2int_var(l.x);
		rxr = fixed2int_var(r.x);
		iy = iy1;
		if_debug2('z', "[z]rectangle, x=[%d,%d]\n", rxl, rxr);
		goto last;
	}

#define fill_trap_rect(x,y,w,h)\
  (fill_direct ?\
    (swap_axes ? (*fill_rect)(dev, y, x, h, w, cindex) :\
     (*fill_rect)(dev, x, y, w, h, cindex)) :\
   swap_axes ? gz_fill_rectangle(y, x, h, w, pdevc, pgs) :\
   gz_fill_rectangle(x, y, w, h, pdevc, pgs))

	/* Compute the dx/dy ratios. */
	/* dx# = dx#i + (dx#f / fh). */
#define compute_dx(tl, d)\
  if ( d >= 0 )\
   { if ( d < fh ) tl.di = 0, tl.df = d;\
     else tl.di = (int)(d / fh), tl.df = d - tl.di * fh, tl.x += yline * tl.di;\
   }\
  else\
   { if ( (tl.df = d + fh) >= 0 /* d >= -fh */ ) tl.di = -1, tl.x -= yline;\
     else tl.di = (int)-((fh - 1 - d) / fh), tl.df = d - tl.di * fh, tl.x += yline * tl.di;\
   }

	/* Compute the x offsets at the first scan line to sample. */
	/* We need to be careful in computing yline * dx#f {/,%} fh */
	/* because the multiplication may overflow.  We know that */
	/* all the quantities involved are non-negative, and that */
	/* yline is less than 1 (as a fixed, of course); this gives us */
	/* a cheap conservative check for overflow in the multiplication. */
#define ymult_limit (max_fixed / fixed_1)
#define ymult_quo(yl, dxxf)\
  (dxxf < ymult_limit ? yl * dxxf / fh : fixed_mult_quo(yl, dxxf, fh))
#define ymult_rem(yl, dxxf)\
  (dxxf < ymult_limit ? yl * dxxf % fh : fixed_mult_rem(yl, dxxf, fh))

	/* It's worth checking for dxl == dxr, since this is the case */
	/* for parallelograms (including stroked lines). */
	compute_dx(l, dxl);
	if ( dxr == dxl )
	   {	fixed fx = ymult_quo(yline, l.df);
		l.x += fx;
		if ( l.di == 0 )
			r.di = 0, r.df = l.df;
		else			/* too hard to do adjustments right */
			compute_dx(r, dxr);
		r.x += fx;
	   }
	else
	   {	l.x += ymult_quo(yline, l.df);
		compute_dx(r, dxr);
		r.x += ymult_quo(yline, r.df);
	   }
	rxl = fixed2int_var(l.x);
	rxr = fixed2int_var(r.x);

	/* Compute one line's worth of dx/dy. */
	/* dx# * fixed_1 = ld#i + (ld#f / fh). */
	/* We don't have to bother with this if */
	/* we're only sampling a single scan line. */
	if ( iy1 - iy == 1 )
	   {	iy++;
		goto last;
	   }
#define compute_ldx(tl)\
  if ( tl.df < ymult_limit )\
    tl.ldi = int2fixed(tl.di) + int2fixed(tl.df) / fh,\
    tl.ldf = int2fixed(tl.df) % fh,\
    tl.xf = yline * tl.df % fh - fh;\
  else\
    tl.ldi = int2fixed(tl.di) + fixed_mult_quo(fixed_1, tl.df, fh),\
    tl.ldf = fixed_mult_rem(fixed_1, tl.df, fh),\
    tl.xf = fixed_mult_rem(yline, tl.df, fh) - fh
	compute_ldx(l);
	if ( dxr == dxl )
		r.ldi = l.ldi, r.ldf = l.ldf, r.xf = l.xf;
	else
	   {	compute_ldx(r);
	   }
#undef compute_ldx

	while ( ++iy != iy1 )
	   {	int ixl, ixr;
#define step_line(tl)\
  tl.x += tl.ldi;\
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= fh, tl.x++;
		step_line(l);
		step_line(r);
#undef step_line
		ixl = fixed2int_var(l.x);
		ixr = fixed2int_var(r.x);
		if ( ixl != rxl || ixr != rxr )
		   {	code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry);
			if ( code < 0 ) goto xit;
			rxl = ixl, rxr = ixr, ry = iy;
		   }	
	   }
last:	code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry);
xit:	gp_check_interrupts();
	if ( code < 0 && fill_direct ) return_error(code);
	return code;
   }
}