Пример #1
0
static int
alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits, 
                  bool devn)
{
    gx_device *dev = gs_currentdevice_inline(pgs);
    int log2_alpha_bits = ilog2(alpha_bits);
    gs_fixed_rect bbox;
    gs_int_rect ibox;
    uint width, raster, band_space;
    uint height;
    gs_log2_scale_point log2_scale;
    gs_memory_t *mem;
    gx_device_memory *mdev;

    log2_scale.x = log2_scale.y = log2_alpha_bits;
    gx_path_bbox(pgs->path, &bbox);
    ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1;
    ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1;
    ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1;
    ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1;
    width = (ibox.q.x - ibox.p.x) << log2_scale.x;
    raster = bitmap_raster(width);
    band_space = raster << log2_scale.y;
    height = (abuf_nominal / band_space) << log2_scale.y;
    if (height == 0)
        height = 1 << log2_scale.y;
    mem = pgs->memory;
    mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
                           "alpha_buffer_init");
    if (mdev == 0)
        return 0;		/* if no room, don't buffer */
    /* We may have to update the marking parameters if we have a pdf14 device
       as our target.  Need to do while dev is still active in pgs */
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) {
        gs_update_trans_marking_params(pgs);
    }
    gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale,
                            alpha_bits, ibox.p.x << log2_scale.x, devn);
    mdev->width = width;
    mdev->height = height;
    mdev->bitmap_memory = mem;
    if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) {
        /* No room for bits, punt. */
        gs_free_object(mem, mdev, "alpha_buffer_init");
        return 0;
    }
    gx_set_device_only(pgs, (gx_device *) mdev);
    scale_paths(pgs, log2_scale.x, log2_scale.y, true);
    return 1;
}
Пример #2
0
/* Draw a one-pixel-wide line. */
int
gz_draw_line_fixed(fixed ixf, fixed iyf, fixed itoxf, fixed itoyf,
  gx_device_color *pdevc, gs_state *pgs)
{	int ix = fixed2int(ixf);
	int iy = fixed2int(iyf);
	int itox = fixed2int(itoxf);
	int itoy = fixed2int(itoyf);
	if ( itoy == iy )		/* horizontal line */
	   {	if ( ix <= itox )
			gz_fill_rectangle(ix, iy, fixed2int_ceiling(itoxf) -
						ix, 1, pdevc, pgs);
		else
			gz_fill_rectangle(itox, iy, fixed2int_ceiling(ixf) -
						itox, 1, pdevc, pgs);
	   }
	else
	   {	gx_device *dev = pgs->device->info;
		fixed h, w, tf;
#define fswap(a, b) tf = a, a = b, b = tf
		if ( color_is_pure(pdevc) &&
		    (*dev->procs->draw_line)(dev, ix, iy, itox, itoy,
					     pdevc->color1) >= 0 )
		  return 0;
		h = itoyf - iyf;
		w = itoxf - ixf;
#define fixed_eps (fixed)1
		if ( (w < 0 ? -w : w) <= (h < 0 ? -h : h) )
		   {	if ( h < 0 )
				fswap(ixf, itoxf), fswap(iyf, itoyf),
				h = -h;
			gz_fill_trapezoid_fixed(ixf, fixed_eps, iyf,
						itoxf, fixed_eps, h,
						0, pdevc, pgs);
		   }
		else
		   {	if ( w < 0 )
				fswap(ixf, itoxf), fswap(iyf, itoyf),
				w = -w;
			gz_fill_trapezoid_fixed(iyf, fixed_eps, ixf,
						itoyf, fixed_eps, w,
						1, pdevc, pgs);
		   }
#undef fixed_eps
#undef fswap
	   }
	return 0;
}
Пример #3
0
static int
alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits)
{
    gx_device *dev = gs_currentdevice_inline(pgs);
    int log2_alpha_bits = ilog2(alpha_bits);
    gs_fixed_rect bbox;
    gs_int_rect ibox;
    uint width, raster, band_space;
    uint height;
    gs_log2_scale_point log2_scale;
    gs_memory_t *mem;
    gx_device_memory *mdev;

    log2_scale.x = log2_scale.y = log2_alpha_bits;
    gx_path_bbox(pgs->path, &bbox);
    ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1;
    ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1;
    ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1;
    ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1;
    width = (ibox.q.x - ibox.p.x) << log2_scale.x;
    raster = bitmap_raster(width);
    band_space = raster << log2_scale.y;
    height = (abuf_nominal / band_space) << log2_scale.y;
    if (height == 0)
	height = 1 << log2_scale.y;
    mem = pgs->memory;
    mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
			   "alpha_buffer_init");
    if (mdev == 0)
	return 0;		/* if no room, don't buffer */
    gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale,
			    alpha_bits, ibox.p.x << log2_scale.x);
    mdev->width = width;
    mdev->height = height;
    mdev->bitmap_memory = mem;
    if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) {
	/* No room for bits, punt. */
	gs_free_object(mem, mdev, "alpha_buffer_init");
	return 0;
    }
    gx_set_device_only(pgs, (gx_device *) mdev);
    scale_paths(pgs, log2_scale.x, log2_scale.y, true);
    return 1;
}
Пример #4
0
int 
gx_default_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
	int i0, int j, int w,
	const frac31 *c0, const int32_t *c0f, const int32_t *cg_num, int32_t cg_den)
{
    /* This default implementation decomposes the area into constant color rectangles.
       Devices may supply optimized implementations with
       the inversed nesting of the i,k cicles,
       i.e. with enumerating planes first, with a direct writing to the raster,
       and with a fixed bits per component.
     */
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
    int i, i1 = i0 + w, bi = i0, k;
    gx_color_index ci0 = 0, ci1;
    const gx_device_color_info *cinfo = &dev->color_info;
    int n = cinfo->num_components;
    int si, ei, di, code;

    if (j < fixed2int(fa->clip->p.y) ||
	    j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
	return 0;
    for (k = 0; k < n; k++) {
	int shift = cinfo->comp_shift[k];
	int bits = cinfo->comp_bits[k];

	c[k] = c0[k];
	f[k] = c0f[k];
	ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
    }
    for (i = i0 + 1, di = 1; i < i1; i += di) {
	if (di == 1) {
	    /* Advance colors by 1 pixel. */
	    ci1 = 0;
	    for (k = 0; k < n; k++) {
		int shift = cinfo->comp_shift[k];
		int bits = cinfo->comp_bits[k];

		if (cg_num[k]) {
		    int32_t m = f[k] + cg_num[k];

		    c[k] += m / cg_den;
		    m -= m / cg_den * cg_den;
		    if (m < 0) {
			c[k]--;
			m += cg_den;
		    }
		    f[k] = m;
		}
		ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
	    }
	} else {
Пример #5
0
int continue_margin_common(line_list * ll, margin_set * set, active_line * flp, active_line * alp, fixed y0, fixed y1)
{   int code;
#   if ADJUST_SERIF
    section *sect = set->sect;
    fixed yy0 = max(max(y0, alp->start.y), set->y);
    fixed yy1 = min(min(y1, alp->end.y), set->y + fixed_1);

    if (yy0 <= yy1) {
        fixed x00 = (yy0 == y0 ? flp->x_current : AL_X_AT_Y(flp, yy0));
        fixed x10 = (yy0 == y0 ? alp->x_current : AL_X_AT_Y(alp, yy0));
        fixed x01 = (yy1 == y1 ? flp->x_next : AL_X_AT_Y(flp, yy1));
        fixed x11 = (yy1 == y1 ? alp->x_next : AL_X_AT_Y(alp, yy1));
        fixed xmin = min(x00, x01), xmax = max(x10, x11);

        int i0 = fixed2int(xmin) - ll->bbox_left, i;
        int i1 = fixed2int_ceiling(xmax) - ll->bbox_left;

        for (i = i0; i < i1; i++) {
            section *s = &sect[i];
            int x_pixel = int2fixed(i + ll->bbox_left);
            int xl = max(xmin - x_pixel, 0);
            int xu = min(xmax - x_pixel, fixed_1);

            s->x0 = min(s->x0, xl);
            s->x1 = max(s->x1, xu);
            x_pixel+=0; /* Just a place for breakpoint */
        }
        code = store_margin(ll, set, i0, i1);
        if (code < 0)
            return code;
        /* fixme : after ADJUST_SERIF becames permanent,
         * don't call margin_boundary if yy0 > yy1.
         */
    }
#   endif

    code = margin_boundary(ll, set, flp, 0, 0, yy0, yy1, 1, y0, y1);
    if (code < 0)
        return code;
    return margin_boundary(ll, set, alp, 0, 0, yy0, yy1, -1, y0, y1);
}
Пример #6
0
/* Note that the arguments are fixeds, not ints! */
int
gz_fill_trapezoid_fixed(fixed fx0, fixed fw0, fixed fy0,
  fixed fx1, fixed fw1, fixed fh, int swap_axes,
  gx_device_color *pdevc, gs_state *pgs)
{	/* For the moment, we just convert everything to ints. */
	/* Later we will do the right thing with fractional pixels. */
	int x0 = fixed2int(fx0);
	fixed fx0r = fx0 + fw0;
	int w0 = fixed2int_ceiling(fx0r) - x0;
	int y0 = fixed2int(fy0);
	int x1 = fixed2int(fx1);
	fixed fx1r = fx1 + fw1;
	int w1 = fixed2int_ceiling(fx1r) - x1;
	fixed fy1 = fy0 + fh;
	int y1 = fixed2int_ceiling(fy1);
	int h = y1 - y0;
	if ( w0 == 0 && w1 == 0 || h <= 0 ) return 0;
	if ( !swap_axes && color_is_pure(pdevc) )
	   {	gx_device *dev = pgs->device->info;
		if ( (*dev->procs->fill_trapezoid)(dev,
			x0, y0, w0, x1, y1, w1,
			pdevc->color1) >= 0
		   )
			return 0;
	   }
	   {	int xl, fxl;
		int dxl, dxl1, dxlf = x1 - x0;
		int xr, fxr;
		int dxr, dxr1, dxrf = x1 + w1 - (x0 + w0);
		int y = y0;
		int rxl, rxr, ry;
		/* Compute integer and fractional deltas */
#define reduce_delta(df, d, d1, pos)\
	if ( df >= 0 )\
	   {	if ( df >= h )\
		  d1 = (d = df / h) + 1, df -= d * h;\
		else	/* save the divides */\
		   {	pos();\
			d = 0, d1 = 1;\
		   }\
	   }\
	else			/* df < 0 */\
	   {	if ( df <= -h )\
		  d1 = (d = df / h) - 1, df = d * h - df;\
		else	/* save the divides */\
		  d = 0, d1 = -1, df = -df;\
	   }
#define fill_trap_rect(x,y,w,h)\
  if ( swap_axes ) gz_fill_rectangle(y, x, h, w, pdevc, pgs);\
  else gz_fill_rectangle(x, y, w, h, pdevc, pgs)
#define pos_for_xl()			/* nothing */
		reduce_delta(dxlf, dxl, dxl1, pos_for_xl);
#define pos_for_xr()\
	if ( dxl == 0 && dxlf == 0 && dxrf == 0 )  /* detect rectangle */\
	   {	fill_trap_rect(x0, y0, w0, h);\
		return 0;\
	   }
		reduce_delta(dxrf, dxr, dxr1, pos_for_xr);
		xl = x0, fxl = arith_rshift(dxlf, 1);
		xr = x0 + w0, fxr = arith_rshift(dxrf, 1);
		rxl = xl, rxr = xr, ry = y;
		/* Do the fill */
		do
		   {	if ( xl != rxl || xr != rxr )	/* detect rectangles */
			   {	fill_trap_rect(rxl, ry, rxr - rxl, y - ry);
				rxl = xl, rxr = xr, ry = y;
			   }
			if ( (fxl += dxlf) >= h ) fxl -= h, xl += dxl1;
			else xl += dxl;
			if ( (fxr += dxrf) >= h ) fxr -= h, xr += dxr1;
			else xr += dxr;
		   }
		while ( ++y < y1 );
		if ( y != ry )
		   {	fill_trap_rect(rxl, ry, rxr - rxl, y - ry);
		   }
#undef fill_trap_rect
	   }
	return 0;
}
Пример #7
0
int 
gx_default_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
	int i0, int j, int w,
	const frac31 *c0, const int32_t *c0f, const int32_t *cg_num, int32_t cg_den)
{
    /* This default implementation decomposes the area into constant color rectangles.
       Devices may supply optimized implementations with
       the inversed nesting of the i,k cicles,
       i.e. with enumerating planes first, with a direct writing to the raster,
       and with a fixed bits per component.
     */
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
    int i, i1 = i0 + w, bi = i0, k;
    gx_color_index ci0 = 0, ci1;
    const gx_device_color_info *cinfo = &dev->color_info;
    int n = cinfo->num_components;
    int si, ei, code;

    if (j < fixed2int(fa->clip->p.y) ||
	    j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
	return 0;
    for (k = 0; k < n; k++) {
	int shift = cinfo->comp_shift[k];
	int bits = cinfo->comp_bits[k];

	c[k] = c0[k];
	f[k] = c0f[k];
	ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
    }
    for (i = i0 + 1; i < i1; i++) {
	ci1 = 0;
	for (k = 0; k < n; k++) {
	    int shift = cinfo->comp_shift[k];
	    int bits = cinfo->comp_bits[k];
	    int32_t m = f[k] + cg_num[k];

	    c[k] += m / cg_den;
	    m -= m / cg_den * cg_den;
	    if (m < 0) {
		c[k]--;
		m += cg_den;
	    }
	    f[k] = m;
	    ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
	}
	if (ci1 != ci0) {
	    si = max(bi, fixed2int(fa->clip->p.x));	    /* Must be compatible to the clipping logic. */
	    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
	    if (si < ei) {
		
		if (fa->swap_axes) {
		    vd_rect(int2fixed(j), int2fixed(si), int2fixed(j + 1), int2fixed(ei), 1, (ulong)ci0);
		    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
		} else {
		    vd_rect(int2fixed(si), int2fixed(j), int2fixed(ei), int2fixed(j + 1), 1, (ulong)ci0);
		    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
		}
		if (code < 0)
		    return code;
	    }
	    bi = i;
	    ci0 = ci1;
	}
    }
    si = max(bi, fixed2int(fa->clip->p.x));	    /* Must be compatible to the clipping logic. */
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
    if (si < ei) {
	if (fa->swap_axes) {
	    vd_rect(int2fixed(j), int2fixed(si), int2fixed(j + 1), int2fixed(ei), 1, (ulong)ci0);
	    return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
	} else {
	    vd_rect(int2fixed(si), int2fixed(j), int2fixed(ei), int2fixed(j + 1), 1, (ulong)ci0);
	    return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
	}
    }
    return 0;
}