コード例 #1
0
ファイル: gslib.c プロジェクト: BorodaZizitopa/ghostscript
static int
test6(gs_state * pgs, gs_memory_t * mem)
{
    gs_color_space *pcs;
    gs_cie_abc *pabc;
    gs_cie_render *pcrd;
    static const gs_vector3 white_point =
    {1, 1, 1};
    static const gs_cie_render_proc3 encode_abc =
    {
        {render_abc, render_abc, render_abc}
    };
    int code;
    gs_color_space *rgb_cs;

    rgb_cs = gs_cspace_new_DeviceRGB(mem);

    gs_scale(pgs, 150.0, 150.0);
    gs_translate(pgs, 0.5, 0.5);
    gs_setcolorspace(pgs, rgb_cs);
    spectrum(pgs, 5);
    gs_translate(pgs, 1.2, 0.0);
    /* We must set the CRD before the color space. */
    code = gs_cie_render1_build(&pcrd, mem, "test6");
    if (code < 0)
        return code;
    gs_cie_render1_initialize(mem, pcrd, NULL, &white_point, NULL,
                              NULL, NULL, NULL,
                              NULL, NULL, NULL,
                              NULL, &encode_abc, NULL,
                              NULL);
    gs_setcolorrendering(pgs, pcrd);
    gs_cspace_build_CIEABC(&pcs, NULL, mem);
    /* There should be an API for initializing CIE color spaces too.... */
    pabc = pcs->params.abc;
    pabc->common.points.WhitePoint = white_point;
    gs_cie_abc_complete(pabc);
    /* End of initializing the color space. */
    gs_setcolorspace(pgs, pcs);
    spectrum(pgs, 5);
    gs_free_object(mem, rgb_cs, "test6 rgb_cs");
    return 0;
}
コード例 #2
0
ファイル: plsrgb.c プロジェクト: ststeiger/ghostsvg
/* set the srgb color space */
static int
pl_setSRGB(gs_state *pgs)
{
    gs_color_space *pcs;
    int code;

    code = pl_cspace_init_SRGB(&pcs, pgs);
    if ( code < 0 )
        return code;
    code = gs_setcolorspace(pgs, pcs);
    rc_decrement(pcs, "ps_setSRGB");
    return code;
}
コード例 #3
0
ファイル: zicc.c プロジェクト: hackqiang/gs
/* Install a ICC type color space and use the ICC LABLUT profile. */
int
seticc_lab(i_ctx_t * i_ctx_p, float *white, float *black, float *range_buff)
{
    int                     code;
    gs_color_space *        pcs;
    gs_color_space *        palt_cs;
    gs_imager_state *       pis = (gs_imager_state *)igs;
    int                     i;
    static const char *const rfs = LAB_ICC;
    gs_param_string val, *pval;

    val.data = (const byte *)rfs;
    val.size = strlen(rfs);
    val.persistent = true;
    pval = &val;

    palt_cs = gs_currentcolorspace(igs);
    /* build the color space object */
    code = gs_cspace_build_ICC(&pcs, NULL, gs_state_memory(igs));
    if (code < 0)
        return gs_rethrow(code, "building color space object");
    /* record the current space as the alternative color space */
    /* pcs->base_space = palt_cs;
    rc_increment_cs(palt_cs); */
    /* Get the lab profile.  It may already be set in the icc manager.
       If not then lets populate it.  */
    if (pis->icc_manager->lab_profile == NULL ) {
        /* This can't happen as the profile
           should be initialized during the
           setting of the user params */
        return gs_rethrow(code, "cannot find lab icc profile");
    }
    /* Assign the LAB to LAB profile to this color space */
    code = gsicc_set_gscs_profile(pcs, pis->icc_manager->lab_profile, gs_state_memory(igs));
    rc_increment(pis->icc_manager->lab_profile);
    if (code < 0)
        return gs_rethrow(code, "installing the lab profile");
    pcs->cmm_icc_profile_data->Range.ranges[0].rmin = 0.0;
    pcs->cmm_icc_profile_data->Range.ranges[0].rmax = 100.0;
    for (i = 1; i < 3; i++) {
        pcs->cmm_icc_profile_data->Range.ranges[i].rmin =
            range_buff[2 * (i-1)];
        pcs->cmm_icc_profile_data->Range.ranges[i].rmax =
            range_buff[2 * (i-1) + 1];
    }
    /* Set the color space.  We are done.  */
    code = gs_setcolorspace(igs, pcs);
    return code;
}
コード例 #4
0
ファイル: zicc.c プロジェクト: hackqiang/gs
/* Install an ICC space from the PDF CalRGB or CalGray types */
int
seticc_cal(i_ctx_t * i_ctx_p, float *white, float *black, float *gamma,
           float *matrix, int num_colorants, ulong dictkey)
{
    int                     code;
    gs_color_space *        pcs;
    gs_imager_state *       pis = (gs_imager_state *)igs;
    gs_memory_t             *mem = pis->memory;
    int                     i;
    cmm_profile_t           *cal_profile;

    /* See if the color space is in the profile cache */
    pcs = gsicc_find_cs(dictkey, igs);
    if (pcs == NULL ) {
        /* build the color space object.  Since this is cached
           in the profile cache which is a member variable
           of the graphic state, we will want to use stable
           memory here */
        code = gs_cspace_build_ICC(&pcs, NULL, mem->stable_memory);
        if (code < 0)
            return gs_rethrow(code, "building color space object");
        /* There is no alternate for this.  Perhaps we should set DeviceRGB? */
        pcs->base_space = NULL;
        /* Create the ICC profile from the CalRGB or CalGray parameters */
        cal_profile = gsicc_create_from_cal(white, black, gamma, matrix,
                                            mem->stable_memory, num_colorants);
        if (cal_profile == NULL)
            return gs_rethrow(-1, "creating the cal profile");
        /* Assign the profile to this color space */
        code = gsicc_set_gscs_profile(pcs, cal_profile, mem->stable_memory);
        if (code < 0)
            return gs_rethrow(code, "installing the cal profile");
        for (i = 0; i < num_colorants; i++) {
            pcs->cmm_icc_profile_data->Range.ranges[i].rmin = 0;
            pcs->cmm_icc_profile_data->Range.ranges[i].rmax = 1;
        }
        /* Add the color space to the profile cache */
        gsicc_add_cs(igs, pcs,dictkey);
    }
    /* Set the color space.  We are done.  */
    code = gs_setcolorspace(igs, pcs);
    return code;
}
コード例 #5
0
/* <array> .setdevicepixelspace - */
static int
zsetdevicepixelspace(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref depth;
    gs_color_space *pcs;
    int code;

    check_read_type(*op, t_array);
    if (r_size(op) != 2)
	return_error(e_rangecheck);
    array_get(imemory, op, 1L, &depth);
    check_type_only(depth, t_integer);
    code = gs_cspace_new_DevicePixel(imemory, &pcs, (int)depth.value.intval);
    if (code < 0)
	return code;
    code = gs_setcolorspace(igs, pcs);
    /* release reference from construction */
    rc_decrement_only(pcs, "zsetseparationspace");
    if (code >= 0)
	pop(1);
    return code;
}
コード例 #6
0
ファイル: gscolor1.c プロジェクト: DecisiveMocha/ghostpdl
/* setcmykcolor */
int
gs_setcmykcolor(gs_gstate * pgs, double c, double m, double y, double k)
{
    gs_color_space      *pcs;
    int                 code;

    pcs = gs_cspace_new_DeviceCMYK(pgs->memory);
    if (pcs == NULL)
        return_error(gs_error_VMerror);
    if ((code = gs_setcolorspace(pgs, pcs)) >= 0) {
       gs_client_color *pcc = gs_currentcolor_inline(pgs);

        cs_adjust_color_count(pgs, -1); /* not strictly necessary */
        pcc->paint.values[0] = FORCE_UNIT(c);
        pcc->paint.values[1] = FORCE_UNIT(m);
        pcc->paint.values[2] = FORCE_UNIT(y);
        pcc->paint.values[3] = FORCE_UNIT(k);
        pcc->pattern = 0;		/* for GC */
        gx_unset_dev_color(pgs);
    }
    rc_decrement_only_cs(pcs, "gs_setcmykcolor");
    return code;
}
コード例 #7
0
ファイル: zicc.c プロジェクト: hackqiang/gs
int seticc(i_ctx_t * i_ctx_p, int ncomps, ref *ICCdict, float *range_buff)
{
    int                     code, k;
    gs_color_space *        pcs;
    gs_color_space *  palt_cs;
    ref *                   pstrmval;
    stream *                s = 0L;
    cmm_profile_t           *picc_profile;
    gs_imager_state *       pis = (gs_imager_state *)igs;
    int                     i, expected = 0;
    ref *                   pnameval;
    static const char *const icc_std_profile_names[] = {
            GSICC_STANDARD_PROFILES
        };
    static const char *const icc_std_profile_keys[] = {
            GSICC_STANDARD_PROFILES_KEYS
        };

    palt_cs = gs_currentcolorspace(igs);

    /* verify the DataSource entry */
    if (dict_find_string(ICCdict, "DataSource", &pstrmval) <= 0)
        return_error(e_undefined);
    check_read_file(i_ctx_p, s, pstrmval);

    /* build the color space object */
    code = gs_cspace_build_ICC(&pcs, NULL, gs_state_memory(igs));
    if (code < 0)
        return gs_rethrow(code, "building color space object");
    /*  For now, dump the profile into a buffer
        and obtain handle from the buffer when we need it.
        We may want to change this later.
        This depends to some degree on what the CMS is capable of doing.
        I don't want to get bogged down on stream I/O at this point.
        Note also, if we are going to be putting these into the clist we will
        want to have this buffer. */
    /* Check if we have the /Name entry.  This is used to associate with
       specs that have enumerated types to indicate sRGB sGray etc */
    if (dict_find_string(ICCdict, "Name", &pnameval) > 0){
        uint size = r_size(pnameval);
        char *str = (char *)gs_alloc_bytes(gs_state_memory(igs), size+1, "seticc");
        memcpy(str, (const char *)pnameval->value.bytes, size);
        str[size] = 0;

        /* Compare this to the standard profile names */
        picc_profile = NULL;
        for (k = 0; k < GSICC_NUMBER_STANDARD_PROFILES; k++) {
            if ( strcmp( str, icc_std_profile_keys[k] ) == 0 ) {
                picc_profile = gsicc_get_profile_handle_file(icc_std_profile_names[k],
                    strlen(icc_std_profile_names[k]), gs_state_memory(igs));
                break;
            }
        }
    } else {
        picc_profile = gsicc_profile_new(s, gs_state_memory(igs), NULL, 0);
    }
    if (picc_profile == NULL) {
        rc_decrement(picc_profile,"seticc");
        rc_decrement(pcs,"seticc");
        return -1;
    }
    code = gsicc_set_gscs_profile(pcs, picc_profile, gs_state_memory(igs));
    if (code < 0) {
        rc_decrement(picc_profile,"seticc");
        rc_decrement(pcs,"seticc");
        return code;
    }
    picc_profile->num_comps = ncomps;

    /* We have to get the profile handle due to the fact that we need to know
       if it has a data space that is CIELAB */
    picc_profile->profile_handle =
        gsicc_get_profile_handle_buffer(picc_profile->buffer,
                                        picc_profile->buffer_size,
                                        gs_state_memory(igs));
    if (picc_profile->profile_handle == NULL) {
        /* Free up everything, the profile is not valid. We will end up going
           ahead and using a default based upon the number of components */
        rc_decrement(picc_profile,"seticc");
        rc_decrement(pcs,"seticc");
        return -1;
    }
    picc_profile->data_cs = gscms_get_profile_data_space(picc_profile->profile_handle);
    switch( picc_profile->data_cs ) {
        case gsCIEXYZ:
        case gsCIELAB:
        case gsRGB:
            expected = 3;
            break;
        case gsGRAY:
            expected = 1;
            break;
        case gsCMYK:
            expected = 4;
            break;
        case gsNCHANNEL:
        case gsNAMED:            /* Silence warnings */
        case gsUNDEFINED:        /* Silence warnings */
            break;
    }
    if (!expected || ncomps != expected) {
        rc_decrement(picc_profile,"seticc");
        rc_decrement(pcs,"seticc");
        return_error(e_rangecheck);
    }

    /* Lets go ahead and get the hash code and check if we match one of the default spaces */
    /* Later we may want to delay this, but for now lets go ahead and do it */
    gsicc_init_hash_cs(picc_profile, pis);

    /* Set the range according to the data type that is associated with the
       ICC input color type.  Occasionally, we will run into CIELAB to CIELAB
       profiles for spot colors in PDF documents. These spot colors are typically described
       as separation colors with tint transforms that go from a tint value
       to a linear mapping between the CIELAB white point and the CIELAB tint
       color.  This results in a CIELAB value that we need to use to fill.  We
       need to detect this to make sure we do the proper scaling of the data.  For
       CIELAB images in PDF, the source is always normal 8 or 16 bit encoded data
       in the range from 0 to 255 or 0 to 65535.  In that case, there should not
       be any encoding and decoding to CIELAB.  The PDF content will not include
       an ICC profile but will set the color space to \Lab.  In this case, we use
       our seticc_lab operation to install the LAB to LAB profile, but we detect
       that we did that through the use of the is_lab flag in the profile descriptor.
       When then avoid the CIELAB encode and decode */
    if (picc_profile->data_cs == gsCIELAB) {
    /* If the input space to this profile is CIELAB, then we need to adjust the limits */
        /* See ICC spec ICC.1:2004-10 Section 6.3.4.2 and 6.4.  I don't believe we need to
           worry about CIEXYZ profiles or any of the other odds ones.  Need to check that though
           at some point. */
        picc_profile->Range.ranges[0].rmin = 0.0;
        picc_profile->Range.ranges[0].rmax = 100.0;
        picc_profile->Range.ranges[1].rmin = -128.0;
        picc_profile->Range.ranges[1].rmax = 127.0;
        picc_profile->Range.ranges[2].rmin = -128.0;
        picc_profile->Range.ranges[2].rmax = 127.0;
        picc_profile->islab = true;
    } else {
        for (i = 0; i < ncomps; i++) {
            picc_profile->Range.ranges[i].rmin = range_buff[2 * i];
            picc_profile->Range.ranges[i].rmax = range_buff[2 * i + 1];
        }
    }
    /* Now see if we are in an overide situation.  We have to wait until now
       in case this is an LAB profile which we will not overide */
    if (gs_currentoverrideicc(pis) && picc_profile->data_cs != gsCIELAB) {
        /* Free up the profile structure */
        switch( picc_profile->data_cs ) {
            case gsRGB:
                pcs->cmm_icc_profile_data = pis->icc_manager->default_rgb;
                break;
            case gsGRAY:
                pcs->cmm_icc_profile_data = pis->icc_manager->default_gray;
                break;
            case gsCMYK:
                pcs->cmm_icc_profile_data = pis->icc_manager->default_cmyk;
                break;
            default:
                break;
        }
        /* Have one increment from the color space.  Having these tied 
           together is not really correct.  Need to fix that.  ToDo.  MJV */
        rc_adjust(picc_profile, -2, "seticc");
        rc_increment(pcs->cmm_icc_profile_data);
    } 
    /* Set the color space.  We are done.  No joint cache here... */
    code = gs_setcolorspace(igs, pcs);
    /* The context has taken a reference to the colorspace. We no longer need
     * ours, so drop it. */
    rc_decrement_only(pcs, "seticc");
    /* In this case, we already have a ref count of 2 on the icc profile
       one for when it was created and one for when it was set.  We really
       only want one here so adjust */
    rc_decrement(picc_profile,"seticc");
    /* Remove the ICC dict from the stack */
    pop(1);
    return code;
}
コード例 #8
0
/* The current color space is the alternate space for the separation space. */
static int
zsetseparationspace(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const ref *pcsa;
    gs_color_space *pcs;
    gs_color_space * pacs;
    ref_colorspace cspace_old;
    ref sname, name_none, name_all;
    gs_function_t *pfn = NULL;
    separation_type sep_type;
    int code;
    const gs_memory_t * mem = imemory;

    /* Verify that we have an array as our input parameter */
    check_read_type(*op, t_array);
    if (r_size(op) != 4)
	return_error(e_rangecheck);

    /* The alternate color space has been selected as the current color space */
    pacs = gs_currentcolorspace(igs);
    if (!pacs->type->can_be_alt_space)
	return_error(e_rangecheck);

    /*
     * pcsa is a pointer to element 1 (2nd element)  in the Separation colorspace
     * description array.  Thus pcsa[2] is element #3 (4th element) which is the
     * tint transform.
     */
    pcsa = op->value.const_refs + 1;
    sname = *pcsa;
    switch (r_type(&sname)) {
	default:
	    return_error(e_typecheck);
	case t_string:
	    code = name_from_string(mem, &sname, &sname);
	    if (code < 0)
		return code;
	    /* falls through */
	case t_name:
	    break;
    }

    if ((code = name_ref(mem, (const byte *)"All", 3, &name_all, 0)) < 0)
	return code;
    if ((code = name_ref(mem, (const byte *)"None", 4, &name_none, 0)) < 0)
	return code;
    sep_type = ( name_eq(&sname, &name_all) ? SEP_ALL :
	         name_eq(&sname, &name_none) ? SEP_NONE : SEP_OTHER);

    /* Check tint transform procedure. */
    /* See comment above about psca */
    check_proc(pcsa[2]);
    pfn = ref_function(pcsa + 2);
    if (pfn == NULL)
	return_error(e_rangecheck);

    cspace_old = istate->colorspace;
    /* Now set the current color space as Separation */
    code = gs_cspace_new_Separation(&pcs, pacs, imemory);
    if (code < 0)
	return code;
    pcs->params.separation.sep_type = sep_type;
    pcs->params.separation.sep_name = name_index(mem, &sname);
    pcs->params.separation.get_colorname_string = gs_get_colorname_string;
    istate->colorspace.procs.special.separation.layer_name = pcsa[0];
    istate->colorspace.procs.special.separation.tint_transform = pcsa[2];
    if (code >= 0)
        code = gs_cspace_set_sepr_function(pcs, pfn);
    if (code >= 0)
	code = gs_setcolorspace(igs, pcs);
    /* release reference from construction */
    rc_decrement_only(pcs, "zsetseparationspace");
    if (code < 0) {
	istate->colorspace = cspace_old;
	return code;
    }
    pop(1);
    return 0;
}
コード例 #9
0
ファイル: gslib.c プロジェクト: BorodaZizitopa/ghostscript
static int
test10(gs_state * pgs, gs_memory_t * mem)
{
    gs_c_param_list list;
    gs_param_string nstr, OFstr;
    gs_param_float_array PSa;
    gs_param_float_array HWRa;
    gs_param_int_array HWSa;
    int HWSize[2];
    float HWResolution[2], PageSize[2];
    long MaxBitmap;
    int code;
    gx_device *dev = gs_currentdevice(pgs);
    float xlate_x, xlate_y;
    gs_rect cliprect;

    gs_c_param_list_write(&list, mem);
    code = gs_getdeviceparams(dev, (gs_param_list *) & list);
    if (code < 0) {
        lprintf1("getdeviceparams failed! code = %d\n", code);
        gs_abort(mem);
    }
    gs_c_param_list_read(&list);
    code = param_read_string((gs_param_list *) & list, "Name", &nstr);
    if (code < 0) {
        lprintf1("reading Name failed! code = %d\n", code);
        gs_abort(mem);
    }
    code = param_read_int_array((gs_param_list *) & list,
                                "HWSize", &HWSa);
    if (code < 0) {
        lprintf1("reading HWSize failed! code = %d\n", code);
        gs_abort(mem);
    }
    emprintf3(mem, "HWSize[%d] = [ %d, %d ]\n", HWSa.size,
              HWSa.data[0], HWSa.data[1]);
    code = param_read_float_array((gs_param_list *) & list,
                                  "HWResolution", &HWRa);
    if (code < 0) {
        lprintf1("reading Resolution failed! code = %d\n", code);
        gs_abort(mem);
    }
    emprintf3(mem, "HWResolution[%d] = [ %f, %f ]\n", HWRa.size,
              HWRa.data[0], HWRa.data[1]);
    code = param_read_float_array((gs_param_list *) & list,
                                  "PageSize", &PSa);
    if (code < 0) {
        lprintf1("reading PageSize failed! code = %d\n", code);
        gs_abort(mem);
    }
    emprintf3(mem, "PageSize[%d] = [ %f, %f ]\n", PSa.size,
              PSa.data[0], PSa.data[1]);
    code = param_read_long((gs_param_list *) & list,
                           "MaxBitmap", &MaxBitmap);
    if (code < 0) {
        lprintf1("reading MaxBitmap failed! code = %d\n", code);
        gs_abort(mem);
    }
    emprintf1(mem, "MaxBitmap = %ld\n", MaxBitmap);
    /* Switch to param list functions to "write" */
    gs_c_param_list_write(&list, mem);
    /* Always set the PageSize. */
    PageSize[0] = 72.0 * ypage_wid;
    PageSize[1] = 72.0 * xpage_len;
    PSa.data = PageSize;
    code = param_write_float_array((gs_param_list *) & list,
                                   "PageSize", &PSa);
    if (nstr.data[0] != 'v') {
        /* Set the OutputFile string file name */
        OFstr.persistent = false;
        OFstr.data = outfile;
        OFstr.size = strlen(outfile);
        code = param_write_string((gs_param_list *) & list,
                                  "OutputFile", &OFstr);
        if (code < 0) {
            lprintf1("setting OutputFile name failed, code=%d\n",
                     code);
            gs_abort(mem);
        }
        if (nstr.data[0] == 'x') {
            HWResolution[0] = HWResolution[1] = 72.0;
        } else {
            HWResolution[0] = HWResolution[1] = 360.0;
        }
        HWRa.data = HWResolution;
        HWSize[0] = (int)(HWResolution[0] * ypage_wid);
        HWSize[1] = (int)(HWResolution[1] * xpage_len);
        emprintf3(mem, "\tHWSize = [%d,%d], HWResolution = %f dpi\n",
                  HWSize[0], HWSize[1], HWResolution[0]);
        HWSa.data = HWSize;
        code = param_write_float_array((gs_param_list *) & list,
                                       "HWResolution", &HWRa);
        code = param_write_int_array((gs_param_list *) & list,
                                     "HWSize", &HWSa);
        MaxBitmap = 1000000L;
        code = param_write_long((gs_param_list *) & list,
                                "MaxBitmap", &MaxBitmap);
    }
    gs_c_param_list_read(&list);
    code = gs_putdeviceparams(dev, (gs_param_list *) & list);
    emprintf1(mem, "putdeviceparams: code=%d\n", code);
    gs_c_param_list_release(&list);

    /* note: initgraphics no longer resets the color or color space */
    gs_erasepage(pgs);
    gs_initgraphics(pgs);
    {
        gs_color_space *cs = gs_cspace_new_DeviceGray(mem);
        gs_setcolorspace(pgs, cs);
        gs_setcolorspace(pgs, cs);
        gs_decrement(cs, "test10 DeviceGray");
    }

    gs_clippath(pgs);
    gs_pathbbox(pgs, &cliprect);
    emprintf4(mem, "\tcliprect = [[%g,%g],[%g,%g]]\n",
              cliprect.p.x, cliprect.p.y, cliprect.q.x, cliprect.q.y);
    gs_newpath(pgs);

    switch (((rotate_value + 270) / 90) & 3) {
        default:
        case 0:		/* 0 = 360 degrees in PS == 90 degrees in printer */
            xlate_x = cliprect.p.x;
            xlate_y = cliprect.p.y;
            break;
        case 1:		/* 90 degrees in PS = 180 degrees printer */
            xlate_x = cliprect.q.x;
            xlate_y = cliprect.p.y;
            break;
        case 2:		/* 180 degrees in PS == 270 degrees in printer */
            xlate_x = cliprect.q.x;
            xlate_y = cliprect.q.y;
            break;
        case 3:		/* 270 degrees in PS == 0 degrees in printer */
            xlate_x = cliprect.p.x;
            xlate_y = cliprect.q.y;
            break;
    }
    emprintf2(mem, "translate origin to [ %f, %f ]\n", xlate_x, xlate_y);
    gs_translate(pgs, xlate_x, xlate_y);

    /* further move (before rotate) by user requested amount */
    gs_translate(pgs, 72.0 * (float)xmove_origin, 72.0 * (float)ymove_origin);

    gs_rotate(pgs, (float)rotate_value + 270.0);
    gs_scale(pgs, scale_x * 72.0 / 2032.0,
             scale_y * 72.0 / 2032.0);
    gs_setlinecap(pgs, gs_cap_butt);
    gs_setlinejoin(pgs, gs_join_bevel);
    gs_setfilladjust(pgs, 0.0, 0.0);

    capture_exec(pgs);
    return 0;
}
コード例 #10
0
ファイル: gscolor3.c プロジェクト: DecisiveMocha/ghostpdl
/* 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;
}
コード例 #11
0
/* The current color space is the alternate space for the DeviceN space. */
static int
zsetdevicenspace(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const ref *pcsa;
    gs_separation_name *names;
    gs_device_n_map *pmap;
    uint num_components;
    gs_color_space *pcs;
    gs_color_space *pacs;
    ref_colorspace cspace_old;
    gs_function_t *pfn;
    int code;

    /* Verify that we have an array as our input parameter */
    check_read_type(*op, t_array);
    if (r_size(op) < 4 || r_size(op) > 5)
	return_error(e_rangecheck);

    /* pcsa is a pointer to the color names array (element 1 in input array) */
    pcsa = op->value.const_refs + 1;
    if (!r_is_array(pcsa))
	return_error(e_typecheck);
    num_components = r_size(pcsa);
    if (num_components == 0)
	return_error(e_rangecheck);
    if (num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
	return_error(e_limitcheck);

    /* Check tint transform procedure.  Note: Cheap trick to get pointer to it.
       The tint transform procedure is element 3 in the input array */
    check_proc(pcsa[2]);
    
    /* The alternate color space has been selected as the current color space */
    pacs = gs_currentcolorspace(igs);

    code = gs_cspace_new_DeviceN(&pcs, num_components, pacs, imemory);
    if (code < 0)
	return code;
    names = pcs->params.device_n.names;
    pmap = pcs->params.device_n.map;
    pcs->params.device_n.get_colorname_string = gs_get_colorname_string;

    /* Pick up the names of the components */
    {
	uint i;
	ref sname;

	for (i = 0; i < num_components; ++i) {
	    array_get(imemory, pcsa, (long)i, &sname);
	    switch (r_type(&sname)) {
		case t_string:
		    code = name_from_string(imemory, &sname, &sname);
		    if (code < 0) {
			rc_decrement(pcs, ".setdevicenspace");
			return code;
		    }
		    /* falls through */
		case t_name:
		    names[i] = name_index(imemory, &sname);
		    break;
		default:
		    rc_decrement(pcs, ".setdevicenspace");
		    return_error(e_typecheck);
	    }
	}
    }

    /* Now set the current color space as DeviceN */

    cspace_old = istate->colorspace;
    /*
     * pcsa is a pointer to element 1 (2nd element)  in the DeviceN
     * description array.  Thus pcsa[2] is element #3 (4th element)
     * which is the tint transform.
     */
    istate->colorspace.procs.special.device_n.layer_names = pcsa[0];
    istate->colorspace.procs.special.device_n.tint_transform = pcsa[2];    
    pfn = ref_function(pcsa + 2);	/* See comment above */
    if (!pfn)
	code = gs_note_error(e_rangecheck);

    if (code < 0) {
	istate->colorspace = cspace_old;
	rc_decrement_only(pcs, "zsetdevicenspace");
	return code;
    }
    gs_cspace_set_devn_function(pcs, pfn);
    code = gs_setcolorspace(igs, pcs);
    /* release reference from construction */
    rc_decrement_only(pcs, "zsetdevicenspace");
    if (code < 0) {
	istate->colorspace = cspace_old;
	return code;
    }
    pop(1);
    return 0;
}
コード例 #12
0
ファイル: xpstile.c プロジェクト: computersforpeace/ghostpdl
int
xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
    int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*), void *user)
{
    xps_item_t *node;
    int code;

    char *opacity_att;
    char *transform_att;
    char *viewbox_att;
    char *viewport_att;
    char *tile_mode_att;
    /*char *viewbox_units_att;*/
    /*char *viewport_units_att;*/

    xps_item_t *transform_tag = NULL;

    gs_matrix transform;
    gs_rect viewbox;
    gs_rect viewport;
    float scalex, scaley;
    int tile_mode;

    opacity_att = xps_att(root, "Opacity");
    transform_att = xps_att(root, "Transform");
    viewbox_att = xps_att(root, "Viewbox");
    viewport_att = xps_att(root, "Viewport");
    tile_mode_att = xps_att(root, "TileMode");
    /*viewbox_units_att = xps_att(root, "ViewboxUnits");*/
    /*viewport_units_att = xps_att(root, "ViewportUnits");*/

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "ImageBrush.Transform"))
            transform_tag = xps_down(node);
        if (!strcmp(xps_tag(node), "VisualBrush.Transform"))
            transform_tag = xps_down(node);
    }

    xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);

    gs_make_identity(&transform);
    if (transform_att)
        xps_parse_render_transform(ctx, transform_att, &transform);
    if (transform_tag)
        xps_parse_matrix_transform(ctx, transform_tag, &transform);

    viewbox.p.x = 0.0; viewbox.p.y = 0.0;
    viewbox.q.x = 1.0; viewbox.q.y = 1.0;
    if (viewbox_att)
        xps_parse_rectangle(ctx, viewbox_att, &viewbox);

    viewport.p.x = 0.0; viewport.p.y = 0.0;
    viewport.q.x = 1.0; viewport.q.y = 1.0;
    if (viewport_att)
        xps_parse_rectangle(ctx, viewport_att, &viewport);

    /* some sanity checks on the viewport/viewbox size */
    if (fabs(viewport.q.x - viewport.p.x) < 0.01) { gs_warn("skipping tile with zero width view port"); return 0; }
    if (fabs(viewport.q.y - viewport.p.y) < 0.01) { gs_warn("skipping tile with zero height view port"); return 0; }
    if (fabs(viewbox.q.x - viewbox.p.x) < 0.01) { gs_warn("skipping tile with zero width view box"); return 0; }
    if (fabs(viewbox.q.y - viewbox.p.y) < 0.01) { gs_warn("skipping tile with zero height view box"); return 0; }

    scalex = (viewport.q.x - viewport.p.x) / (viewbox.q.x - viewbox.p.x);
    scaley = (viewport.q.y - viewport.p.y) / (viewbox.q.y - viewbox.p.y);

    tile_mode = TILE_NONE;
    if (tile_mode_att)
    {
        if (!strcmp(tile_mode_att, "None"))
            tile_mode = TILE_NONE;
        if (!strcmp(tile_mode_att, "Tile"))
            tile_mode = TILE_TILE;
        if (!strcmp(tile_mode_att, "FlipX"))
            tile_mode = TILE_FLIP_X;
        if (!strcmp(tile_mode_att, "FlipY"))
            tile_mode = TILE_FLIP_Y;
        if (!strcmp(tile_mode_att, "FlipXY"))
            tile_mode = TILE_FLIP_X_Y;
    }

    gs_gsave(ctx->pgs);

    code = xps_begin_opacity(ctx, base_uri, dict, opacity_att, NULL, false, false);
    if (code)
    {
        gs_grestore(ctx->pgs);
        return gs_rethrow(code, "cannot create transparency group");
    }

    /* TODO(tor): check viewport and tiling to see if we can set it to TILE_NONE */

    if (tile_mode != TILE_NONE)
    {
        struct tile_closure_s closure;

        gs_client_pattern gspat;
        gs_client_color gscolor;
        gs_color_space *cs;
        bool sa;

        closure.ctx = ctx;
        closure.base_uri = base_uri;
        closure.dict = dict;
        closure.tag = root;
        closure.tile_mode = tile_mode;
        closure.user = user;
        closure.func = func;

        closure.viewbox.p.x = viewbox.p.x;
        closure.viewbox.p.y = viewbox.p.y;
        closure.viewbox.q.x = viewbox.q.x;
        closure.viewbox.q.y = viewbox.q.y;

        gs_pattern1_init(&gspat);
        uid_set_UniqueID(&gspat.uid, gs_next_ids(ctx->memory, 1));
        gspat.PaintType = 1;
        gspat.TilingType = 2;
        gspat.PaintProc = xps_remap_pattern;
        gspat.client_data = &closure;

        /* We need to know if this tiling brush includes transparency.
           We could do a proper scan, but for now we'll be lazy and just look
           at the flag from scanning the page. */
        gspat.uses_transparency = ctx->has_transparency;

        gspat.XStep = viewbox.q.x - viewbox.p.x;
        gspat.YStep = viewbox.q.y - viewbox.p.y;
        gspat.BBox.p.x = viewbox.p.x;
        gspat.BBox.p.y = viewbox.p.y;
        gspat.BBox.q.x = viewbox.q.x;
        gspat.BBox.q.y = viewbox.q.y;

        if (tile_mode == TILE_FLIP_X || tile_mode == TILE_FLIP_X_Y)
        {
            gspat.BBox.q.x += gspat.XStep;
            gspat.XStep *= 2;
        }

        if (tile_mode == TILE_FLIP_Y || tile_mode == TILE_FLIP_X_Y)
        {
            gspat.BBox.q.y += gspat.YStep;
            gspat.YStep *= 2;
        }

        gs_matrix_translate(&transform, viewport.p.x, viewport.p.y, &transform);
        gs_matrix_scale(&transform, scalex, scaley, &transform);
        gs_matrix_translate(&transform, -viewbox.p.x, -viewbox.p.y, &transform);

        cs = ctx->srgb;
        gs_setcolorspace(ctx->pgs, cs);
        gsicc_profile_reference(cs->cmm_icc_profile_data, 1);

        sa = gs_currentstrokeadjust(ctx->pgs);
        gs_setstrokeadjust(ctx->pgs, false);
        gs_makepattern(&gscolor, &gspat, &transform, ctx->pgs, NULL);
        gs_setpattern(ctx->pgs, &gscolor);
        xps_fill(ctx);
        gs_setstrokeadjust(ctx->pgs, sa);
        gsicc_profile_reference(cs->cmm_icc_profile_data, -1);

        /* gs_makepattern increments the pattern count stored in the color
         * structure. We will discard the color struct (its on the stack)
         * so we need to decrement the reference before we throw away
         * the structure.
         */
        gs_pattern_reference(&gscolor, -1);
    }
    else
    {
        xps_clip(ctx);

        gs_concat(ctx->pgs, &transform);

        gs_translate(ctx->pgs, viewport.p.x, viewport.p.y);
        gs_scale(ctx->pgs, scalex, scaley);
        gs_translate(ctx->pgs, -viewbox.p.x, -viewbox.p.y);

        gs_moveto(ctx->pgs, viewbox.p.x, viewbox.p.y);
        gs_lineto(ctx->pgs, viewbox.p.x, viewbox.q.y);
        gs_lineto(ctx->pgs, viewbox.q.x, viewbox.q.y);
        gs_lineto(ctx->pgs, viewbox.q.x, viewbox.p.y);
        gs_closepath(ctx->pgs);
        gs_clip(ctx->pgs);
        gs_newpath(ctx->pgs);

        code = func(ctx, base_uri, dict, root, user);
        if (code < 0)
        {
            xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot draw tile");
        }
    }

    xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);

    gs_grestore(ctx->pgs);

    return 0;
}