[gs-cvs] rev 7149 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Wed Nov 1 13:18:41 PST 2006
Author: leonardo
Date: 2006-11-01 13:18:41 -0800 (Wed, 01 Nov 2006)
New Revision: 7149
Modified:
trunk/gs/src/gxcpath.c
trunk/gs/src/gxfill.c
Log:
Fix : When filling a path with a shading, the filling rule was missed.
DETAILS :
1. Unwing the rev 7114 patch due to a significant slowdown
for filling a path with a shading (gxfill.c).
2. A minor change to gxfill.c : removed a redundant assignment to fo.lop .
3. The old code always used the non-zero winding rule,
because gx_cpath_to_path misses the winding rule
when called from gx_default_fill_path.
See commet in code.
This is the real fix for the problem.
4. pcpath->rule sometimes was not initialized when pcpath->path_valid is true (gxcpath.c)
We don't like that gx_default_fill_path creates a big clipping path,
which then converts into a path, which then is being intersected
with a rectangle and/or parallelogram(the shading BBox) in gs_shading_fill_path.
The biggest time expence in this chain is the sorting a lot of
rectangles when gx_cpath_intersect_path_slow applies the filling
algorithm to compute the intersection. In many cases the
the rectangle is simply the bounding box of the path,
but it still needs the clipping path planarization, because
the "planarized" property isn't stored in the path structure.
We tried to optimize against it, but didn't succeed with no raster differences.
Delaying that optimization for better times.
Due to a short time frame we need to make this patch smaller and simpler.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gxcpath.c
===================================================================
--- trunk/gs/src/gxcpath.c 2006-11-01 19:58:48 UTC (rev 7148)
+++ trunk/gs/src/gxcpath.c 2006-11-01 21:18:41 UTC (rev 7149)
@@ -655,6 +655,7 @@
if (path_valid) {
gx_path_assign_preserve(&pcpath->path, ppath_orig);
pcpath->path_valid = true;
+ pcpath->rule = rule;
} else {
code = gx_cpath_path_list_new(pcpath->path.memory, NULL, rule,
ppath_orig, next, &pcpath->path_list);
Modified: trunk/gs/src/gxfill.c
===================================================================
--- trunk/gs/src/gxfill.c 2006-11-01 19:58:48 UTC (rev 7148)
+++ trunk/gs/src/gxfill.c 2006-11-01 21:18:41 UTC (rev 7149)
@@ -417,7 +417,6 @@
fo.ymin = ibox.p.y;
fo.ymax = ibox.q.y;
fo.dev = dev;
- fo.lop = lop;
fo.pbox = &sbox;
fo.rule = params->rule;
fo.is_spotan = is_spotan_device(dev);
@@ -553,8 +552,7 @@
{
int code;
- if ((gx_dc_is_pattern2_color(pdevc) || pdevc->type == &gx_dc_type_data_ht_colored) &&
- params->rule == -1) {
+ if ((gx_dc_is_pattern2_color(pdevc) || pdevc->type == &gx_dc_type_data_ht_colored)) {
/* Optimization for shading and halftone fill :
The general filling algorithm subdivides the fill region into
trapezoid or rectangle subregions and then paints each subregion
@@ -598,8 +596,23 @@
cb.p.x, cb.p.y, cb.q.x - cb.p.x, cb.q.y - cb.p.y,
dev, pis->log_op, rs);
} else {
- /* Shading fill algorithm fills an area restricted with a path,
- so we need to convert cpath into path .*/
+ /* The shading fill algorithm fills an area restricted with a path,
+ so we need to convert cpath into path.
+
+ We can't set a clipping device here like we did for
+ gx_dc_type_data_ht_colored, because the shading itself
+ may add another clipping with its BBox,
+ which may be transformed into a parallelogram.
+ We don't want two clipping devices chained consequently.
+ */
+ if (params->rule != gx_rule_winding_number) {
+ /* HACK : Rather cpath_intersection contains a valid path,
+ it is not planarized to a simple winding path,
+ so we can't use the contained path.
+ Reset path_valid against using it.
+ */
+ cpath_intersection.path_valid = false;
+ }
code = gx_cpath_to_path(&cpath_intersection, &path_intersection);
if (code >= 0)
code = gx_dc_pattern2_fill_path(pdevc, &path_intersection, NULL, pdev);
More information about the gs-cvs
mailing list