[gs-cvs] rev 8006 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Sun May 27 09:39:20 PDT 2007


Author: leonardo
Date: 2007-05-27 09:39:19 -0700 (Sun, 27 May 2007)
New Revision: 8006

Modified:
   trunk/gs/src/gxshade1.c
   trunk/gs/src/gxshade4.h
   trunk/gs/src/gxshade6.c
Log:
Fix (shadings) : Optimize filling a radial shading extension.

DETAILS : 

This partially improves performance for the test case of 
the bug 689189 "PDF fails with /unregistered in --shfill--".

The test case includes multiple radial shadings, 
which paint an extansion only.
This patch optimizes the case when the paint area is
strongly inside the radial shading extension.
In this case the shading rasterization is replaced with
painting a pure color.

1. The new function R_fill_rect_with_const_color is the main worker.
2. The old patch_color_to_device_color function is renamed into 
   patch_color_to_device_color_inline.
3. patch_color_to_device_color is made public for R_fill_rect_with_const_color.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gxshade1.c
===================================================================
--- trunk/gs/src/gxshade1.c	2007-05-26 13:13:33 UTC (rev 8005)
+++ trunk/gs/src/gxshade1.c	2007-05-27 16:39:19 UTC (rev 8006)
@@ -639,6 +639,27 @@
     return 0;
 }
 
+private int
+R_fill_rect_with_const_color(const patch_fill_state_t *pfs, const gs_fixed_rect *clip_rect, float t)
+{
+    patch_color_t pc;
+    const gs_color_space *pcs = pfs->direct_space;
+    gx_device_color dc;
+    int code;
+
+    code = gs_function_evaluate(pfs->Function, &t, pc.cc.paint.values);
+    if (code < 0)
+	return code;
+    pcs->type->restrict_color(&pc.cc, pcs);
+    code = patch_color_to_device_color(pfs, &pc, &dc);
+    if (code < 0)
+	return code;
+    return gx_fill_rectangle_device_rop(fixed2int_pixround(clip_rect->p.x), fixed2int_pixround(clip_rect->p.y), 
+					fixed2int_pixround(clip_rect->q.x) - fixed2int_pixround(clip_rect->p.x),
+					fixed2int_pixround(clip_rect->q.y) - fixed2int_pixround(clip_rect->p.y), 
+					&dc, pfs->dev, pfs->pis->log_op);
+}
+
 typedef struct radial_shading_attrs_s {
     double x0, y0;
     double x1, y1;
@@ -716,7 +737,6 @@
        t0 := (c - r0) / (cc + (r1 - r0))
        t1 := (c + r0) / (cc - (r1 - r0))
      */
-
     if (by_x) {
 	c = rsa->p[point_index].x - rsa->x0;
 	cc = rsa->x1 - rsa->x0;
@@ -1032,6 +1052,10 @@
 	    code = R_tensor_annulus(&pfs1, rect, x0, y0, r0, d0, x1, y1, r1, d1);
 	if (code >= 0)
 	    code = R_extensions(&pfs1, psh, rect, d0, d1, false, psh->params.Extend[1]);
+    } else if (span_type == 1) {
+	code = R_fill_rect_with_const_color(&pfs1, clip_rect, d0);
+    } else if (span_type == 8) {
+	code = R_fill_rect_with_const_color(&pfs1, clip_rect, d1);
     } else {
 	bool second_interval = true; 
 

Modified: trunk/gs/src/gxshade4.h
===================================================================
--- trunk/gs/src/gxshade4.h	2007-05-26 13:13:33 UTC (rev 8005)
+++ trunk/gs/src/gxshade4.h	2007-05-27 16:39:19 UTC (rev 8006)
@@ -188,6 +188,9 @@
 int gx_shade_background(gx_device *pdev, const gs_fixed_rect *rect, 
 	const gx_device_color *pdevc, gs_logical_operation_t log_op);
 
+int patch_color_to_device_color(const patch_fill_state_t *pfs, 
+	const patch_color_t *c, gx_device_color *pdevc);
+
 byte *reserve_colors(patch_fill_state_t *pfs, patch_color_t *c0[], int n);
 void release_colors(patch_fill_state_t *pfs, byte *ptr, int n);
 

Modified: trunk/gs/src/gxshade6.c
===================================================================
--- trunk/gs/src/gxshade6.c	2007-05-26 13:13:33 UTC (rev 8005)
+++ trunk/gs/src/gxshade6.c	2007-05-27 16:39:19 UTC (rev 8006)
@@ -911,7 +911,7 @@
 #define DEBUG_COLOR_INDEX_CACHE 0
 
 private inline int
-patch_color_to_device_color(const patch_fill_state_t *pfs, const patch_color_t *c, gx_device_color *pdevc, frac31 *frac_values)
+patch_color_to_device_color_inline(const patch_fill_state_t *pfs, const patch_color_t *c, gx_device_color *pdevc, frac31 *frac_values)
 {
     /* Must return 2 if the color is not pure. 
        See try_device_linear_color.
@@ -954,6 +954,12 @@
     return 0;
 }
 
+int
+patch_color_to_device_color(const patch_fill_state_t *pfs, const patch_color_t *c, gx_device_color *pdevc)
+{
+    return patch_color_to_device_color_inline(pfs, c, pdevc, NULL);
+}
+
 private inline double
 color_span(const patch_fill_state_t *pfs, const patch_color_t *c0, const patch_color_t *c1)
 {
@@ -1032,7 +1038,7 @@
 	/* if (dbg_nofill)
 		return 0; */
 #   endif
-    code = patch_color_to_device_color(pfs, &c1, &dc, NULL);
+    code = patch_color_to_device_color_inline(pfs, &c1, &dc, NULL);
     if (code < 0)
 	return code;
     if (!VD_TRACE_DOWN)
@@ -1178,7 +1184,7 @@
 	    fa.lop = 0;
 	    fa.ystart = ybot;
 	    fa.yend = ytop;
-	    code = patch_color_to_device_color(pfs, c0, NULL, fc[0]);
+	    code = patch_color_to_device_color_inline(pfs, c0, NULL, fc[0]);
 	    if (code < 0)
 		goto out;
 	    if (code == 2) {
@@ -1186,7 +1192,7 @@
 		code=gs_note_error(gs_error_unregistered);
 		goto out;
 	    }
-	    code = patch_color_to_device_color(pfs, c1, NULL, fc[1]);
+	    code = patch_color_to_device_color_inline(pfs, c1, NULL, fc[1]);
 	    if (code < 0)
 		goto out;
 	    code = dev_proc(pdev, fill_linear_color_trapezoid)(pdev, &fa, 
@@ -1686,17 +1692,17 @@
 	fa.ht = NULL;
 	fa.swap_axes = false;
 	fa.lop = 0;
-	code = patch_color_to_device_color(pfs, p0->c, &dc[0], fc[0]);
+	code = patch_color_to_device_color_inline(pfs, p0->c, &dc[0], fc[0]);
 	if (code != 0)
 	    return code;
 	if (dc[0].type != &gx_dc_type_data_pure)
 	    return 2;
 	if (!wedge) {
-	    code = patch_color_to_device_color(pfs, p1->c, &dc[1], fc[1]);
+	    code = patch_color_to_device_color_inline(pfs, p1->c, &dc[1], fc[1]);
 	    if (code != 0)
 		return code;
 	}
-	code = patch_color_to_device_color(pfs, p2->c, &dc[2], fc[2]);
+	code = patch_color_to_device_color_inline(pfs, p2->c, &dc[2], fc[2]);
 	if (code != 0)
 	    return code;
 	draw_triangle(&p0->p, &p1->p, &p2->p, RGB(255, 0, 0));
@@ -2067,7 +2073,7 @@
 #   endif
     if (!VD_TRACE_DOWN)
         vd_disable;
-    code = patch_color_to_device_color(pfs, c, &dc, NULL);
+    code = patch_color_to_device_color_inline(pfs, c, &dc, NULL);
     if (code < 0)
 	return code;
     if (le->end.y < re->end.y) {
@@ -2153,7 +2159,7 @@
     patch_interpolate_color(c[1], p->p[0][0]->c, p->p[0][1]->c, pfs, 0.5);
     patch_interpolate_color(c[2], p->p[1][0]->c, p->p[1][1]->c, pfs, 0.5);
     patch_interpolate_color(c[0], c[1], c[2], pfs, 0.5);
-    code = patch_color_to_device_color(pfs, c[0], &dc, NULL);
+    code = patch_color_to_device_color_inline(pfs, c[0], &dc, NULL);
     if (code < 0)
 	return code;
     {	gs_fixed_point qq[4];



More information about the gs-cvs mailing list