Exemplo n.º 1
0
/* shfill */
int
gs_shfill(gs_state * pgs, const gs_shading_t * psh)
{
    /*
     * shfill is equivalent to filling the current clipping path (or, if
     * clipping, its bounding box) with the shading, disregarding the
     * Background if any.  In order to produce reasonable high-level output,
     * we must actually implement this by calling gs_fill rather than
     * gs_shading_fill_path.  However, filling with a shading pattern does
     * paint the Background, so if necessary, we construct a copy of the
     * shading with Background removed.
     */
    gs_pattern2_template_t pat;
    gx_path cpath;
    gs_matrix imat;
    gs_client_color cc;
    gs_color_space cs;
    gx_device_color devc;
    int code;

    gs_pattern2_init(&pat);
    pat.Shading = psh;
    gs_make_identity(&imat);
    code = gs_make_pattern(&cc, (gs_pattern_template_t *)&pat, &imat, pgs,
			   pgs->memory);
    if (code < 0)
	return code;
    code = gs_pattern2_set_shfill(&cc);
    if (code < 0)
	return code;
    gs_cspace_init(&cs, &gs_color_space_type_Pattern, pgs->memory, false);
    cs.params.pattern.has_base_space = false;
    code = cs.type->remap_color(&cc, &cs, &devc, (gs_imager_state *)pgs,
				pgs->device, gs_color_select_texture);
    if (code >= 0) {
	gx_path_init_local(&cpath, pgs->memory);
	code = gx_cpath_to_path(pgs->clip_path, &cpath);
	if (code >= 0)
	    code = gx_fill_path(&cpath, &devc, pgs, gx_rule_winding_number,
				fixed_0, fixed_0);
	gx_path_free(&cpath, "gs_shfill");
    }
    gs_pattern_reference(&cc, -1);
    return code;
}
Exemplo n.º 2
0
/* shfill */
int
gs_shfill(gs_gstate * pgs, const gs_shading_t * psh)
{
    /*
     * shfill is equivalent to filling the current clipping path (or, if
     * clipping, its bounding box) with the shading, disregarding the
     * Background if any.  In order to produce reasonable high-level output,
     * we must implement this by calling gs_fill_path.
     */
    gs_pattern2_template_t pat;
    gs_matrix imat;
    gs_client_color cc;
    gs_color_space *pcs;
    gx_device_color devc;
    int code;

    /* Must install the shading color space
       to allow check_DeviceN_component_names initialize
       the color component map.
     */
    /* Don't bother with saving the old color space, color,
       and cie_joint_caches,
       because .shfill is always called within gsave-grestore -
       see gs/lib . */
    code = gs_setcolorspace(pgs, psh->params.ColorSpace);
    if (code < 0)
        return 0;
    if (psh->params.cie_joint_caches != NULL) {
        pgs->cie_joint_caches = psh->params.cie_joint_caches;
        rc_increment(pgs->cie_joint_caches);
    }
    gs_pattern2_init(&pat);
    pat.Shading = psh;
    gs_make_identity(&imat);
    code = gs_make_pattern(&cc, (gs_pattern_template_t *)&pat, &imat, pgs,
                           pgs->memory);
    if (code < 0)
        return code;
    code = gs_pattern2_set_shfill(&cc);
    if (code < 0)
        return code;
    pcs = gs_cspace_alloc(pgs->memory, &gs_color_space_type_Pattern);
    if (pcs == NULL)
        return_error(gs_error_VMerror);

    pcs->params.pattern.has_base_space = false;
    code = pcs->type->remap_color(&cc, pcs, &devc, pgs,
                                  pgs->device, gs_color_select_texture);
    if (code >= 0) {
        gx_device *dev = pgs->device;
        bool need_path = !dev_proc(dev, dev_spec_op)(dev,
                             gxdso_pattern_shfill_doesnt_need_path, NULL, 0);

        if (need_path) {
            gx_path cpath;

            gx_path_init_local(&cpath, pgs->memory);
            code = gx_cpath_to_path(pgs->clip_path, &cpath);
            if (code >= 0)
                code = gx_fill_path(&cpath, &devc, pgs, gx_rule_winding_number,
                                    pgs->fill_adjust.x, pgs->fill_adjust.y);
            gx_path_free(&cpath, "gs_shfill");
        } else
            code = gx_fill_path(NULL, &devc, pgs, gx_rule_winding_number,
                                pgs->fill_adjust.x, pgs->fill_adjust.y);
    }
    rc_decrement_cs(pcs, "gs_shfill");
    gs_pattern_reference(&cc, -1);
    return code;
}