Exemple #1
0
/*
 *  Flush text from buffer.
 */
static int
flush_text_buffer(gx_device_pdf *pdev)
{
    pdf_text_state_t *pts = pdev->text->text_state;
    stream *s = pdev->strm;

    if (pts->buffer.count_chars != 0) {
        pdf_font_resource_t *pdfont = pts->in.pdfont;
        int code = pdf_assign_font_object_id(pdev, pdfont);

        if (code < 0)
            return code;
        code = pdf_add_resource(pdev, pdev->substream_Resources, "/Font", (pdf_resource_t *)pdfont);
        if (code < 0)
            return code;
    }
    if (pts->buffer.count_moves > 0) {
        int i, cur = 0;

        if (pts->use_leading)
            stream_puts(s, "T*");
        stream_puts(s, "[");
        for (i = 0; i < pts->buffer.count_moves; ++i) {
            int next = pts->buffer.moves[i].index;

            pdf_put_string(pdev, pts->buffer.chars + cur, next - cur);
            pprintg1(s, "%g", pts->buffer.moves[i].amount);
            cur = next;
        }
        if (pts->buffer.count_chars > cur)
            pdf_put_string(pdev, pts->buffer.chars + cur,
                           pts->buffer.count_chars - cur);
        stream_puts(s, "]TJ\n");
    } else {
        pdf_put_string(pdev, pts->buffer.chars, pts->buffer.count_chars);
        stream_puts(s, (pts->use_leading ? "'\n" : "Tj\n"));
    }
    pts->buffer.count_chars = 0;
    pts->buffer.count_moves = 0;
    pts->use_leading = false;
    return 0;
}
/* Create colored and uncolored Pattern color spaces. */
static int
pdf_pattern_space(gx_device_pdf *pdev, cos_value_t *pvalue,
		  pdf_resource_t **ppres, const char *cs_name)
{
    int code;

    if (!*ppres) {
	int code = pdf_begin_resource_body(pdev, resourceColorSpace, gs_no_id,
					   ppres);

	if (code < 0)
	    return code;
	pprints1(pdev->strm, "%s\n", cs_name);
	pdf_end_resource(pdev);
	(*ppres)->object->written = true; /* don't write at end */
	((pdf_color_space_t *)*ppres)->ranges = 0;
	((pdf_color_space_t *)*ppres)->serialized = 0;
    }
    code = pdf_add_resource(pdev, pdev->substream_Resources, "/ColorSpace", *ppres);
    if (code < 0)
	return code;
    cos_resource_value(pvalue, (*ppres)->object);
    return 0;
}
Exemple #3
0
PDFLIB_API void PDFLIB_CALL
PDF_set_parameter(PDF *p, const char *key, const char *value)
{
    static const char fn[] = "PDF_set_parameter";
    pdc_usebox usebox = use_none;
    pdc_text_format textformat = pdc_auto;
    int i, k;

    if (key == NULL || !*key)
	pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "key", 0, 0, 0);

    i = get_index(key);

    if (!pdf_enter_api(p, fn, (pdf_state) pdf_state_all,
	"(p[%p], \"%s\", \"%s\")\n", (void *) p, key, value))
	return;

    if (i == -1)
	pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0);

    if ((p->state_stack[p->state_sp] & parms[i].set_scope) == 0)
	pdc_error(p->pdc, PDF_E_DOC_SCOPE_SET, key, pdf_current_scope(p), 0, 0);

    if (value == NULL)
	pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "value", 0, 0, 0);

    switch (i)
    {
        case PDF_PARAMETER_PDIUSEBOX:
        case PDF_PARAMETER_VIEWAREA:
        case PDF_PARAMETER_VIEWCLIP:
        case PDF_PARAMETER_PRINTAREA:
        case PDF_PARAMETER_PRINTCLIP:
            k = pdc_get_keycode(value, pdf_usebox_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            usebox = (pdc_usebox) k;
            break;

        case PDF_PARAMETER_TEXTFORMAT:
        case PDF_PARAMETER_HYPERTEXTFORMAT:
            k = pdc_get_keycode(value, pdf_textformat_keylist);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            textformat = (pdc_text_format) k;
            break;
    }

    switch (i)
    {
        case PDF_PARAMETER_SEARCHPATH:
        case PDF_PARAMETER_FONTAFM:
	case PDF_PARAMETER_FONTPFM:
        case PDF_PARAMETER_FONTOUTLINE:
        case PDF_PARAMETER_HOSTFONT:
        case PDF_PARAMETER_ENCODING:
        case PDF_PARAMETER_ICCPROFILE:
        case PDF_PARAMETER_STANDARDOUTPUTINTENT:
	{
            pdf_add_resource(p, key, value);
            break;
        }

	case PDF_PARAMETER_FLUSH:
	    if (p->binding != NULL && strcmp(p->binding, "C++"))
		break;

	    if (!strcmp(value, "none"))
		p->flush = pdf_flush_none;
	    else if (!strcmp(value, "page"))
                p->flush = (pdf_flush_state) (p->flush | pdf_flush_page);
	    else if (!strcmp(value, "content"))
                p->flush = (pdf_flush_state) (p->flush | pdf_flush_content);
	    else if (!strcmp(value, "heavy"))
                p->flush = (pdf_flush_state) (p->flush | pdf_flush_heavy);
	    else
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);

	    break;

	case PDF_PARAMETER_DEBUG:
	{
	    const unsigned char *c;

	    for (c = (const unsigned char *) value; *c; c++) {
		p->debug[(int) *c] = 1;

		if (*c == 't') {
		    pdc_set_trace(p->pdc, "PDFlib " PDFLIB_VERSIONSTRING);
		}
	    }
	    break;
	}

	case PDF_PARAMETER_NODEBUG:
	{
	    const unsigned char *c;

	    for (c = (const unsigned char *) value; *c; c++) {
		if (*c == 't')
		    pdc_set_trace(p->pdc, NULL);

		p->debug[(int) *c] = 0;
	    }
	    break;
	}

        case PDF_PARAMETER_BINDING:
            if (!p->binding)
                p->binding = pdc_strdup(p->pdc, value);
            break;

        case PDF_PARAMETER_HASTOBEPOS:
            p->hastobepos = pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_UNDERLINE:
	    p->underline = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_OVERLINE:
	    p->overline = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_STRIKEOUT:
	    p->strikeout = pdf_bool_value(p, key, value);
	    break;

        case PDF_PARAMETER_KERNING:
            pdc_warning(p->pdc, PDF_E_UNSUPP_KERNING, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_AUTOSUBSETTING:
            pdc_warning(p->pdc, PDF_E_UNSUPP_SUBSET, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_AUTOCIDFONT:
            pdc_warning(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0);
            break;

        case PDF_PARAMETER_UNICODEMAP:
            pdc_warning(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0);
            break;

	case PDF_PARAMETER_MASTERPASSWORD:
	    pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_USERPASSWORD:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_PERMISSIONS:
            pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0);
	    break;

	case PDF_PARAMETER_COMPATIBILITY:

	    if (!strcmp(value, "1.3"))
		p->compatibility = PDC_1_3;
	    else if (!strcmp(value, "1.4"))
		p->compatibility = PDC_1_4;
	    else if (!strcmp(value, "1.5"))
		p->compatibility = PDC_1_5;
	    else
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    break;

	case PDF_PARAMETER_PDFX:
	    pdc_warning(p->pdc, PDF_E_UNSUPP_PDFX, 0, 0, 0, 0);

	    break;


        case PDF_PARAMETER_RESOURCEFILE:
            if (p->resourcefilename)
            {
                pdc_free(p->pdc, p->resourcefilename);
                p->resourcefilename = NULL;
            }
            p->resourcefilename = pdc_strdup(p->pdc, value);
            p->resfilepending = pdc_true;
            break;

	case PDF_PARAMETER_PREFIX:
            if (p->prefix)
            {
                pdc_free(p->pdc, p->prefix);
                p->prefix = NULL;
            }
            /* because of downward compatibility */
            p->prefix = pdc_strdup(p->pdc, &value[value[0] == '/' ? 1 : 0]);
	    break;

	case PDF_PARAMETER_WARNING:
	    pdc_set_warnings(p->pdc, pdf_bool_value(p, key, value));
	    break;

        case PDF_PARAMETER_OPENWARNING:
            p->debug['o'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_FONTWARNING:
            p->debug['F'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_ICCWARNING:
            p->debug['I'] = (char) pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_IMAGEWARNING:
	    p->debug['i'] = (char) pdf_bool_value(p, key, value);
	    break;

        case PDF_PARAMETER_PDIWARNING:
            p->debug['p'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_HONORICCPROFILE:
            p->debug['e'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_GLYPHWARNING:
            p->debug['g'] = (char) pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_RENDERINGINTENT:
            k = pdc_get_keycode(value, gs_renderingintents);
            if (k == PDC_KEY_NOTFOUND)
                pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            p->rendintent = (pdf_renderingintent) k;
            break;

        case PDF_PARAMETER_PRESERVEOLDPANTONENAMES:
            p->preserveoldpantonenames = pdf_bool_value(p, key, value);
            break;

        case PDF_PARAMETER_SPOTCOLORLOOKUP:
            p->spotcolorlookup = pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_INHERITGSTATE:
	    p->inheritgs = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_PDISTRICT:
	    p->pdi_strict = pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_PDIUSEBOX:
            p->pdi_usebox = usebox;
            break;

	case PDF_PARAMETER_PASSTHROUGH:
	    p->debug['P'] = (char) !pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_HIDETOOLBAR:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= HideToolbar;
	    break;

	case PDF_PARAMETER_HIDEMENUBAR:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= HideMenubar;
	    break;

	case PDF_PARAMETER_HIDEWINDOWUI:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= HideWindowUI;
	    break;

	case PDF_PARAMETER_FITWINDOW:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= FitWindow;
	    break;

	case PDF_PARAMETER_CENTERWINDOW:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= CenterWindow;
	    break;

	case PDF_PARAMETER_DISPLAYDOCTITLE:
	    if (pdf_bool_value(p, key, value))
		p->ViewerPreferences.flags |= DisplayDocTitle;
	    break;

	case PDF_PARAMETER_NONFULLSCREENPAGEMODE:
	    if (!strcmp(value, "useoutlines")) {
		p->ViewerPreferences.flags |= NonFullScreenPageModeOutlines;
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeThumbs;
	    } else if (!strcmp(value, "usethumbs")) {
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeOutlines;
		p->ViewerPreferences.flags |= NonFullScreenPageModeThumbs;
	    } else if (!strcmp(value, "usenone")) {
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeOutlines;
		p->ViewerPreferences.flags &= ~NonFullScreenPageModeThumbs;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }

	    break;

	case PDF_PARAMETER_DIRECTION:
	    if (!strcmp(value, "r2l")) {
		p->ViewerPreferences.flags |= DirectionR2L;
	    } else if (!strcmp(value, "l2r")) {
		p->ViewerPreferences.flags &= ~DirectionR2L;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }
	    break;

	case PDF_PARAMETER_VIEWAREA:
            p->ViewerPreferences.ViewArea = usebox;
	    break;

	case PDF_PARAMETER_VIEWCLIP:
            p->ViewerPreferences.ViewClip = usebox;
            break;

	case PDF_PARAMETER_PRINTAREA:
            p->ViewerPreferences.PrintArea = usebox;
            break;

	case PDF_PARAMETER_PRINTCLIP:
            p->ViewerPreferences.PrintClip = usebox;
            break;

        case PDF_PARAMETER_TOPDOWN:
            if (pdf_bool_value(p, key, value))
                p->ydirection = (float) -1.0;
            else
                p->ydirection = (float) 1.0;
            break;

        case PDF_PARAMETER_USERCOORDINATES:
            p->usercoordinates = pdf_bool_value(p, key, value);
            break;

	case PDF_PARAMETER_OPENACTION:
	    pdf_cleanup_destination(p, &p->open_action);

	    pdf_parse_destination_optlist(p,
                value, &p->open_action, 1, pdf_openaction);
	    break;

	case PDF_PARAMETER_OPENMODE:
	    if (!strcmp(value, "none")) {
		p->open_mode = open_none;
	    } else if (!strcmp(value, "bookmarks")) {
		p->open_mode = open_bookmarks;
	    } else if (!strcmp(value, "thumbnails")) {
		p->open_mode = open_thumbnails;
	    } else if (!strcmp(value, "fullscreen")) {
		p->open_mode = open_fullscreen;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }
	    break;

	case PDF_PARAMETER_BOOKMARKDEST:
	    pdf_cleanup_destination(p, &p->bookmark_dest);

	    pdf_parse_destination_optlist(p,
                value, &p->bookmark_dest, 0, pdf_bookmark);
	    break;

	case PDF_PARAMETER_FILLRULE:
	    if (!strcmp(value, "winding")) {
		p->fillrule = pdf_fill_winding;
	    } else if (!strcmp(value, "evenodd")) {
		p->fillrule = pdf_fill_evenodd;
	    } else {
		pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
	    }
	    break;

        case PDF_PARAMETER_TEXTFORMAT:
            p->textformat = textformat;
            break;

        case PDF_PARAMETER_HYPERTEXTFORMAT:
            p->hypertextformat = textformat;
            break;

        case PDF_PARAMETER_HYPERTEXTENCODING:
        {
            pdc_encoding enc;

            if (!*value)
            {
                enc = pdc_unicode;
            }
            else
            {
                enc = pdf_find_encoding(p, (const char *) value);
                if (enc == pdc_invalidenc)
                    enc = pdf_insert_encoding(p, (const char *) value);
                if (enc < 0 && enc != pdc_unicode)
                    pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0);
            }
            p->hypertextencoding = enc;
            break;
        }

	/* deprecated */
	case PDF_PARAMETER_NATIVEUNICODE:
	    (void) pdf_bool_value(p, key, value);
	    break;

	case PDF_PARAMETER_TRANSITION:
	    pdf_set_transition(p, value);
	    break;

	case PDF_PARAMETER_BASE:
	    if (p->base) {
		pdc_free(p->pdc, p->base);
		p->base = NULL;
	    }

	    p->base = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_PARAMETERS:
	    if (p->launchlink_parameters) {
		pdc_free(p->pdc, p->launchlink_parameters);
		p->launchlink_parameters = NULL;
	    }
	    p->launchlink_parameters = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_OPERATION:
	    if (p->launchlink_operation) {
		pdc_free(p->pdc, p->launchlink_operation);
		p->launchlink_operation = NULL;
	    }
	    p->launchlink_operation = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_LAUNCHLINK_DEFAULTDIR:
	    if (p->launchlink_defaultdir) {
		pdc_free(p->pdc, p->launchlink_defaultdir);
		p->launchlink_defaultdir = NULL;
	    }
	    p->launchlink_defaultdir = pdc_strdup(p->pdc, value);
	    break;

	case PDF_PARAMETER_TRACE:
	    if (pdf_bool_value(p, key, value)) {
		p->debug['t'] = 1;
		pdc_set_trace(p->pdc, "PDFlib " PDFLIB_VERSIONSTRING);
	    } else {
		pdc_set_trace(p->pdc, NULL);
		p->debug['t'] = 0;
	    }
	    break;

	case PDF_PARAMETER_TRACEFILE:
	    pdc_set_tracefile(p->pdc, value);
	    break;

	case PDF_PARAMETER_TRACEMSG:
	    /* do nothing -- client-supplied string will show up in the trace */
	    break;

	case PDF_PARAMETER_SERIAL:
	case PDF_PARAMETER_LICENSE:
	    break;

	case PDF_PARAMETER_LICENSEFILE:
	    break;

	default:
	    pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0);
	    break;
    } /* switch */
} /* PDF_set_parameter */
/*
 * Create a PDF color space corresponding to a PostScript color space.
 * For parameterless color spaces, set *pvalue to a (literal) string with
 * the color space name; for other color spaces, create a cos_array_t if
 * necessary and set *pvalue to refer to it.  In the latter case, if
 * by_name is true, return a string /Rxxxx rather than a reference to
 * the actual object.
 *
 * If ppranges is not NULL, then if  the domain of the color space had
 * to be scaled (to convert a CIEBased space to ICCBased), store a pointer
 * to the ranges in *ppranges, otherwise set *ppranges to 0.
 */
int
pdf_color_space_named(gx_device_pdf *pdev, cos_value_t *pvalue,
		const gs_range_t **ppranges,
		const gs_color_space *pcs,
		const pdf_color_space_names_t *pcsn,
		bool by_name, const byte *res_name, int name_length)
{
    gs_color_space_index csi = gs_color_space_get_index(pcs);
    cos_array_t *pca;
    cos_dict_t *pcd;
    cos_value_t v;
    const gs_cie_common *pciec;
    gs_function_t *pfn;
    const gs_range_t *ranges = 0;
    uint serialized_size;
    byte *serialized = NULL, serialized0[100];
    pdf_resource_t *pres = NULL;
    int code;

    if (ppranges)
	*ppranges = 0;		/* default */
    switch (csi) {
    case gs_color_space_index_DeviceGray:
	cos_c_string_value(pvalue, pcsn->DeviceGray);
	return 0;
    case gs_color_space_index_DeviceRGB:
	cos_c_string_value(pvalue, pcsn->DeviceRGB);
	return 0;
    case gs_color_space_index_DeviceCMYK:
	cos_c_string_value(pvalue, pcsn->DeviceCMYK);
	return 0;
    case gs_color_space_index_Pattern:
	if (!pcs->params.pattern.has_base_space) {
	    cos_c_string_value(pvalue, "/Pattern");
	    return 0;
	}
	break;
    case gs_color_space_index_CIEICC:
        /*
	 * Take a special early exit for unrecognized ICCBased color spaces,
	 * or for PDF 1.2 output (ICCBased color spaces date from PDF 1.3).
	 */
        if (pcs->params.icc.picc_info->picc == 0 ||
	    pdev->CompatibilityLevel < 1.3
	    ) {
	    if (res_name != NULL)
		return 0; /* Ignore .includecolorspace */
            return pdf_color_space( pdev, pvalue, ppranges,
                                    pcs->base_space,
                                    pcsn, by_name);
	}
        break;
    default:
	break;
    }
    if (pdev->params.ColorConversionStrategy == ccs_CMYK && 
	    csi != gs_color_space_index_DeviceCMYK &&
	    csi != gs_color_space_index_DeviceGray &&
	    csi != gs_color_space_index_Pattern)
	return_error(gs_error_rangecheck);
    if (pdev->params.ColorConversionStrategy == ccs_sRGB && 
	    csi != gs_color_space_index_DeviceRGB && 
	    csi != gs_color_space_index_DeviceGray &&
	    csi != gs_color_space_index_Pattern)
	return_error(gs_error_rangecheck);
    if (pdev->params.ColorConversionStrategy == ccs_Gray && 
	    csi != gs_color_space_index_DeviceGray &&
	    csi != gs_color_space_index_Pattern)
	return_error(gs_error_rangecheck);
    /* Check whether we already have a PDF object for this color space. */
    if (pcs->id != gs_no_id)
	pres = pdf_find_resource_by_gs_id(pdev, resourceColorSpace, pcs->id);
    if (pres == NULL) {
	stream s;

	s_init(&s, pdev->memory);
	swrite_position_only(&s);
	code = cs_serialize(pcs, &s);
	if (code < 0)
	    return_error(gs_error_unregistered); /* Must not happen. */
	serialized_size = stell(&s);
	sclose(&s);
	if (serialized_size <= sizeof(serialized0))
	    serialized = serialized0;
	else {
	    serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space");
	    if (serialized == NULL)
		return_error(gs_error_VMerror);
	}
	swrite_string(&s, serialized, serialized_size);
	code = cs_serialize(pcs, &s);
	if (code < 0)
	    return_error(gs_error_unregistered); /* Must not happen. */
	if (stell(&s) != serialized_size) 
	    return_error(gs_error_unregistered); /* Must not happen. */
	sclose(&s);
	pres = pdf_find_cspace_resource(pdev, serialized, serialized_size);
	if (pres != NULL) {
	    if (serialized != serialized0)
		gs_free_object(pdev->pdf_memory, serialized, "pdf_color_space");
	    serialized = NULL;
	}
    }
    if (pres) {
	const pdf_color_space_t *const ppcs =
	    (const pdf_color_space_t *)pres;

	if (ppranges != 0 && ppcs->ranges != 0)
	    *ppranges = ppcs->ranges;
	pca = (cos_array_t *)pres->object;
	goto ret;
    }

    /* Space has parameters -- create an array. */
    pca = cos_array_alloc(pdev, "pdf_color_space");
    if (pca == 0)
	return_error(gs_error_VMerror);

    switch (csi) {

    case gs_color_space_index_CIEICC:
	code = pdf_iccbased_color_space(pdev, pvalue, pcs, pca);
        break;

    case gs_color_space_index_CIEA: {
	/* Check that we can represent this as a CalGray space. */
	const gs_cie_a *pcie = pcs->params.a;
	bool unitary = cie_ranges_are_0_1(&pcie->RangeA, 1);
	bool identityA = (pcie->MatrixA.u == 1 && pcie->MatrixA.v == 1 && 
	                  pcie->MatrixA.w == 1);
	gs_vector3 expts;

	pciec = (const gs_cie_common *)pcie;
	if (!pcie->common.MatrixLMN.is_identity) {
	    code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec,
					 &pcie->RangeA, ONE_STEP_NOT, NULL,
					 &ranges);
	    break;
	}
	if (unitary && identityA &&
	    CIE_CACHE_IS_IDENTITY(&pcie->caches.DecodeA) &&
	    CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts) &&
	    expts.v == expts.u && expts.w == expts.u
	    ) {
	    DO_NOTHING;
	} else if (unitary && identityA &&
		   CIE_CACHE3_IS_IDENTITY(pcie->common.caches.DecodeLMN) &&
		   cie_vector_cache_is_exponential(&pcie->caches.DecodeA, &expts.u)
		   ) {
	    DO_NOTHING;
	} else {
	    code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec,
					 &pcie->RangeA, ONE_STEP_NOT, NULL,
					 &ranges);
	    break;
	}
	code = cos_array_add(pca, cos_c_string_value(&v, "/CalGray"));
	if (code < 0)
	    return code;
	pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
	if (pcd == 0)
	    return_error(gs_error_VMerror);
	if (expts.u != 1) {
	    code = cos_dict_put_c_key_real(pcd, "/Gamma", expts.u);
	    if (code < 0)
		return code;
	}
    }
    cal:
    /* Finish handling a CIE-based color space (Calxxx or Lab). */
    if (code < 0)
	return code;
    code = pdf_finish_cie_space(pca, pcd, pciec);
    break;

    case gs_color_space_index_CIEABC: {
	/* Check that we can represent this as a CalRGB space. */
	const gs_cie_abc *pcie = pcs->params.abc;
	bool unitary = cie_ranges_are_0_1(pcie->RangeABC.ranges, 3);
	gs_vector3 expts;
	const gs_matrix3 *pmat = NULL;
	cie_cache_one_step_t one_step =
	    cie_cached_abc_is_one_step(pcie, &pmat);

	pciec = (const gs_cie_common *)pcie;
	if (unitary) {
	    switch (one_step) {
	    case ONE_STEP_ABC:
		if (CIE_VECTOR3_CACHE_IS_EXPONENTIAL(pcie->caches.DecodeABC.caches, expts))
		    goto calrgb;
		break;
	    case ONE_STEP_LMN:
		if (CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts))
		    goto calrgb;
	    default:
		break;
	    }
	}
	if (cie_is_lab(pcie)) {
	    /* Represent this as a Lab space. */
	    pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
	    if (pcd == 0)
		return_error(gs_error_VMerror);
	    code = pdf_put_lab_color_space(pca, pcd, pcie->RangeABC.ranges);
	    goto cal;
	} else {
	    code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ", pciec,
					 pcie->RangeABC.ranges,
					 one_step, pmat, &ranges);
	    break;
	}
    calrgb:
	code = cos_array_add(pca, cos_c_string_value(&v, "/CalRGB"));
	if (code < 0)
	    return code;
	pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
	if (pcd == 0)
	    return_error(gs_error_VMerror);
	if (expts.u != 1 || expts.v != 1 || expts.w != 1) {
	    code = cos_dict_put_c_key_vector3(pcd, "/Gamma", &expts);
	    if (code < 0)
		return code;
	}
	if (!pmat->is_identity) {
	    cos_array_t *pcma =
		cos_array_alloc(pdev, "pdf_color_space(Matrix)");

	    if (pcma == 0)
		return_error(gs_error_VMerror);
	    if ((code = cos_array_add_vector3(pcma, &pmat->cu)) < 0 ||
		(code = cos_array_add_vector3(pcma, &pmat->cv)) < 0 ||
		(code = cos_array_add_vector3(pcma, &pmat->cw)) < 0 ||
		(code = cos_dict_put(pcd, (const byte *)"/Matrix", 7,
				     COS_OBJECT_VALUE(&v, pcma))) < 0
		)
		return code;
	}
    }
    goto cal;

    case gs_color_space_index_CIEDEF:
	code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ",
				     (const gs_cie_common *)pcs->params.def,
				     pcs->params.def->RangeDEF.ranges,
				     ONE_STEP_NOT, NULL, &ranges);
	break;

    case gs_color_space_index_CIEDEFG:
	code = pdf_convert_cie_space(pdev, pca, pcs, "CMYK",
				     (const gs_cie_common *)pcs->params.defg,
				     pcs->params.defg->RangeDEFG.ranges,
				     ONE_STEP_NOT, NULL, &ranges);
	break;

    case gs_color_space_index_Indexed:
	code = pdf_indexed_color_space(pdev, pvalue, pcs, pca);
	break;

    case gs_color_space_index_DeviceN:
        if (pdev->CompatibilityLevel < 1.3)
	    return_error(gs_error_rangecheck);
	pfn = gs_cspace_get_devn_function(pcs);
	/****** CURRENTLY WE ONLY HANDLE Functions ******/
	if (pfn == 0)
	    return_error(gs_error_rangecheck);
	{
	    cos_array_t *psna = 
		cos_array_alloc(pdev, "pdf_color_space(DeviceN)");
	    int i;
	    byte *name_string;
	    uint name_string_length;
	    cos_value_t v_attriburtes, *va = NULL;

	    if (psna == 0)
		return_error(gs_error_VMerror);
	    for (i = 0; i < pcs->params.device_n.num_components; ++i) {
	 	if ((code = pcs->params.device_n.get_colorname_string(
				  pdev->memory,
				  pcs->params.device_n.names[i], &name_string, 
				  &name_string_length)) < 0 ||
		    (code = pdf_string_to_cos_name(pdev, name_string, 
				  name_string_length, &v)) < 0 ||
		    (code = cos_array_add_no_copy(psna, &v)) < 0)
		    return code;
	    }
	    COS_OBJECT_VALUE(&v, psna);
	    if (pcs->params.device_n.colorants != NULL) {
		cos_dict_t *colorants  = cos_dict_alloc(pdev, "pdf_color_space(DeviceN)");
		cos_value_t v_colorants, v_separation, v_colorant_name;
		const gs_device_n_attributes *csa;
		pdf_resource_t *pres_attributes;

		if (colorants == NULL)
		    return_error(gs_error_VMerror);
		code = pdf_alloc_resource(pdev, resourceOther, 0, &pres_attributes, -1);
		if (code < 0)
		    return code;
		cos_become(pres_attributes->object, cos_type_dict);
		COS_OBJECT_VALUE(&v_colorants, colorants);
		code = cos_dict_put((cos_dict_t *)pres_attributes->object, 
		    (const byte *)"/Colorants", 10, &v_colorants);
		if (code < 0)
		    return code;
		for (csa = pcs->params.device_n.colorants; csa != NULL; csa = csa->next) {
	 	    code = pcs->params.device_n.get_colorname_string(pdev->memory,
				  csa->colorant_name, &name_string, &name_string_length);
		    if (code < 0)
			return code;
		    code = pdf_color_space(pdev, &v_separation, NULL, csa->cspace, pcsn, false);
		    if (code < 0)
			return code;
		    code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v_colorant_name);
		    if (code < 0)
			return code;
		    code = cos_dict_put(colorants, v_colorant_name.contents.chars.data, 
					v_colorant_name.contents.chars.size, &v_separation);
		    if (code < 0)
			return code;
		}
    		code = pdf_substitute_resource(pdev, &pres_attributes, resourceOther, NULL, true);
		if (code < 0)
		    return code;
		va = &v_attriburtes;
		COS_OBJECT_VALUE(va, pres_attributes->object);
	    }
	    if ((code = pdf_separation_color_space(pdev, pca, "/DeviceN", &v,
						   pcs->base_space,
					pfn, &pdf_color_space_names, va)) < 0)
		return code;
	}
	break;

    case gs_color_space_index_Separation:
	pfn = gs_cspace_get_sepr_function(pcs);
	/****** CURRENTLY WE ONLY HANDLE Functions ******/
	if (pfn == 0)
	    return_error(gs_error_rangecheck);
	{
	    byte *name_string;
	    uint name_string_length;
	    if ((code = pcs->params.separation.get_colorname_string(
				  pdev->memory, 
				  pcs->params.separation.sep_name, &name_string, 
				  &name_string_length)) < 0 ||
		(code = pdf_string_to_cos_name(pdev, name_string, 
				      name_string_length, &v)) < 0 ||
		(code = pdf_separation_color_space(pdev, pca, "/Separation", &v,
					    pcs->base_space,
					    pfn, &pdf_color_space_names, NULL)) < 0)
		return code;
	}
	break;

    case gs_color_space_index_Pattern:
	if ((code = pdf_color_space(pdev, pvalue, ppranges,
				    pcs->base_space,
				    &pdf_color_space_names, false)) < 0 ||
	    (code = cos_array_add(pca,
				  cos_c_string_value(&v, "/Pattern"))) < 0 ||
	    (code = cos_array_add(pca, pvalue)) < 0
	    )
	    return code;
	break;

    default:
	return_error(gs_error_rangecheck);
    }
    /*
     * Register the color space as a resource, since it must be referenced
     * by name rather than directly.
     */
    {
	pdf_color_space_t *ppcs;

	if (code < 0 ||
	    (code = pdf_alloc_resource(pdev, resourceColorSpace, pcs->id,
				       &pres, -1)) < 0
	    ) {
	    COS_FREE(pca, "pdf_color_space");
	    return code;
	}
	pdf_reserve_object_id(pdev, pres, 0);
	if (res_name != NULL) {
	    int l = min(name_length, sizeof(pres->rname) - 1);
	    
	    memcpy(pres->rname, res_name, l);
	    pres->rname[l] = 0;
	}
	ppcs = (pdf_color_space_t *)pres;
	if (serialized == serialized0) {
	    serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space");
	    if (serialized == NULL)
		return_error(gs_error_VMerror);
	    memcpy(serialized, serialized0, serialized_size);
	}
	ppcs->serialized = serialized;
	ppcs->serialized_size = serialized_size;
	if (ranges) {
	    int num_comp = gs_color_space_num_components(pcs);
	    gs_range_t *copy_ranges = (gs_range_t *)
		gs_alloc_byte_array(pdev->pdf_memory, num_comp,
				    sizeof(gs_range_t), "pdf_color_space");

	    if (copy_ranges == 0) {
		COS_FREE(pca, "pdf_color_space");
		return_error(gs_error_VMerror);
	    }
	    memcpy(copy_ranges, ranges, num_comp * sizeof(gs_range_t));
	    ppcs->ranges = copy_ranges;
	    if (ppranges)
		*ppranges = copy_ranges;
	} else
	    ppcs->ranges = 0;
	pca->id = pres->object->id;
	COS_FREE(pres->object, "pdf_color_space");
	pres->object = (cos_object_t *)pca;
	cos_write_object(COS_OBJECT(pca), pdev);
    }
 ret:
    if (by_name) {
	/* Return a resource name rather than an object reference. */
	discard(COS_RESOURCE_VALUE(pvalue, pca));
    } else
	discard(COS_OBJECT_VALUE(pvalue, pca));
    if (pres != NULL) {
	pres->where_used |= pdev->used_mask;
	code = pdf_add_resource(pdev, pdev->substream_Resources, "/ColorSpace", pres);
	if (code < 0)
	    return code;
    }
    return 0;
}
Exemple #5
0
static void
pdf_read_resourcefile(PDF *p, const char *filename)
{
    pdc_file   *fp = NULL;
    char      **linelist;
    char       *line;
    char       *category = NULL;
    char       *uprfilename = NULL;
#if defined(AS400) || defined(WIN32)
#define BUFSIZE 2048
    char        buffer[BUFSIZE];
#ifdef WIN32
    char        regkey[128];
    HKEY        hKey = NULL;
    DWORD       size, lType;
#endif
#endif
    int         il, nlines = 0, nextcat, begin;

#ifdef WIN32

/* don't add patchlevel's to registry searchpath */
#define stringiz1(x)	#x
#define stringiz(x)	stringiz1(x)

#define PDFLIBKEY  "Software\\PDFlib\\PDFlib\\"

    strcpy(regkey, PDFLIBKEY);
    strcat(regkey, PDFLIB_VERSIONSTRING);

    /* process registry entries */
    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L,
        (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
    {
        size = BUFSIZE - 2;
        if (RegQueryValueExA(hKey, "SearchPath", (LPDWORD) NULL,
                             &lType, (LPBYTE) buffer, &size)
            == ERROR_SUCCESS && *buffer)
        {
            char **pathlist;
            int ip, np;

            np = pdc_split_stringlist(p->pdc, buffer,
                                      ";", &pathlist);
            for (ip = 0; ip < np; ip++)
                pdf_add_resource(p, "SearchPath", pathlist[ip]);
            pdc_cleanup_stringlist(p->pdc, pathlist);
        }

        size = BUFSIZE - 2;
        if (RegQueryValueExA(hKey, "prefix", (LPDWORD) NULL,
                             &lType, (LPBYTE) buffer, &size)
            == ERROR_SUCCESS && *buffer)
        {
            /* '/' because of downward compatibility */
            if (p->prefix)
            {
                pdc_free(p->pdc, p->prefix);
                p->prefix = NULL;
            }
            p->prefix = pdc_strdup(p->pdc,
                            &buffer[buffer[0] == '/' ? 1 : 0]);
        }

        RegCloseKey(hKey);
    }
#endif  /* WIN32 */

#ifdef AS400
    strcpy (buffer, "/pdflib/");
    strcat (buffer, PDFLIB_VERSIONSTRING);
    il = (int) strlen(buffer);
    strcat (buffer, "/fonts");
    pdf_add_resource(p, "SearchPath", buffer);
    strcpy(&buffer[il], "/bind/data");
    pdf_add_resource(p, "SearchPath", buffer);
#endif  /* AS400 */

    /* searching for name of upr file */
    uprfilename = (char *)filename;
    if (!uprfilename || *uprfilename == '\0')
    {
        /* user-supplied upr file */
        uprfilename = pdc_getenv(RESOURCEFILE);
        if (!uprfilename || *uprfilename == '\0')
        {
            uprfilename = DEFAULTRESOURCEFILE;

            /* user-supplied upr file */
            fp = pdf_fopen(p, uprfilename, NULL, 0);
            if (fp == NULL)
            {
                uprfilename = NULL;
#ifdef WIN32
                /* process registry entries */
                if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L,
                    (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
                {
                    size = BUFSIZE - 2;
                    if (RegQueryValueExA(hKey, "resourcefile", (LPDWORD) NULL,
                                         &lType, (LPBYTE) buffer, &size)
                        == ERROR_SUCCESS && *buffer)
                    {
                        uprfilename = buffer;
                    }

                    RegCloseKey(hKey);
                }
#endif  /* WIN32 */
            }
        }

        if (!uprfilename || *uprfilename == '\0')
            return;

        if (p->resourcefilename)
        {
            pdc_free(p->pdc, p->resourcefilename);
            p->resourcefilename = NULL;
        }
        p->resourcefilename = pdc_strdup(p->pdc, uprfilename);
    }

    /* read upr file */
    if ((fp == NULL) && ((fp = pdf_fopen(p, uprfilename, "UPR ", 0)) == NULL))
	pdc_error(p->pdc, -1, 0, 0, 0, 0);

    nlines = pdc_read_textfile(p->pdc, fp, &linelist);
    pdc_fclose(fp);

    if (!nlines) return;

    /* Lines loop */
    begin = 1;
    nextcat = 0;
    for (il = 0; il < nlines; il++)
    {
        line = linelist[il];

        /* Next category */
        if (line[0] == '.' && strlen(line) == 1)
        {
            begin = 0;
            nextcat = 1;
            continue;
        }

        /* Skip category list */
        if (begin) continue;

        /* Prefiex or category expected */
        if (nextcat)
        {
            /* Directory prefix */
            if (line[0] == '/')
            {
                if (p->prefix)
                {
                    pdc_free(p->pdc, p->prefix);
                    p->prefix = NULL;
                }
                p->prefix = pdc_strdup(p->pdc, &line[1]);
                continue;
            }

            /* Ressource Category */
            category = line;
            nextcat = 0;
            continue;
        }

        /* Add resource */
        pdf_add_resource(p, category, line);
    }

    pdc_cleanup_stringlist(p->pdc, linelist);
}