[gs-cvs] rev 8020 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Tue Jun 5 14:10:17 PDT 2007
Author: leonardo
Date: 2007-06-05 14:10:17 -0700 (Tue, 05 Jun 2007)
New Revision: 8020
Modified:
trunk/gs/src/devs.mak
trunk/gs/src/gdevpdfd.c
trunk/gs/src/gdevpdfi.c
trunk/gs/src/gsptype2.c
trunk/gs/src/gsshade.c
trunk/gs/src/gsshade.h
trunk/gs/src/gxcpath.c
trunk/gs/src/gxfill.c
trunk/gs/src/gxpath.h
Log:
Fix (shadings) : Optimize path manipulations for shading fill (continued 2).
DETAILS :
This is the 2nd step for the elimination of gs_shading_fill_path.
It excludes that function from high level devices.
After the last patch, ps2write is only device that calls gs_shading_fill_path
while converting a shading into an image.
This patch replaces that call with a call to gs_shading_do_fill_rectangle.
This patch also fixes the revision 8017 regression
with the change to gdevpdfi.c .
Minor changes :
1. lcvd_fill_rectangle_shifted_from_mdev appears to be same as lcvd_fill_rectangle_shifted.
Removing the 1st one.
2. path_scale appears almost same as gx_path_scale_exp2_shared.
Removing the 1st one.
3. In gdevpdfd.c, when the scale isn't dividing by 4,
the old code chooses a smaller scale by X.
The new code dies by Y for a better view.
It may cause minor differences in raster.
4. We're not sure why lcvd_get_clipping_box_from_target was used sometimes.
It looks incorrect. Replaced with lcvd_get_clipping_box_shifted_from_mdev.
5. gx_cpath_scale_exp2_shared didn't scale list->xmin, list->xmax.
6. gx_cpath_copy is defined and not used.
Saving it from a dead branch, because it may be useful in future.
EXPECTED DIFFERENCES :
Should fix pdfwrite rev 8017 regressions.
Modified: trunk/gs/src/devs.mak
===================================================================
--- trunk/gs/src/devs.mak 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/devs.mak 2007-06-05 21:10:17 UTC (rev 8020)
@@ -857,7 +857,7 @@
$(GLOBJ)gdevpdfd.$(OBJ) : $(GLSRC)gdevpdfd.c $(math__h) $(memory__h)\
$(gx_h) $(gxdevice_h) $(gxfixed_h) $(gxistate_h) $(gxpaint_h)\
$(gxcoord_h) $(gxdevmem_h) $(gxcolor2_h) $(gxhldevc_h)\
- $(gsstate_h) $(gserrors_h) $(gsptype2_h)\
+ $(gsstate_h) $(gserrors_h) $(gsptype2_h) $(gsshade_h)\
$(gzpath_h) $(gzcpath_h) $(gdevpdfx_h) $(gdevpdfg_h) $(gdevpdfo_h) $(gsutil_h)
$(GLCC) $(GLO_)gdevpdfd.$(OBJ) $(C_) $(GLSRC)gdevpdfd.c
Modified: trunk/gs/src/gdevpdfd.c
===================================================================
--- trunk/gs/src/gdevpdfd.c 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gdevpdfd.c 2007-06-05 21:10:17 UTC (rev 8020)
@@ -27,6 +27,7 @@
#include "gsstate.h"
#include "gserrors.h"
#include "gsptype2.h"
+#include "gsshade.h"
#include "gzpath.h"
#include "gzcpath.h"
#include "gdevpdfx.h"
@@ -520,21 +521,6 @@
return cvd->std_fill_rectangle((gx_device *)&cvd->mdev,
x - cvd->mdev.mapped_x, y - cvd->mdev.mapped_y, width, height, color);
}
-private int
-lcvd_fill_rectangle_shifted_from_mdev(gx_device *dev, int x, int y, int width, int height, gx_color_index color)
-{
- pdf_lcvd_t *cvd = (pdf_lcvd_t *)dev;
-
- return cvd->std_fill_rectangle((gx_device *)&cvd->mdev,
- x - cvd->mdev.mapped_x, y - cvd->mdev.mapped_y, width, height, color);
-}
-private void
-lcvd_get_clipping_box_from_target(gx_device *dev, gs_fixed_rect *pbox)
-{
- gx_device_memory *mdev = (gx_device_memory *)dev;
-
- (*dev_proc(mdev->target, get_clipping_box))(mdev->target, pbox);
-}
private void
lcvd_get_clipping_box_shifted_from_mdev(gx_device *dev, gs_fixed_rect *pbox)
{
@@ -998,9 +984,9 @@
/* 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);
- dev_proc(&cvd->mdev, get_clipping_box) = lcvd_get_clipping_box_from_target;
+ dev_proc(&cvd->mdev, get_clipping_box) = lcvd_get_clipping_box_shifted_from_mdev;
} else {
- dev_proc(&cvd->mdev, fill_rectangle) = lcvd_fill_rectangle_shifted_from_mdev;
+ dev_proc(&cvd->mdev, fill_rectangle) = lcvd_fill_rectangle_shifted;
dev_proc(&cvd->mdev, get_clipping_box) = lcvd_get_clipping_box_shifted_from_mdev;
}
dev_proc(&cvd->mdev, pattern_manage) = lcvd_pattern_manage;
@@ -1024,28 +1010,6 @@
}
}
-private int
-path_scale(gx_path *path, double scalex, double scaley)
-{
- segment *pseg = (segment *)path->first_subpath;
-
- for (;pseg != NULL; pseg = pseg->next) {
- pseg->pt.x = (fixed)floor(pseg->pt.x * scalex + 0.5);
- pseg->pt.y = (fixed)floor(pseg->pt.y * scaley + 0.5);
- if (pseg->type == s_curve) {
- curve_segment *s = (curve_segment *)pseg;
-
- s->p1.x = (fixed)floor(s->p1.x * scalex + 0.5);
- s->p1.y = (fixed)floor(s->p1.y * scaley + 0.5);
- s->p2.x = (fixed)floor(s->p2.x * scalex + 0.5);
- s->p2.y = (fixed)floor(s->p2.y * scaley + 0.5);
- }
- }
- path->position.x = (fixed)floor(path->position.x * scalex + 0.5);
- path->position.y = (fixed)floor(path->position.y * scaley + 0.5);
- return 0;
-}
-
/* ------ Driver procedures ------ */
/* Fill a path. */
@@ -1110,7 +1074,8 @@
gs_matrix m, save_ctm = ctm_only(pis), ms, msi, mm;
gs_int_point rect_size;
/* double scalex = 1.9, scaley = 1.4; debug purpose only. */
- double scale, scalex = 1.0, scaley = 1.0;
+ double scale, scalex, scaley;
+ int log2_scale_x = 0, log2_scale_y = 0;
gx_drawing_color dc = *pdcolor;
gs_pattern2_instance_t pi = *(gs_pattern2_instance_t *)dc.ccolor.pattern;
gs_state *pgs = gs_state_copy(pi.saved, gs_state_memory(pi.saved));
@@ -1150,12 +1115,13 @@
we prefer to deal only with integers being powers of 2
in order to avoid possible distorsions when scaling paths.
*/
- scalex = ceil(sqrt(scale));
- scalex = scaley = 1 << ilog2((int)scalex);
- if (scalex * scaley < scale)
- scalex *= 2;
- if (scalex * scaley < scale)
- scaley *= 2;
+ log2_scale_x = log2_scale_y = ilog2((int)ceil(sqrt(scale)));
+ if ((double)(1 << log2_scale_x) * (1 << log2_scale_y) < scale)
+ log2_scale_y++;
+ if ((double)(1 << log2_scale_x) * (1 << log2_scale_y) < scale)
+ log2_scale_x++;
+ scalex = (double)(1 << log2_scale_x);
+ scaley = (double)(1 << log2_scale_y);
rect_size.x = (int)floor(rect_size.x / scalex + 0.5);
rect_size.y = (int)floor(rect_size.y / scaley + 0.5);
gs_make_scaling(1.0 / scalex, 1.0 / scaley, &ms);
@@ -1182,32 +1148,11 @@
}
pdf_put_matrix(pdev, NULL, &cvd.m, " cm q\n");
cvd.write_matrix = false;
- if (code >= 0) {
- /* See gx_default_fill_path. */
- gx_clip_path cpath_intersection;
- gx_path path_intersection, path1, *p = &path_intersection;
-
- gx_path_init_local(&path_intersection, pdev->memory);
- gx_path_init_local(&path1, pdev->memory);
- gx_cpath_init_local_shared(&cpath_intersection, pcpath, pdev->memory);
- if ((code = gx_cpath_intersect(&cpath_intersection, ppath, params->rule, (gs_imager_state *)pis)) >= 0)
- code = gx_cpath_to_path(&cpath_intersection, &path_intersection);
- if (code >= 0 && scale > 1) {
- code = gx_path_copy(&path_intersection, &path1);
- if (code > 0) {
- p = &path1;
- code = path_scale(&path1, scalex, scaley);
- }
- }
- if (code >= 0)
- code = gx_dc_pattern2_fill_path(&dc, p, NULL, (gx_device *)&cvd.mdev);
- gx_path_free(&path_intersection, "gdev_pdf_fill_path");
- gx_path_free(&path1, "gdev_pdf_fill_path");
- gx_cpath_free(&cpath_intersection, "gdev_pdf_fill_path");
- }
- if (code >= 0) {
+ if (code >= 0)
+ code = gs_shading_do_fill_rectangle(pi.template.Shading,
+ NULL, (gx_device *)&cvd.mdev, (gs_imager_state *)pgs, !pi.shfill);
+ if (code >= 0)
code = pdf_dump_converted_image(pdev, &cvd);
- }
stream_puts(pdev->strm, "Q Q\n");
pdf_remove_masked_image_converter(pdev, &cvd, need_mask);
gs_setmatrix((gs_state *)pis, &save_ctm);
Modified: trunk/gs/src/gdevpdfi.c
===================================================================
--- trunk/gs/src/gdevpdfi.c 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gdevpdfi.c 2007-06-05 21:10:17 UTC (rev 8020)
@@ -1390,6 +1390,8 @@
return 0;
case pattern_manage__is_cpath_accum:
return 0;
+ case pattern_manage__shfill_doesnt_need_path:
+ return 0; /* gdev_pdf_fill_path still does need a path. */
}
return_error(gs_error_unregistered);
}
Modified: trunk/gs/src/gsptype2.c
===================================================================
--- trunk/gs/src/gsptype2.c 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gsptype2.c 2007-06-05 21:10:17 UTC (rev 8020)
@@ -331,7 +331,7 @@
else {
gs_state *pis = pinst->saved;
- return shading_path_add_box(ppath, &psh->params.BBox, &pis->ctm);
+ return gs_shading_path_add_box(ppath, &psh->params.BBox, &pis->ctm);
}
}
Modified: trunk/gs/src/gsshade.c
===================================================================
--- trunk/gs/src/gsshade.c 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gsshade.c 2007-06-05 21:10:17 UTC (rev 8020)
@@ -418,7 +418,7 @@
/* Add a user-space rectangle to a path. */
int
-shading_path_add_box(gx_path *ppath, const gs_rect *pbox,
+gs_shading_path_add_box(gx_path *ppath, const gs_rect *pbox,
const gs_matrix_fixed *pmat)
{
gs_fixed_point pt;
@@ -527,7 +527,7 @@
}
code = gx_cpath_from_rectangle(path_clip, &path_box);
if (code >= 0) {
- code = shading_path_add_box(box_path, &psh->params.BBox, pmat);
+ code = gs_shading_path_add_box(box_path, &psh->params.BBox, pmat);
if (code == gs_error_limitcheck) {
/* Ignore huge BBox - bug 689027. */
code = 0;
Modified: trunk/gs/src/gsshade.h
===================================================================
--- trunk/gs/src/gsshade.h 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gsshade.h 2007-06-05 21:10:17 UTC (rev 8020)
@@ -253,6 +253,10 @@
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
#endif
+#ifndef gs_matrix_fixed_DEFINED
+#define gs_matrix_fixed_DEFINED
+typedef struct gs_matrix_fixed_s gs_matrix_fixed;
+#endif
/* Fill a path with a shading. */
/* Depricated. To be removed soon. */
int gs_shading_fill_path_adjusted(const gs_shading_t *psh, /*const*/ gx_path *ppath,
@@ -263,4 +267,8 @@
int gs_shading_do_fill_rectangle(const gs_shading_t *psh,
const gs_fixed_rect *prect, gx_device *dev,
gs_imager_state *pis, bool fill_background);
+
+int gs_shading_path_add_box(gx_path *ppath, const gs_rect *pbox,
+ const gs_matrix_fixed *pmat);
+
#endif /* gsshade_INCLUDED */
Modified: trunk/gs/src/gxcpath.c
===================================================================
--- trunk/gs/src/gxcpath.c 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gxcpath.c 2007-06-05 21:10:17 UTC (rev 8020)
@@ -722,6 +722,8 @@
SCALE_V(ymax, log2_scale_y);
#undef SCALE_V
}
+ list->xmin = arith_rshift(list->xmin, -log2_scale_x);
+ list->xmax = arith_rshift(list->xmax, -log2_scale_x);
}
pcpath->id = gs_next_ids(pcpath->path.memory, 1); /* path changed => change id */
return 0;
@@ -1024,6 +1026,40 @@
return false;
}
+int
+gx_cpath_copy(const gx_clip_path * from, gx_clip_path * pcpath)
+{ /* *pcpath must be initialized. */
+ gx_clip_rect *r, *s;
+ gx_clip_list *l = &pcpath->rect_list->list;
+
+ pcpath->path_valid = false;
+ /* NOTE: pcpath->path still contains the old path. */
+ if (pcpath->path_list)
+ rc_decrement(pcpath->path_list, "gx_cpath_copy");
+ pcpath->path_list = NULL;
+ pcpath->rule = from->rule;
+ pcpath->outer_box = from->outer_box;
+ pcpath->inner_box = from->inner_box;
+ l->single = from->rect_list->list.single;
+ for (r = from->rect_list->list.head; r != NULL; r = r->next) {
+ s = gs_alloc_struct(from->rect_list->rc.memory, gx_clip_rect, &st_clip_rect, "gx_cpath_copy");
+ if (s == NULL)
+ return_error(gs_error_VMerror);
+ *s = *r;
+ s->next = NULL;
+ if (l->tail) {
+ s->prev = l->tail;
+ l->tail->next = s;
+ } else {
+ l->head = s;
+ s->prev = NULL;
+ }
+ l->tail = s;
+ }
+ l->count = from->rect_list->list.count;
+ return 0;
+}
+
/* ------ Debugging printout ------ */
#ifdef DEBUG
Modified: trunk/gs/src/gxfill.c
===================================================================
--- trunk/gs/src/gxfill.c 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gxfill.c 2007-06-05 21:10:17 UTC (rev 8020)
@@ -557,6 +557,20 @@
return code;
}
+private int
+pass_shading_area_through_clip_path_device(gx_device * pdev, const gs_imager_state * pis,
+ gx_path * ppath, const gx_fill_params * params,
+ const gx_device_color * pdevc, const gx_clip_path * pcpath)
+{
+ if (pdevc == NULL) {
+ gx_device_clip *cdev = (gx_device_clip *)pdev;
+
+ return dev_proc(cdev->target, fill_path)(cdev->target, pis, ppath, params, pdevc, pcpath);
+ }
+ /* We know that tha clip path device implements fill_path with default proc. */
+ return gx_default_fill_path(pdev, pis, ppath, params, pdevc, pcpath);
+}
+
/*
* Fill a path. This is the default implementation of the driver
* fill_path procedure.
@@ -591,14 +605,14 @@
gs_imager_state *pis_noconst = (gs_imager_state *)pis; /* Break const. */
if (ppath != NULL) {
- gx_cpath_init_local_shared(&cpath_intersection, pcpath, pdev->memory);
+ code = gx_cpath_init_local_shared(&cpath_intersection, pcpath, pdev->memory);
+ if (code < 0)
+ return code;
code = gx_cpath_intersect_with_params(&cpath_intersection, ppath, params->rule,
pis_noconst, params);
pcpath1 = &cpath_intersection;
} else
pcpath1 = pcpath;
-
-
pcpath2 = pcpath1;
if (code >= 0)
code = gx_dc_pattern2_clip_with_bbox(pdevc, pdev, &cpath_with_shading_bbox, &pcpath1);
@@ -616,6 +630,9 @@
cdev.HWResolution[1] = pdev->HWResolution[1];
cdev.target = pdev;
dev = (gx_device *)&cdev;
+ if ((*dev_proc(pdev, pattern_manage))(pdev,
+ gs_no_id, NULL, pattern_manage__shading_area) > 0)
+ set_dev_proc(&cdev, fill_path, pass_shading_area_through_clip_path_device);
(*dev_proc(dev, open_device))(dev);
cb.p.x = fixed2int_pixround(clip_box.p.x);
cb.p.y = fixed2int_pixround(clip_box.p.y);
Modified: trunk/gs/src/gxpath.h
===================================================================
--- trunk/gs/src/gxpath.h 2007-06-05 15:53:48 UTC (rev 8019)
+++ trunk/gs/src/gxpath.h 2007-06-05 21:10:17 UTC (rev 8020)
@@ -343,6 +343,7 @@
fixed, fixed);
const gs_fixed_rect *cpath_is_rectangle(const gx_clip_path * pcpath);
bool gx_cpath_rect_visible(gx_clip_path * pcpath, gs_int_rect *prect);
+int gx_cpath_copy(const gx_clip_path * from, gx_clip_path * pcpath);
/* Enumerate a clipping path. This interface does not copy the path. */
/* However, it does write into the path's "visited" flags. */
More information about the gs-cvs
mailing list