diff options
author | L Peter Deutsch <lpd@ghostscript.com> | 2000-09-11 02:14:09 +0000 |
---|---|---|
committer | L Peter Deutsch <lpd@ghostscript.com> | 2000-09-11 02:14:09 +0000 |
commit | 34e6ce71c14fa3cc24dd84daf41f06e57a718437 (patch) | |
tree | 066da6a98184347c7460b6bdb49a8fd0f7e5aa8d /gs/src/gdevpdfi.c | |
parent | 39207d100fca4d9759ed65ca70aa0c3742cfcb09 (diff) | |
download | ghostpdl-34e6ce71c14fa3cc24dd84daf41f06e57a718437.tar.gz |
Adds the ability to write some PDF 1.4 constructs: graphics state parameters
AIS, BM, ca/CA, and TK, and images with soft masks (except for Matte).
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@703 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs/src/gdevpdfi.c')
-rw-r--r-- | gs/src/gdevpdfi.c | 291 |
1 files changed, 196 insertions, 95 deletions
diff --git a/gs/src/gdevpdfi.c b/gs/src/gdevpdfi.c index ddd08f2a3..92d4e0f02 100644 --- a/gs/src/gdevpdfi.c +++ b/gs/src/gdevpdfi.c @@ -27,6 +27,7 @@ #include "gdevpdfo.h" /* for data stream */ #include "gxcspace.h" #include "gximage3.h" +#include "gximag3x.h" #include "gsiparm4.h" /* Forward references */ @@ -35,6 +36,8 @@ private image_enum_proc_end_image(pdf_image_end_image); private image_enum_proc_end_image(pdf_image_end_image_object); private IMAGE3_MAKE_MID_PROC(pdf_image3_make_mid); private IMAGE3_MAKE_MCDE_PROC(pdf_image3_make_mcde); +private IMAGE3X_MAKE_MID_PROC(pdf_image3x_make_mid); +private IMAGE3X_MAKE_MCDE_PROC(pdf_image3x_make_mcde); private const gx_image_enum_procs_t pdf_image_enum_procs = { pdf_image_plane_data, @@ -135,6 +138,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, pdf_image_enum *pie; gs_image_format_t format; const gs_color_space *pcs; + gs_color_space cs_gray_temp; cos_value_t cs_value; int num_components; bool is_mask = false, in_line = false; @@ -148,6 +152,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, gs_pixel_image_t pixel; /* we may change some components */ gs_image1_t type1; gs_image3_t type3; + gs_image3x_t type3x; gs_image4_t type4; } image; ulong nbytes; @@ -184,6 +189,21 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, pdf_image3_make_mid, pdf_image3_make_mcde, pinfo); } + case IMAGE3X_IMAGETYPE: { + /* See ImageType3 above for more information. */ + const gs_image3x_t *pim3x = (const gs_image3x_t *)pic; + + if (pdev->CompatibilityLevel < 1.4) + goto nyi; + if (prect && !(prect->p.x == 0 && prect->p.y == 0 && + prect->q.x == pim3x->Width && + prect->q.y == pim3x->Height)) + goto nyi; + return gx_begin_image3x_generic((gx_device *)pdev, pis, pmat, pic, + prect, pdcolor, pcpath, mem, + pdf_image3x_make_mid, + pdf_image3x_make_mcde, pinfo); + } case 4: if (pdev->CompatibilityLevel < 1.3) goto nyi; @@ -207,12 +227,20 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, code = pdf_open_page(pdev, PDF_IN_STREAM); if (code < 0) return code; - if (is_mask && context != PDF_IMAGE_TYPE3_MASK) { - code = pdf_set_drawing_color(pdev, pdcolor, &pdev->fill_color, - &psdf_set_fill_color_commands); - if (code < 0) - goto nyi; - } + if (context == PDF_IMAGE_TYPE3_MASK) { + /* + * The soft mask for an ImageType 3x image uses a DevicePixel + * color space, which pdf_color_space() can't handle. Patch it + * to DeviceGray here. + */ + gs_cspace_init_DeviceGray(&cs_gray_temp); + pcs = &cs_gray_temp; + } else if (is_mask) + code = pdf_prepare_imagemask(pdev, pis, pdcolor); + else + code = pdf_prepare_image(pdev, pis); + if (code < 0) + goto nyi; if (prect) rect = *prect; else { @@ -297,95 +325,7 @@ gdev_pdf_begin_typed_image(gx_device * dev, const gs_imager_state * pis, PDF_IMAGE_DEFAULT); } -/* - * For ImageType 3 images, we create temporary dummy (null) devices that - * forward the begin_typed_image call to the implementation above. - */ -private int -pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem) -{ - gx_device *fdev; - int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem); - - if (code < 0) - return code; - gx_device_set_target((gx_device_forward *)fdev, tdev); - *pmxdev = fdev; - return 0; -} -/* Implement the mask image device. */ -private dev_proc_begin_typed_image(pdf_mid_begin_typed_image); -private int -pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height, - gs_memory_t *mem) -{ - int code = pdf_make_mxd(pmidev, dev, mem); - - if (code < 0) - return code; - set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image); - return 0; -} -private int -pdf_mid_begin_typed_image(gx_device * dev, const gs_imager_state * pis, - const gs_matrix *pmat, const gs_image_common_t *pic, - const gs_int_rect * prect, - const gx_drawing_color * pdcolor, - const gx_clip_path * pcpath, gs_memory_t * mem, - gx_image_enum_common_t ** pinfo) -{ - /* The target of the null device is the pdfwrite device. */ - gx_device_pdf *const pdev = (gx_device_pdf *) - ((gx_device_null *)dev)->target; - int code = pdf_begin_typed_image - (pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, - PDF_IMAGE_TYPE3_MASK); - - if (code < 0) - return code; - if ((*pinfo)->procs != &pdf_image_object_enum_procs) { - /* We couldn't handle the mask image. Bail out. */ - /* (This is never supposed to happen.) */ - return_error(gs_error_rangecheck); - } - return code; -} -/* Implement the mask clip device. */ -private int -pdf_image3_make_mcde(gx_device *dev, const gs_imager_state *pis, - const gs_matrix *pmat, const gs_image_common_t *pic, - const gs_int_rect *prect, const gx_drawing_color *pdcolor, - const gx_clip_path *pcpath, gs_memory_t *mem, - gx_image_enum_common_t **pinfo, - gx_device **pmcdev, gx_device *midev, - gx_image_enum_common_t *pminfo, - const gs_int_point *origin) -{ - int code = pdf_make_mxd(pmcdev, midev, mem); - pdf_image_enum *pmie; - pdf_image_enum *pmce; - cos_stream_t *pmcs; - - if (code < 0) - return code; - code = pdf_begin_typed_image - ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem, - pinfo, PDF_IMAGE_TYPE3_DATA); - if (code < 0) - return code; - /* Add the /Mask entry to the image dictionary. */ - if ((*pinfo)->procs != &pdf_image_enum_procs) { - /* We couldn't handle the image. Bail out. */ - gx_image_end(*pinfo, false); - gs_free_object(mem, *pmcdev, "pdf_image3_make_mcde"); - return_error(gs_error_rangecheck); - } - pmie = (pdf_image_enum *)pminfo; - pmce = (pdf_image_enum *)(*pinfo); - pmcs = (cos_stream_t *)pmce->writer.pres->object; - return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/Mask", - pmie->writer.pres->object); -} +/* ---------------- All images ---------------- */ /* Process the next piece of an image. */ private int @@ -503,15 +443,176 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last, gs_free_object(pie->memory, pie, "pdf_end_image"); return code; } + /* End a normal image, drawing it. */ private int pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last) { return pdf_image_end_image_data(info, draw_last, true); } + +/* ---------------- Type 3/3x images ---------------- */ + +/* + * For both types of masked images, we create temporary dummy (null) devices + * that forward the begin_typed_image call to the implementation above. + */ +private int +pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem) +{ + gx_device *fdev; + int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem); + + if (code < 0) + return code; + gx_device_set_target((gx_device_forward *)fdev, tdev); + *pmxdev = fdev; + return 0; +} + /* End the mask of an ImageType 3 image, not drawing it. */ private int pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last) { return pdf_image_end_image_data(info, draw_last, false); } + +/* ---------------- Type 3 images ---------------- */ + +/* Implement the mask image device. */ +private dev_proc_begin_typed_image(pdf_mid_begin_typed_image); +private int +pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height, + gs_memory_t *mem) +{ + int code = pdf_make_mxd(pmidev, dev, mem); + + if (code < 0) + return code; + set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image); + return 0; +} +private int +pdf_mid_begin_typed_image(gx_device * dev, const gs_imager_state * pis, + const gs_matrix *pmat, const gs_image_common_t *pic, + const gs_int_rect * prect, + const gx_drawing_color * pdcolor, + const gx_clip_path * pcpath, gs_memory_t * mem, + gx_image_enum_common_t ** pinfo) +{ + /* The target of the null device is the pdfwrite device. */ + gx_device_pdf *const pdev = (gx_device_pdf *) + ((gx_device_null *)dev)->target; + int code = pdf_begin_typed_image + (pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, + PDF_IMAGE_TYPE3_MASK); + + if (code < 0) + return code; + if ((*pinfo)->procs != &pdf_image_object_enum_procs) { + /* We couldn't handle the mask image. Bail out. */ + /* (This is never supposed to happen.) */ + return_error(gs_error_rangecheck); + } + return code; +} + +/* Implement the mask clip device. */ +private int +pdf_image3_make_mcde(gx_device *dev, const gs_imager_state *pis, + const gs_matrix *pmat, const gs_image_common_t *pic, + const gs_int_rect *prect, const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath, gs_memory_t *mem, + gx_image_enum_common_t **pinfo, + gx_device **pmcdev, gx_device *midev, + gx_image_enum_common_t *pminfo, + const gs_int_point *origin) +{ + int code = pdf_make_mxd(pmcdev, midev, mem); + pdf_image_enum *pmie; + pdf_image_enum *pmce; + cos_stream_t *pmcs; + + if (code < 0) + return code; + code = pdf_begin_typed_image + ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem, + pinfo, PDF_IMAGE_TYPE3_DATA); + if (code < 0) + return code; + /* Add the /Mask entry to the image dictionary. */ + if ((*pinfo)->procs != &pdf_image_enum_procs) { + /* We couldn't handle the image. Bail out. */ + gx_image_end(*pinfo, false); + gs_free_object(mem, *pmcdev, "pdf_image3_make_mcde"); + return_error(gs_error_rangecheck); + } + pmie = (pdf_image_enum *)pminfo; + pmce = (pdf_image_enum *)(*pinfo); + pmcs = (cos_stream_t *)pmce->writer.pres->object; + return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/Mask", + pmie->writer.pres->object); +} + +/* ---------------- Type 3x images ---------------- */ + +/* Implement the mask image device. */ +private int +pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height, + int depth, gs_memory_t *mem) +{ + int code = pdf_make_mxd(pmidev, dev, mem); + + if (code < 0) + return code; + set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image); + return 0; +} + +/* Implement the mask clip device. */ +private int +pdf_image3x_make_mcde(gx_device *dev, const gs_imager_state *pis, + const gs_matrix *pmat, const gs_image_common_t *pic, + const gs_int_rect *prect, + const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath, gs_memory_t *mem, + gx_image_enum_common_t **pinfo, + gx_device **pmcdev, gx_device *midev[2], + gx_image_enum_common_t *pminfo[2], + const gs_int_point origin[2]) +{ + int code; + pdf_image_enum *pmie; + pdf_image_enum *pmce; + cos_stream_t *pmcs; + int i; + + if (midev[0]) { + if (midev[1]) + return_error(gs_error_rangecheck); + i = 0; + } else if (midev[1]) + i = 1; + else + return_error(gs_error_rangecheck); + code = pdf_make_mxd(pmcdev, midev[i], mem); + if (code < 0) + return code; + code = pdf_begin_typed_image + ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem, + pinfo, PDF_IMAGE_TYPE3_DATA); + if (code < 0) + return code; + /* Add the /SMask entry to the image dictionary. */ + if ((*pinfo)->procs != &pdf_image_enum_procs) { + /* We couldn't handle the image. Bail out. */ + gx_image_end(*pinfo, false); + gs_free_object(mem, *pmcdev, "pdf_image3_make_mcde"); + return_error(gs_error_rangecheck); + } + pmie = (pdf_image_enum *)pminfo[i]; + pmce = (pdf_image_enum *)(*pinfo); + pmcs = (cos_stream_t *)pmce->writer.pres->object; + return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/SMask", + pmie->writer.pres->object); +} |