diff options
author | Igor Melichev <igor.melichev@artifex.com> | 2005-03-30 12:48:08 +0000 |
---|---|---|
committer | Igor Melichev <igor.melichev@artifex.com> | 2005-03-30 12:48:08 +0000 |
commit | 6c182a489d1bc69f4432c46e620920400f7435fe (patch) | |
tree | 5bf003aadf86f47ead116e2d4e229aa0002d1b09 | |
parent | 14002b0fe3f84f521b8cb899cfc16df843ff28d6 (diff) | |
download | ghostpdl-6c182a489d1bc69f4432c46e620920400f7435fe.tar.gz |
ps2write : Convert type 3,4 image into a clipped image (continued).
DETAILS :
1. Improved the prototype of pdf_setup_masked_image_converter.
2. Renamed 'autorelease' into 'write_on_close' for a better reflection of its meaning.
3. Renamed gx_device_pdf::image_mask_matrix into gx_device_pdf::converting_image_matrix.
3. Type 3 images now convert with no scaling to the device space (int pdf_begin_typed_image).
The mask image of the typoe 3 image is scaled to the size of the data image.
EXPECTED DIFFERENCES :
None.
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@5806 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r-- | gs/src/gdevpdfd.c | 36 | ||||
-rw-r--r-- | gs/src/gdevpdfi.c | 58 | ||||
-rw-r--r-- | gs/src/gdevpdfx.h | 6 |
3 files changed, 53 insertions, 47 deletions
diff --git a/gs/src/gdevpdfd.c b/gs/src/gdevpdfd.c index 723d23f67..da8bd8f58 100644 --- a/gs/src/gdevpdfd.c +++ b/gs/src/gdevpdfd.c @@ -534,7 +534,7 @@ write_image(gx_device_pdf *pdev, gx_device_memory *mdev, gs_matrix *m) if (m != NULL) - pdf_put_matrix(pdev, "W n", m, " cm\n"); + pdf_put_matrix(pdev, "W n ", m, " cm\n"); code = pdf_copy_color_data(pdev, mdev->base, sourcex, mdev->raster, gx_no_bitmap_id, 0, 0, mdev->width, mdev->height, &image, &writer, 2); @@ -866,12 +866,19 @@ lcvd_handle_fill_path_as_shading_coverage(gx_device *dev, } int -pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs_matrix *m, pdf_lcvd_t *cvd, - bool need_mask, int x, int y, int w, int h, bool autorelease) +pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs_matrix *m, pdf_lcvd_t **pcvd, + bool need_mask, int x, int y, int w, int h, bool write_on_close) { int code; gx_device_memory *mask = 0; + pdf_lcvd_t *cvd = *pcvd; + if (cvd == NULL) { + cvd = gs_alloc_struct(mem, pdf_lcvd_t, &st_pdf_lcvd_t, "pdf_image3_make_mid"); + if (cvd == NULL) + return_error(gs_error_VMerror); + *pcvd = cvd; + } cvd->pdev = pdev; gs_make_mem_device(&cvd->mdev, gdev_mem_device_for_bits(pdev->color_info.depth), mem, 0, (gx_device *)pdev); @@ -904,7 +911,7 @@ pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs code = (*dev_proc(mask, open_device))((gx_device *)mask); if (code < 0) return code; - if (autorelease) { + if (write_on_close) { code = (*dev_proc(mask, fill_rectangle))((gx_device *)mask, 0, 0, mask->width, mask->height, (gx_color_index)0); if (code < 0) @@ -913,7 +920,7 @@ pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs } cvd->std_fill_rectangle = dev_proc(&cvd->mdev, fill_rectangle); cvd->std_close_device = dev_proc(&cvd->mdev, close_device); - if (!autorelease) { + if (!write_on_close) { /* Type 3 images will write to the mask directly. */ dev_proc(&cvd->mdev, fill_rectangle) = (need_mask ? lcvd_fill_rectangle_shifted2 : lcvd_fill_rectangle_shifted); @@ -923,11 +930,10 @@ pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs dev_proc(&cvd->mdev, pattern_manage) = lcvd_pattern_manage; dev_proc(&cvd->mdev, fill_path) = lcvd_handle_fill_path_as_shading_coverage; cvd->m = *m; - if (autorelease) { + if (write_on_close) { cvd->mdev.is_open = true; mask->is_open = true; dev_proc(&cvd->mdev, close_device) = lcvd_close_device_with_writing; - mask->target = (gx_device *)cvd; } return 0; } @@ -990,16 +996,17 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath if (!convert_to_image) { /* Fallback to the default implermentation for handling a shading with CompatibilityLevel<=1.2 . */ - code = gx_default_fill_path(dev, pis, ppath, params, pdcolor, pcpath); + return gx_default_fill_path(dev, pis, ppath, params, pdcolor, pcpath); } else { /* Convert a shading into a bitmap with CompatibilityLevel<=1.2 . */ - pdf_lcvd_t cvd; + pdf_lcvd_t cvd, *pcvd = &cvd; int sx, sy; gs_fixed_rect bbox, bbox1; bool need_mask = gx_dc_pattern2_can_overlap(pdcolor); gs_matrix m; gs_point p; + gs_int_point rect_size; code = gx_path_bbox(ppath, &bbox); if (code < 0) @@ -1015,11 +1022,14 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath gs_distance_transform_inverse(sx * pdev->HWResolution[0] / 72, sy * pdev->HWResolution[0] / 72, &ctm_only(pis), &p); gs_make_identity(&m); + rect_size.x = fixed2int(bbox.q.x + fixed_half) - sx; + rect_size.y = fixed2int(bbox.q.y + fixed_half) - sy; + if (rect_size.x == 0 || rect_size.x == 0) + return 0; m.tx = p.x; m.ty = p.y; - code = pdf_setup_masked_image_converter(pdev, pdev->memory, &m, &cvd, need_mask, sx, sy, - fixed2int(bbox.q.x + fixed_half) - sx, - fixed2int(bbox.q.y + fixed_half) - sy, false); + code = pdf_setup_masked_image_converter(pdev, pdev->memory, &m, &pcvd, need_mask, sx, sy, + rect_size.x, rect_size.y, false); stream_puts(pdev->strm, "q\n"); if (code >= 0) code = gx_default_fill_path((gx_device *)&cvd.mdev, pis, ppath, params, pdcolor, pcpath); @@ -1027,8 +1037,8 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath code = pdf_dump_converted_image(pdev, &cvd); stream_puts(pdev->strm, "Q\n"); pdf_remove_masked_image_converter(pdev, &cvd, need_mask); + return code; } - return code; } if (code < 0) return code; diff --git a/gs/src/gdevpdfi.c b/gs/src/gdevpdfi.c index 108464f63..c2b94c0f4 100644 --- a/gs/src/gdevpdfi.c +++ b/gs/src/gdevpdfi.c @@ -36,6 +36,7 @@ #include "gxcolor2.h" #include "gxhldevc.h" + /* Forward references */ private image_enum_proc_plane_data(pdf_image_plane_data); private image_enum_proc_end_image(pdf_image_end_image); @@ -325,6 +326,10 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, } case 3: { const gs_image3_t *pim3 = (const gs_image3_t *)pic; + gs_image3_t pim3a; + const gs_image_common_t *pic1 = pic; + gs_matrix m, mi; + const gs_matrix *pmat1 = pmat; if (pdev->CompatibilityLevel < 1.2 || (pdev->CompatibilityLevel < 1.3 && (!PS2WRITE || !pdev->OrderResources))) @@ -333,11 +338,24 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, prect->q.x == pim3->Width && prect->q.y == pim3->Height)) goto nyi; + if (PS2WRITE && pdev->OrderResources && !pdev->PatternImagemask) { + gs_make_identity(&m); + pmat1 = &m; + m.tx = floor(pis->ctm.tx + 0.5); /* Round the origin against the image size distorsions */ + m.ty = floor(pis->ctm.ty + 0.5); + pim3a = *pim3; + gs_matrix_invert(&pim3a.ImageMatrix, &mi); + gs_make_identity(&pim3a.ImageMatrix); + gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix); + pic1 = (gs_image_common_t *)&pim3a; + /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */ + gs_matrix_multiply(&mi, &ctm_only(pis), &pdev->converting_image_matrix); + } /* * We handle ImageType 3 images in a completely different way: * the default implementation sets up the enumerator. */ - return gx_begin_image3_generic((gx_device *)pdev, pis, pmat, pic, + return gx_begin_image3_generic((gx_device *)pdev, pis, pmat1, pic1, prect, pdcolor, pcpath, mem, pdf_image3_make_mid, pdf_image3_make_mcde, pinfo); @@ -394,27 +412,15 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, goto nyi; if (PS2WRITE && pdev->OrderResources && !pdev->PatternImagemask) { gs_matrix m, m1, mi; - gs_point p; - gs_int_point q; - extern_st(st_pdf_lcvd_t); gs_image4_t pi4 = *(const gs_image4_t *)pic; gs_make_identity(&m1); gs_matrix_invert(&pic->ImageMatrix, &mi); gs_matrix_multiply(&mi, &ctm_only(pis), &m); - cvd = gs_alloc_struct(mem, pdf_lcvd_t, &st_pdf_lcvd_t, "pdf_begin_typed_image"); - if (cvd == NULL) - return_error(gs_error_VMerror); - gs_distance_transform_inverse(pis->ctm.tx * pdev->HWResolution[0] / 72, - pis->ctm.ty * pdev->HWResolution[0] / 72, &ctm_only(pis), &p); - q.x = (int)floor(pis->ctm.tx); - q.y = (int)floor(pis->ctm.ty); - code = pdf_setup_masked_image_converter(pdev, mem, &m, cvd, + code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd, true, 0, 0, pi4.Width, pi4.Height, false); if (code < 0) return code; - cvd->mask->target = 0; /* fixme : move the initialization out from - pdf_setup_masked_image_converter because it unuseful here. */ cvd->mdev.is_open = true; /* fixme: same as above. */ cvd->mask->is_open = true; /* fixme: same as above. */ cvd->mask_is_empty = false; @@ -849,7 +855,7 @@ use_image_as_pattern(gx_device_pdf *pdev, const pdf_resource_t *pres1, As a temporary hack use the offset of the image. fixme : This isn't generally correct, because the mask may be "transpozed" against the image. */ - gs_matrix m = pdev->image_mask_matrix; + gs_matrix m = pdev->converting_image_matrix; m.tx = pmat->tx; m.ty = pmat->ty; @@ -899,7 +905,7 @@ pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw, pdev->image_mask_scale = (double)pxo->data_height / pxo->height; pdev->image_mask_id = pdf_resource_id(pres); - pdev->image_mask_matrix = *mat; + pdev->converting_image_matrix = *mat; } else if (do_image == USE_AS_PATTERN) code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id); } @@ -1020,18 +1026,16 @@ pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height, if (PS2WRITE && pdev->OrderResources && !pdev->PatternImagemask) { gs_matrix m; - pdf_lcvd_t *cvd; - extern_st(st_pdf_lcvd_t); + pdf_lcvd_t *cvd = NULL; int code; gs_make_identity(&m); - cvd = gs_alloc_struct(mem, pdf_lcvd_t, &st_pdf_lcvd_t, "pdf_image3_make_mid"); - if (cvd == NULL) - return_error(gs_error_VMerror); - code = pdf_setup_masked_image_converter(pdev, mem, &m, cvd, + code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd, true, 0, 0, width, height, true); if (code < 0) return code; + cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with + pdf_image3_make_mcde. The latter will reset it. */ cvd->mask_is_empty = false; *pmidev = (gx_device *)cvd->mask; return 0; @@ -1087,17 +1091,9 @@ pdf_image3_make_mcde(gx_device *dev, const gs_imager_state *pis, if (PS2WRITE && pdev->OrderResources && !pdev->PatternImagemask) { /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/ pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target; - gs_point p; ((gx_device_memory *)midev)->target = NULL; - cvd->m.xx = pis->ctm.xx * 72 / pdev->HWResolution[0]; - cvd->m.xy = pis->ctm.xy * 72 / pdev->HWResolution[0]; - cvd->m.yx = pis->ctm.yx * 72 / pdev->HWResolution[1]; - cvd->m.yy = pis->ctm.yy * 72 / pdev->HWResolution[1]; - gs_distance_transform_inverse(origin->x * pdev->HWResolution[0] / 72, - origin->y * pdev->HWResolution[0] / 72, &ctm_only(pis), &p); - cvd->m.tx = p.x; - cvd->m.ty = p.y; + cvd->m = pdev->converting_image_matrix; cvd->mdev.mapped_x = origin->x; cvd->mdev.mapped_y = origin->y; *pmcdev = (gx_device *)&cvd->mdev; diff --git a/gs/src/gdevpdfx.h b/gs/src/gdevpdfx.h index 456a14791..9946429bf 100644 --- a/gs/src/gdevpdfx.h +++ b/gs/src/gdevpdfx.h @@ -644,7 +644,7 @@ struct gx_device_pdf_s { (which is being converted into a pattern) between 2 consecutive calls to pdf_image_end_image_data. */ gs_id image_mask_id; - gs_matrix image_mask_matrix; + gs_matrix converting_image_matrix; double image_mask_scale; #endif }; @@ -923,8 +923,8 @@ typedef struct { #define pdf_lcvd_t_max_ptrs (gx_device_memory_max_ptrs + 2) -int pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs_matrix *m, pdf_lcvd_t *cvd, - bool need_mask, int x, int y, int w, int h, bool autorelease); +int pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs_matrix *m, pdf_lcvd_t **pcvd, + bool need_mask, int x, int y, int w, int h, bool write_on_close); int pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd); void pdf_remove_masked_image_converter(gx_device_pdf *pdev, pdf_lcvd_t *cvd, bool need_mask); |