예제 #1
0
int
gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev,
                                const gs_pdf14trans_params_t * pparams)
{
    gs_transparency_group_params_t tgp = {0};
    gs_rect bbox;

    if (pparams->Background_components != 0 &&
        pparams->Background_components != pdev->color_info.num_components)
        return_error(gs_error_rangecheck);
    tgp.Isolated = pparams->Isolated;
    tgp.Knockout = pparams->Knockout;
    tgp.idle = pparams->idle;
    tgp.mask_id = pparams->mask_id;

    /* Needed so that we do proper blending */
    tgp.group_color = pparams->group_color;
    tgp.group_color_numcomps = pparams->group_color_numcomps;
    tgp.iccprofile = pparams->iccprofile;
    tgp.icc_hashcode = pparams->icc_hash;

    pgs->opacity.alpha = pparams->opacity.alpha;
    pgs->shape.alpha = pparams->shape.alpha;
    pgs->blend_mode = pparams->blend_mode;
    bbox = pparams->bbox;
#ifdef DEBUG
    if (gs_debug_c('v')) {
        static const char *const cs_names[] = {
            GS_COLOR_SPACE_TYPE_NAMES
        };
        dmlprintf6(pdev->memory, "[v](0x%lx)gx_begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n",
                  (ulong)pgs, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y,
                        pparams->group_color_numcomps);
        if (tgp.ColorSpace)
            dmprintf1(pdev->memory, "     CS = %s",
                cs_names[(int)gs_color_space_get_index(tgp.ColorSpace)]);
        else
            dmputs(pdev->memory, "     (no CS)");
        dmprintf2(pdev->memory, "  Isolated = %d  Knockout = %d\n",
                 tgp.Isolated, tgp.Knockout);
        if (tgp.iccprofile)
            dmprintf(pdev->memory, "     Have ICC Profile for blending\n");
    }
#endif
    if (dev_proc(pdev, begin_transparency_group) != 0)
        return (*dev_proc(pdev, begin_transparency_group)) (pdev, &tgp, &bbox, pgs,
                                                            NULL);
    else
        return 0;
}
예제 #2
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;
}
예제 #3
0
int
gs_push_pdf14trans_device(gs_state * pgs, bool is_pattern)
{
    gs_pdf14trans_params_t params = { 0 };
    cmm_profile_t *icc_profile;
    gsicc_rendering_intents_t rendering_intent;
    int code;
    cmm_dev_profile_t *dev_profile;

    code = dev_proc(pgs->device, get_profile)(pgs->device,  &dev_profile);
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
                          &rendering_intent);

    params.pdf14_op = PDF14_PUSH_DEVICE;
    /*
     * We really only care about the number of spot colors when we have
     * a device which supports spot colors.  With the other devices we use
     * the tint transform function for DeviceN and Separation color spaces
     * and convert spot colors into process colors.
     */
    params.num_spot_colors = get_num_pdf14_spot_colors(pgs);
    params.is_pattern = is_pattern;
    /* If we happen to be in a situation where we are going out to a device
       whose profile is CIELAB then we will need to make sure that we
       do our blending in RGB and convert to CIELAB when we do the put_image
       command */
    if (icc_profile->data_cs == gsCIELAB ||
        icc_profile->islab) {
        params.iccprofile = pgs->icc_manager->default_rgb;
    }
    /* Note: Other parameters not used */
    return gs_state_update_pdf14trans(pgs, &params);
}
예제 #4
0
/*
 * We really only care about the number of spot colors when we have
 * a device which supports spot colors.  With the other devices we use
 * the tint transform function for DeviceN and Separation color spaces
 * and convert spot colors into process colors.
 */
static int
get_num_pdf14_spot_colors(gs_state * pgs)
{
    gx_device * dev = pgs->device;
    gs_devn_params * pclist_devn_params = dev_proc(dev, ret_devn_params)(dev);

    /*
     * Devices which support spot colors store the PageSpotColors device
     * parameter inside their devn_params structure.  (This is done by the
     * devn_put_params routine.)  The PageSpotColors device parameter is
     * set by pdf_main whenever a PDF page is being processed.  See
     * countspotcolors in lib/pdf_main.ps.
     */
    if (pclist_devn_params != NULL) {
        /* If the sep order names were specified, then we should only allocate
           for those.  But only the nonstandard colorants that are stored
           in num_separations.  See devn_put_params for details on this.
           Right now, the PDF14 device will always include CMYK.  A future
           optimization is to be able to NOT have those included in the buffer
           allocations if we don't specify them.  It would then be possible to
           output 8 separations at a time without using compressed color. */
        if (pclist_devn_params->num_separation_order_names == 0) {
            return pclist_devn_params->page_spot_colors;
        }
        return (pclist_devn_params->separations.num_separations);
    }
    return 0;
}
예제 #5
0
파일: gschar.c 프로젝트: ststeiger/ghostsvg
/*
 * Force the enumerator to be a gs_show_enum *, which the current
 * implementation code requires.
 */
static int
show_n_begin(gs_show_enum *penum, gs_state *pgs, int code, gs_text_enum_t *pte)
{
    if (code < 0)
	return code;
    if (gs_object_type(pgs->memory, pte) != &st_gs_show_enum) {
	/* Use the default implementation. */
	gx_device *dev = pgs->device;
	gs_text_params_t text;
	gs_memory_t *mem = pte->memory;
	dev_proc_text_begin((*text_begin)) = dev_proc(dev, text_begin);

	text = pte->text;
	gs_text_release(pte, "show_n_begin");
	/* Temporarily reset the text_begin procedure to the default. */
	set_dev_proc(dev, text_begin, gx_default_text_begin);
	code = gs_text_begin(pgs, &text, mem, &pte);
	set_dev_proc(dev, text_begin, text_begin);
	if (code < 0)
	    return code;
    }
    /* Now we know pte points to a gs_show_enum. */
    *penum = *(gs_show_enum *)pte;
    gs_free_object(pgs->memory, pte, "show_n_begin");
    return code;
}
예제 #6
0
static int
xps_remap_pattern(const gs_client_color *pcc, gs_state *pgs)
{
    const gs_client_pattern *ppat = gs_getpattern(pcc);
    struct tile_closure_s *c = ppat->client_data;
    xps_context_t *ctx = c->ctx;
    int code;

    /* pgs->device is the newly created pattern accumulator, but we want to test the device
     * that is 'behind' that, the actual output device, so we use the one from
     * the saved XPS graphics state.
     */
    code = dev_proc(ctx->pgs->device, dev_spec_op)(ctx->pgs->device,
                                gxdso_pattern_can_accum, ppat, ppat->uid.id);

    if (code == 1) {
        /* Device handles high-level patterns, so return 'remap'.
         * This closes the internal accumulator device, as we no longer need
         * it, and the error trickles back up to the PDL client. The client
         * must then take action to start the device's accumulator, draw the
         * pattern, close the device's accumulator and generate a cache entry.
         */
        return gs_error_Remap_Color;
    } else {
        code = xps_paint_tiling_brush(pcc, pgs);
        if (code)
            return gs_rethrow(code, "remap pattern brush function failed");
        return 0;
    }
}
예제 #7
0
/*
 * We need to forward the color mapping to the target device.
 */
static void
fwd_map_cmyk_cs(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device * const tdev = fdev->target;
    const gx_cm_color_map_procs * pprocs;

    /* Verify that all of the pointers and procs are set */
    /* If not then use a default routine.  This case should be an error */
    if (tdev == 0 || dev_proc(tdev, get_color_mapping_procs) == 0 ||
          (pprocs = dev_proc(tdev, get_color_mapping_procs(tdev))) == 0 ||
          pprocs->map_cmyk == 0)
        cmyk_cs_to_cmyk_cm(tdev, c, m, y, k, out);   /* if all else fails */
    else
        pprocs->map_cmyk(tdev, c, m, y, k, out);
}
예제 #8
0
int
gx_dc_pure_get_nonzero_comps(
    const gx_device_color * pdevc,
    const gx_device *       dev,
    gx_color_index *        pcomp_bits )
{
    int                     code;
    gx_color_value          cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];

    code = dev_proc(dev, decode_color)( (gx_device *)dev,
                                         pdevc->colors.pure,
                                         cvals );
    if (code >= 0) {
        int             i, ncomps = dev->color_info.num_components;
        gx_color_index  mask = 0x1, comp_bits = 0;

        for (i = 0; i < ncomps; i++, mask <<= 1) {
            if (cvals[i] != 0)
                comp_bits |= mask;
        }
        *pcomp_bits = comp_bits;
        code = 0;
    }

    return code;
}
예제 #9
0
/* Write the BMP file header. */
int
write_bmp_header(gx_device_printer *pdev, FILE *file)
{
    int depth = pdev->color_info.depth;
    bmp_quad palette[256];

    if (depth <= 8) {
	int i;
	gx_color_value rgb[3];
	bmp_quad q;

	q.reserved = 0;
	for (i = 0; i != 1 << depth; i++) {
	    /* Note that the use of map_color_rgb is deprecated in
	       favor of decode_color. This should work, though, because
	       backwards compatibility is preserved. */
	    (*dev_proc(pdev, map_color_rgb))((gx_device *)pdev,
					     (gx_color_index)i, rgb);
	    q.red = gx_color_value_to_byte(rgb[0]);
	    q.green = gx_color_value_to_byte(rgb[1]);
	    q.blue = gx_color_value_to_byte(rgb[2]);
	    palette[i] = q;
	}
    }
    return write_bmp_depth_header(pdev, file, depth, (const byte *)palette,
				  gdev_prn_raster(pdev));
}
예제 #10
0
/* Intersect a clipping path a shading BBox. */
int
gx_dc_pattern2_clip_with_bbox(const gx_device_color * pdevc, gx_device * pdev,
                              gx_clip_path *cpath_local, const gx_clip_path **ppcpath1)
{
    if (gx_dc_is_pattern2_color(pdevc) && gx_dc_pattern2_color_has_bbox(pdevc) &&
            (*dev_proc(pdev, dev_spec_op))(pdev, gxdso_pattern_shading_area, NULL, 0) == 0) {
        gs_pattern2_instance_t *pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
        gx_path box_path;
        gs_memory_t *mem = (*ppcpath1 != NULL ? (*ppcpath1)->path.memory : pdev->memory);
        int code;

        gx_path_init_local(&box_path, mem);
        code = gx_dc_shading_path_add_box(&box_path, pdevc);
        if (code == gs_error_limitcheck) {
            /* Ignore huge BBox - bug 689027. */
            code = 0;
        } else {
            if (code >= 0) {
                gx_cpath_init_local_shared(cpath_local, *ppcpath1, mem);
                code = gx_cpath_intersect(cpath_local, &box_path, gx_rule_winding_number, (gs_imager_state *)pinst->saved);
                *ppcpath1 = cpath_local;
            }
        }
        gx_path_free(&box_path, "gx_default_fill_path(path_bbox)");
    }
    return 0;
}
예제 #11
0
int
pl_end_image(gs_state * pgs, void *info, bool draw_last)
{
    gx_device *dev = pgs->device;

    return (*dev_proc(dev, end_image)) (dev, info, draw_last);
}
예제 #12
0
static int
bbox_fill_mask(gx_device * dev,
	       const byte * data, int dx, int raster, gx_bitmap_id id,
	       int x, int y, int w, int h,
	       const gx_drawing_color * pdcolor, int depth,
	       gs_logical_operation_t lop, const gx_clip_path * pcpath)
{
    gx_device_bbox *const bdev = (gx_device_bbox *) dev;
    gx_device *tdev = bdev->target;
    /* Skip the call if there is no target. */
    int code =
	(tdev == 0 ? 0 :
	 dev_proc(tdev, fill_mask)
	 (tdev, data, dx, raster, id, x, y, w, h,
	  pdcolor, depth, lop, pcpath));

    if (pcpath != NULL &&
	!gx_cpath_includes_rectangle(pcpath, int2fixed(x), int2fixed(y),
				     int2fixed(x + w),
				     int2fixed(y + h))
	) {
	/* Let the target do the drawing, but break down the */
	/* image into pieces for computing the bounding box. */
	bdev->target = NULL;
	gx_default_fill_mask(dev, data, dx, raster, id, x, y, w, h,
			     pdcolor, depth, lop, pcpath);
	bdev->target = tdev;
    } else {
	/* Just use the mask bounding box. */
	BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h);
    }
    return code;
}
예제 #13
0
static int
bbox_draw_thin_line(gx_device * dev,
		    fixed fx0, fixed fy0, fixed fx1, fixed fy1,
		    const gx_device_color * pdevc, gs_logical_operation_t lop,
		    fixed adjustx, fixed adjusty)
{
    gx_device_bbox *const bdev = (gx_device_bbox *) dev;
    /* Skip the call if there is no target. */
    gx_device *tdev = bdev->target;
    int code =
	(tdev == 0 ? 0 :
	 dev_proc(tdev, draw_thin_line)
	 (tdev, fx0, fy0, fx1, fy0, pdevc, lop, adjustx, adjusty));

    if (!GX_DC_IS_TRANSPARENT(pdevc, bdev)) {
	fixed xmin, ymin, xmax, ymax;

	/* bbox_add_rect requires points in correct order. */
#define SET_MIN_MAX(vmin, vmax, av, bv)\
  BEGIN\
    if (av < bv)\
	vmin = av, vmax = bv;\
    else\
	vmin = bv, vmax = av;\
  END
	SET_MIN_MAX(xmin, xmax, fx0, fx1);
	SET_MIN_MAX(ymin, ymax, fy0, fy1);
#undef SET_MIN_MAX
	BBOX_ADD_RECT(bdev, xmin, ymin, xmax, ymax);
    }
    return code;
}
예제 #14
0
/* Initialize a Type 1 interpreter. */
static int
type1_exec_init(gs_type1_state *pcis, gs_text_enum_t *penum,
                gs_state *pgs, gs_font_type1 *pfont1)
{
    /*
     * We have to disregard penum->pis and penum->path, and render to
     * the current gstate and path.  This is a design bug that we will
     * have to address someday!
     */

    int alpha_bits = 1;
    gs_log2_scale_point log2_subpixels;

    if (color_is_pure(gs_currentdevicecolor_inline(pgs))) /* Keep consistency with alpha_buffer_bits() */
        alpha_bits = (*dev_proc(pgs->device, get_alpha_bits)) (pgs->device, go_text);
    if (alpha_bits <= 1) {
        /* We render to cache device or the target device has no alpha bits. */
        log2_subpixels = penum->log2_scale;
    } else {
        /* We'll render to target device through alpha buffer. */
        /* Keep consistency with alpha_buffer_init() */
        log2_subpixels.x = log2_subpixels.y = ilog2(alpha_bits);
    }
    return gs_type1_interp_init(pcis, (gs_imager_state *)pgs, pgs->path,
                                &penum->log2_scale, &log2_subpixels,
                                (penum->text.operation & TEXT_DO_ANY_CHARPATH) != 0 ||
                                penum->device_disabled_grid_fitting,
                                pfont1->PaintType, pfont1);
}
예제 #15
0
/* If the color is already concretized, then we are in the color space
   defined by the device profile.  The remaining things to do would
   be to potentially apply alpha, apply the transfer function, and
   do any halftoning.  The remap is based upon the ICC profile defined
   in the device profile entry of the profile manager. */
int
gx_remap_concrete_ICC(const frac * pconc, const gs_color_space * pcs,
        gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
                          gs_color_select_t select)
{
    int num_colorants;
    int code;
    cmm_dev_profile_t *dev_profile;

    code = dev_proc(dev, get_profile)(dev, &dev_profile);
    num_colorants = gsicc_get_device_profile_comps(dev_profile);
    switch( num_colorants ) {
        case 1:
            code = gx_remap_concrete_DGray(pconc, pcs, pdc, pgs, dev, select);
            break;
        case 3:
            code = gx_remap_concrete_DRGB(pconc, pcs, pdc, pgs, dev, select);
            break;
        case 4:
            code = gx_remap_concrete_DCMYK(pconc, pcs, pdc, pgs, dev, select);
            break;
        default:
            /* This is a special case where we have a source color and our
               output profile must be DeviceN.   We will need to map our
               colorants to the proper planes */
            code = gx_remap_concrete_icc_devicen(pconc, pcs, pdc, pgs, dev, select);
            break;
        }
    return code;
    }
예제 #16
0
/* Render an array of saved pages. */
int
gdev_prn_render_pages(gx_device_printer * pdev,
		      const gx_placed_page * ppages, int count)
{
    gx_device_clist_reader * const pcldev =
	(gx_device_clist_reader *)pdev;

    /* Check to make sure the pages are compatible with the device. */
    {
	int i;

	for (i = 0; i < count; ++i) {
	    const gx_saved_page *page = ppages[i].page;

	    /* We would like to fully check the color representation, */
	    /* but we don't have enough information to do that. */
	    if (strcmp(page->dname, pdev->dname) != 0 ||
		memcmp(&page->device.color_info, &pdev->color_info,
		       sizeof(pdev->color_info)) != 0
		)
		return_error(gs_error_rangecheck);
	    /* Currently we don't allow translation in Y. */
	    if (ppages[i].offset.y != 0)
		return_error(gs_error_rangecheck);
	    /* Make sure the band parameters are compatible. */
	    if (page->info.band_params.BandBufferSpace !=
		pdev->buffer_space ||
		page->info.band_params.BandWidth !=
		pdev->width
		)
		return_error(gs_error_rangecheck);
	    /* Currently we require all band heights to be the same. */
	    if (i > 0 && page->info.band_params.BandHeight != 
			 ppages[0].page->info.band_params.BandHeight)
		return_error(gs_error_rangecheck);
	}
    }
    /* Set up the page list in the device. */
    /****** SHOULD FACTOR THIS OUT OF clist_render_init ******/
    pcldev->ymin = pcldev->ymax = 0;
    pcldev->pages = ppages;
    pcldev->num_pages = count;
    pcldev->offset_map = NULL;
    /* Render the pages. */
    {
	int code = (*dev_proc(pdev, output_page))
	    ((gx_device *) pdev, ppages[0].page->num_copies, true);

	/* Delete the temporary files. */
	int i;

	for (i = 0; i < count; ++i) {
	    const gx_saved_page *page = ppages[i].page;

	    pcldev->page_info.io_procs->unlink(page->info.cfname);
	    pcldev->page_info.io_procs->unlink(page->info.bfname);
	}
	return code;
    }
}
예제 #17
0
int
gx_forward_dev_spec_op(gx_device * dev, int dev_spec_op, void *data, int size)
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    /* Note that clist sets fdev->target == fdev,
       so this function is unapplicable to clist. */
    if (tdev == 0) {
        if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) {
            return (dev->procs.fill_path == gx_default_fill_path);
        }
        return gs_error_undefined;
    } else if (dev_spec_op == gxdso_pattern_handles_clip_path) {
        if (dev->procs.fill_path == gx_default_fill_path)
            return 0;
    } else if (dev_spec_op == gxdso_device_child) {
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
        if (d->target == dev) {
            d->target = fdev->target;
            return 1;
        }
    }
    return dev_proc(tdev, dev_spec_op)(tdev, dev_spec_op, data, size);
}
예제 #18
0
/* Check whether color is a shading with BBox. */
int
gx_dc_pattern2_is_rectangular_cell(const gx_device_color * pdevc, gx_device * pdev, gs_fixed_rect *rect)
{
    if (gx_dc_is_pattern2_color(pdevc) && gx_dc_pattern2_color_has_bbox(pdevc) &&
            (*dev_proc(pdev, dev_spec_op))(pdev, gxdso_pattern_shading_area, NULL, 0) == 0) {
        gs_pattern2_instance_t *pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
        const gs_shading_t *psh = pinst->templat.Shading;
        gs_fixed_point p, q;

        if (is_xxyy(&ctm_only(pinst->saved)))
            if (psh->params.have_BBox) {
                int code = gs_point_transform2fixed(&pinst->saved->ctm,
                            psh->params.BBox.p.x, psh->params.BBox.p.y, &p);
                if (code < 0)
                    return code;
                code = gs_point_transform2fixed(&pinst->saved->ctm,
                            psh->params.BBox.q.x, psh->params.BBox.q.y, &q);
                if (code < 0)
                    return code;
                if (p.x > q.x) {
                    p.x ^= q.x; q.x ^= p.x; p.x ^= q.x;
                }
                if (p.y > q.y) {
                    p.y ^= q.y; q.y ^= p.y; p.y ^= q.y;
                }
                rect->p = p;
                rect->q = q;
                return 1;
            }
    }
    return 0;
}
예제 #19
0
/* Check whether we need to call out to create the page device dictionary. */
static bool
save_page_device(gs_state *pgs)
{
    return
        (r_has_type(&gs_int_gstate(pgs)->pagedevice, t_null) &&
         (*dev_proc(gs_currentdevice(pgs), get_page_device))(gs_currentdevice(pgs)) != 0);
}
예제 #20
0
static int
bbox_create_compositor(gx_device * dev,
		       gx_device ** pcdev, const gs_composite_t * pcte,
		       gs_imager_state * pis, gs_memory_t * memory, gx_device *cindev)
{
    gx_device_bbox *const bdev = (gx_device_bbox *) dev;
    gx_device *target = bdev->target;

    /*
     * If there isn't a target, all we care about is the bounding box,
     * so don't bother with actually compositing.
     */
    if (target == 0) {
	*pcdev = dev;
	return 0;
    }
    /*
     * Create a compositor for the target, and then wrap another
     * bbox device around it, but still accumulating the bounding
     * box in the same place.
     */
    {
	gx_device *temp_cdev;
	gx_device_bbox *bbcdev;
	int code = (*dev_proc(target, create_compositor))
	    (target, &temp_cdev, pcte, pis, memory, cindev);

	/* If the target did not create a new compositor then we are done. */
	if (code < 0 || target == temp_cdev) {
	    *pcdev = dev;
	    return code;
	}
	bbcdev = gs_alloc_struct_immovable(memory, gx_device_bbox,
					   &st_device_bbox,
					   "bbox_create_compositor");
	if (bbcdev == 0) {
	    (*dev_proc(temp_cdev, close_device)) (temp_cdev);
	    return_error(gs_error_VMerror);
	}
	gx_device_bbox_init(bbcdev, target, memory);
	gx_device_set_target((gx_device_forward *)bbcdev, temp_cdev);
	bbcdev->box_procs = box_procs_forward;
	bbcdev->box_proc_data = bdev;
	*pcdev = (gx_device *) bbcdev;
	return 0;
    }
}
예제 #21
0
/*
 * We need to forward the color mapping to the target device.
 */
static void
fwd_map_rgb_cs(gx_device * dev, const gs_imager_state *pis,
				   frac r, frac g, frac b, frac out[])
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device * const tdev = fdev->target;
    const gx_cm_color_map_procs * pprocs;

    /* Verify that all of the pointers and procs are set */
    /* If not then use a default routine.  This case should be an error */
    if (tdev == 0 || dev_proc(tdev, get_color_mapping_procs) == 0 ||
          (pprocs = dev_proc(tdev, get_color_mapping_procs(tdev))) == 0 ||
          pprocs->map_rgb == 0)
        rgb_cs_to_rgb_cm(tdev, pis, r, g, b, out);   /* if all else fails */
    else
        pprocs->map_rgb(tdev, pis, r, g, b, out);
}
예제 #22
0
/* Install a DeviceN color space. */
static int
gx_install_DeviceN(gs_color_space * pcs, gs_state * pgs)
{
    int code;
    code = check_DeviceN_component_names(pcs, pgs);
    if (code < 0)
       return code;
    /* See if we have an ICC profile that we can associate with
       this DeviceN color space */
    if (pgs->icc_manager->device_n != NULL) {
        /* An nclr profile is in the manager.  Grab one that matches. */
        cmm_profile_t *profdata = gsicc_finddevicen(pcs, pgs->icc_manager);
        if (profdata != NULL)
            rc_increment(profdata);
        if (pcs->cmm_icc_profile_data != NULL)
            rc_decrement(pcs->cmm_icc_profile_data, "gx_install_DeviceN");
        pcs->cmm_icc_profile_data = profdata;
    }
    /* {csrc} was pgs->color_space->params.device_n.use_alt_cspace */
    ((gs_color_space *)pcs)->params.device_n.use_alt_cspace =
        using_alt_color_space(pgs);
    if (pcs->params.device_n.use_alt_cspace && pcs->cmm_icc_profile_data == NULL ) {
        /* No nclr ICC profile */
        code = (pcs->base_space->type->install_cspace)
            (pcs->base_space, pgs);
    } else if (pcs->params.device_n.use_alt_cspace) {
        gs_color_space *nclr_pcs;
        /* Need to install the nclr cspace */
        code = gs_cspace_build_ICC(&nclr_pcs, NULL, pgs->memory);
        nclr_pcs->cmm_icc_profile_data = pcs->cmm_icc_profile_data;
        rc_increment(pcs->cmm_icc_profile_data);
        rc_increment_cs(nclr_pcs); /* Suspicious - RJW */
        rc_decrement_cs(pcs->base_space, "gx_install_DeviceN");
        pcs->base_space = nclr_pcs;
    }
    /*
     * Give the device an opportunity to capture equivalent colors for any
     * spot colors which might be present in the color space.
     */
    if (code >= 0) {
        if (dev_proc(pgs->device, update_spot_equivalent_colors))
            code = dev_proc(pgs->device, update_spot_equivalent_colors)
                                                        (pgs->device, pgs);
    }
    return code;
}
예제 #23
0
/* Note that we treat this as "texture" for RasterOp. */
static int
tile_colored_fill(const tile_fill_state_t * ptfs,
                  int x, int y, int w, int h)
{
    gx_color_tile *ptile = ptfs->pdevc->colors.pattern.p_tile;
    gs_logical_operation_t lop = ptfs->lop;
    const gx_rop_source_t *source = ptfs->source;
    const gx_rop_source_t *rop_source = ptfs->rop_source;
    gx_device *dev = ptfs->orig_dev;
    int xoff = ptfs->xoff, yoff = ptfs->yoff;
    gx_strip_bitmap *bits = &ptile->tbits;
    const byte *data = bits->data;
    bool full_transfer = (w == ptfs->w0 && h == ptfs->h0);
    gx_bitmap_id source_id =
    (full_transfer ? rop_source->id : gx_no_bitmap_id);
    int code;

    if (source == NULL && lop_no_S_is_T(lop))
        code = (*dev_proc(ptfs->pcdev, copy_color))
            (ptfs->pcdev, data + bits->raster * yoff, xoff,
             bits->raster,
             (full_transfer ? bits->id : gx_no_bitmap_id),
             x, y, w, h);
    else {
        gx_strip_bitmap data_tile;

        data_tile.data = (byte *) data;         /* actually const */
        data_tile.raster = bits->raster;
        data_tile.size.x = data_tile.rep_width = ptile->tbits.size.x;
        data_tile.size.y = data_tile.rep_height = ptile->tbits.size.y;
        data_tile.id = bits->id;
        data_tile.shift = data_tile.rep_shift = 0;
        code = (*dev_proc(dev, strip_copy_rop))
            (dev,
             rop_source->sdata + (y - ptfs->y0) * rop_source->sraster,
             rop_source->sourcex + (x - ptfs->x0),
             rop_source->sraster, source_id,
             (rop_source->use_scolors ? rop_source->scolors : NULL),
             &data_tile, NULL,
             x, y, w, h,
             imod(xoff - x, data_tile.rep_width),
             imod(yoff - y, data_tile.rep_height),
             lop);
    }
    return code;
}
예제 #24
0
gx_color_index
gx_forward_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    return (tdev == 0 ? gx_default_map_cmyk_color(dev, cv) :
	    dev_proc(tdev, map_cmyk_color)(tdev, cv));
}
예제 #25
0
/* Get hardware-detected params. Drain page queue, then call renderer version */
static int
gdev_prn_async_write_get_hardware_params(gx_device * pdev, gs_param_list * plist)
{
    gx_device_printer *const pwdev = (gx_device_printer *) pdev;
    gx_device_printer *const prdev = pwdev->async_renderer;

    if (!pwdev->is_open || !prdev)
        /* if not open, just use device's get hw params */
        return (dev_proc(pwdev, get_hardware_params))(pdev, plist);
    else {
        /* wait for empty pipeline */
        gx_page_queue_wait_until_empty(pwdev->page_queue);

        /* get reader's h/w params, now that writer & reader are sync'ed */
        return (dev_proc(prdev, get_hardware_params))
            ((gx_device *) prdev, plist);
    }
}
예제 #26
0
int
gx_forward_sync_output(gx_device * dev)
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    return (tdev == 0 ? gx_default_sync_output(dev) :
	    dev_proc(tdev, sync_output)(tdev));
}
예제 #27
0
int
gx_forward_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    return (tdev == 0 ? gx_default_get_bits(dev, y, data, actual_data) :
	    dev_proc(tdev, get_bits)(tdev, y, data, actual_data));
}
예제 #28
0
gx_device *
gx_forward_get_xfont_device(gx_device * dev)
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    return (tdev == 0 ? gx_default_get_xfont_device(dev) :
	    dev_proc(tdev, get_xfont_device)(tdev));
}
예제 #29
0
int
gx_forward_get_hardware_params(gx_device * dev, gs_param_list * plist)
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    return (tdev == 0 ? gx_default_get_hardware_params(dev, plist) :
	    dev_proc(tdev, get_hardware_params)(tdev, plist));
}
예제 #30
0
gx_color_index
gx_forward_encode_color(gx_device * dev, const gx_color_value colors[])
{
    gx_device_forward * const fdev = (gx_device_forward *)dev;
    gx_device *tdev = fdev->target;

    return (tdev == 0 ? gx_error_encode_color(dev, colors)
		      : dev_proc(tdev, encode_color)(tdev, colors));
}