summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Melichev <igor.melichev@artifex.com>2005-03-30 12:48:08 +0000
committerIgor Melichev <igor.melichev@artifex.com>2005-03-30 12:48:08 +0000
commit6c182a489d1bc69f4432c46e620920400f7435fe (patch)
tree5bf003aadf86f47ead116e2d4e229aa0002d1b09
parent14002b0fe3f84f521b8cb899cfc16df843ff28d6 (diff)
downloadghostpdl-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.c36
-rw-r--r--gs/src/gdevpdfi.c58
-rw-r--r--gs/src/gdevpdfx.h6
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);