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

leonardo at ghostscript.com leonardo at ghostscript.com
Thu Nov 9 11:25:55 PST 2006


Author: leonardo
Date: 2006-11-09 11:25:53 -0800 (Thu, 09 Nov 2006)
New Revision: 7184

Modified:
   trunk/gs/src/gxshade1.c
   trunk/gs/src/gxshade4.c
   trunk/gs/src/gxshade4.h
   trunk/gs/src/gxshade6.c
Log:
Fix : Provide a single color stack for entire shading.

DETAILS :

This is the 2nd step of the preparation for fixing 
the bug 688955 "64K stack overflows with shadings".
This change is algorithmically equivalent.

1. Ading fields into patch_fill_state_t for representing a color stack in heap.

2. Initialize and finalize them in gxshade6.c . 
   Currently they work idle.

3. Provide a single patch_fill_state_t instance for all
   meshes/patches of a shgading (gxshade1.c). 
   It allows to handle a single color stack 
   for all meshes/patches of a shading.

3. Document the shortened color representation in gxshade4.h .

Most subclasses of shading_fill_state_common are now rudiments,
but we keep them for a while to minimize the patch.
Note A_fill_state_s is not longer a subclass of it.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gxshade1.c
===================================================================
--- trunk/gs/src/gxshade1.c	2006-11-09 02:28:13 UTC (rev 7183)
+++ trunk/gs/src/gxshade1.c	2006-11-09 19:25:53 UTC (rev 7184)
@@ -152,9 +152,7 @@
 /* ---------------- Axial shading ---------------- */
 
 typedef struct A_fill_state_s {
-    shading_fill_state_common;
     const gs_shading_A_t *psh;
-    gs_rect rect;		/* bounding rectangle in user space */
     gs_point delta;
     double length;
     double t0, t1;
@@ -165,38 +163,26 @@
 /* Note t0 and t1 vary over [0..1], not the Domain. */
 
 private int
-A_fill_region(A_fill_state_t * pfs, const gs_fixed_rect *rect_clip)
+A_fill_region(A_fill_state_t * pfs, patch_fill_state_t *pfs1)
 {
     const gs_shading_A_t * const psh = pfs->psh;
-    gs_function_t * const pfn = psh->params.Function;
     double x0 = psh->params.Coords[0] + pfs->delta.x * pfs->v0;
     double y0 = psh->params.Coords[1] + pfs->delta.y * pfs->v0;
     double x1 = psh->params.Coords[0] + pfs->delta.x * pfs->v1;
     double y1 = psh->params.Coords[1] + pfs->delta.y * pfs->v1;
     double h0 = pfs->u0, h1 = pfs->u1;
     patch_curve_t curve[4];
-    patch_fill_state_t pfs1;
-    int code;
 
-    memcpy(&pfs1, (shading_fill_state_t *)pfs, sizeof(shading_fill_state_t));
-    pfs1.Function = pfn;
-    code = init_patch_fill_state(&pfs1);
-    if (code < 0)
-	return code;
-    pfs1.rect = *rect_clip;
-    pfs1.maybe_self_intersecting = false;
-    gs_point_transform2fixed(&pfs->pis->ctm, x0 + pfs->delta.y * h0, y0 - pfs->delta.x * h0, &curve[0].vertex.p);
-    gs_point_transform2fixed(&pfs->pis->ctm, x1 + pfs->delta.y * h0, y1 - pfs->delta.x * h0, &curve[1].vertex.p);
-    gs_point_transform2fixed(&pfs->pis->ctm, x1 + pfs->delta.y * h1, y1 - pfs->delta.x * h1, &curve[2].vertex.p);
-    gs_point_transform2fixed(&pfs->pis->ctm, x0 + pfs->delta.y * h1, y0 - pfs->delta.x * h1, &curve[3].vertex.p);
+    gs_point_transform2fixed(&pfs1->pis->ctm, x0 + pfs->delta.y * h0, y0 - pfs->delta.x * h0, &curve[0].vertex.p);
+    gs_point_transform2fixed(&pfs1->pis->ctm, x1 + pfs->delta.y * h0, y1 - pfs->delta.x * h0, &curve[1].vertex.p);
+    gs_point_transform2fixed(&pfs1->pis->ctm, x1 + pfs->delta.y * h1, y1 - pfs->delta.x * h1, &curve[2].vertex.p);
+    gs_point_transform2fixed(&pfs1->pis->ctm, x0 + pfs->delta.y * h1, y0 - pfs->delta.x * h1, &curve[3].vertex.p);
     curve[0].vertex.cc[0] = curve[0].vertex.cc[1] = pfs->t0; /* The element cc[1] is set to a dummy value against */
     curve[1].vertex.cc[0] = curve[1].vertex.cc[1] = pfs->t1; /* interrupts while an idle priocessing in gxshade.6.c .  */
     curve[2].vertex.cc[0] = curve[2].vertex.cc[1] = pfs->t1;
     curve[3].vertex.cc[0] = curve[3].vertex.cc[1] = pfs->t0;
     make_other_poles(curve);
-    code = patch_fill(&pfs1, curve, NULL, NULL);
-    term_patch_fill_state(&pfs1);
-    return code;
+    return patch_fill(pfs1, curve, NULL, NULL);
 }
 
 private inline int
@@ -205,18 +191,25 @@
 			    gx_device * dev, gs_imager_state * pis)
 {
     const gs_shading_A_t *const psh = (const gs_shading_A_t *)psh0;
+    gs_function_t * const pfn = psh->params.Function;
     gs_matrix cmat;
     gs_rect t_rect;
     A_fill_state_t state;
+    patch_fill_state_t pfs1;
     float d0 = psh->params.Domain[0], d1 = psh->params.Domain[1];
     float dd = d1 - d0;
     double t0, t1;
     gs_point dist;
-    int code = 0;
+    int code;
 
-    shade_init_fill_state((shading_fill_state_t *)&state, psh0, dev, pis);
     state.psh = psh;
-    state.rect = *rect;
+    shade_init_fill_state((shading_fill_state_t *)&pfs1, psh0, dev, pis);
+    pfs1.Function = pfn;
+    pfs1.rect = *clip_rect;
+    code = init_patch_fill_state(&pfs1);
+    if (code < 0)
+	return code;
+    pfs1.maybe_self_intersecting = false;
     /*
      * Compute the parameter range.  We construct a matrix in which
      * (0,0) corresponds to t = 0 and (0,1) corresponds to t = 1,
@@ -242,7 +235,7 @@
     gs_distance_transform(state.delta.x, state.delta.y, &ctm_only(pis),
 			  &dist);
     state.length = hypot(dist.x, dist.y);	/* device space line length */
-    code = A_fill_region(&state, clip_rect);
+    code = A_fill_region(&state, &pfs1);
     if (psh->params.Extend[0] && t0 > t_rect.p.y) {
 	if (code < 0)
 	    return code;
@@ -250,7 +243,7 @@
 	state.v0 = t_rect.p.y;
 	state.v1 = t0;
 	state.t0 = state.t1 = t0 * dd + d0;
-	code = A_fill_region(&state, clip_rect);
+	code = A_fill_region(&state, &pfs1);
     }
     if (psh->params.Extend[1] && t1 < t_rect.q.y) {
 	if (code < 0)
@@ -259,8 +252,9 @@
 	state.v0 = t1;
 	state.v1 = t_rect.q.y;
 	state.t0 = state.t1 = t1 * dd + d0;
-	code = A_fill_region(&state, clip_rect);
+	code = A_fill_region(&state, &pfs1);
     }
+    term_patch_fill_state(&pfs1);
     return code;
 }
 
@@ -487,19 +481,6 @@
     return mesh_triangle(pfs, &p0, &p1, &p2);
 }
 
-private bool 
-R_is_covered(double ax, double ay, 
-	const gs_point *p0, const gs_point *p1, const gs_point *p)
-{
-    double dx0 = p0->x - ax, dy0 = p0->y - ay;
-    double dx1 = p1->x - ax, dy1 = p1->y - ay;
-    double dx = p->x - ax, dy = p->y - ay;
-    double vp0 = dx0 * dy - dy0 * dx;
-    double vp1 = dx * dy1 - dy * dx1;
-
-    return vp0 >= 0 && vp1 >= 0;
-}
-
 private int
 R_obtuse_cone(patch_fill_state_t *pfs, const gs_rect *rect,
 	double x0, double y0, double r0, 
@@ -712,19 +693,18 @@
     pfs1.rect = *clip_rect;
     pfs1.maybe_self_intersecting = false;
     code = R_extensions(&pfs1, psh, rect, d0, d1, psh->params.Extend[0], false);
-    if (code < 0)
-	return code;
-    {
+    if (code >= 0) {
 	float x0 = psh->params.Coords[0], y0 = psh->params.Coords[1];
 	floatp r0 = psh->params.Coords[2];
 	float x1 = psh->params.Coords[3], y1 = psh->params.Coords[4];
 	floatp r1 = psh->params.Coords[5];
 	
 	code = R_tensor_annulus(&pfs1, rect, x0, y0, r0, d0, x1, y1, r1, d1);
-	if (code < 0)
-	    return code;
     }
-    return R_extensions(&pfs1, psh, rect, d0, d1, false, psh->params.Extend[1]);
+    if (code >= 0)
+	code = R_extensions(&pfs1, psh, rect, d0, d1, false, psh->params.Extend[1]);
+    term_patch_fill_state(&pfs1);
+    return code;
 }
 
 int

Modified: trunk/gs/src/gxshade4.c
===================================================================
--- trunk/gs/src/gxshade4.c	2006-11-09 02:28:13 UTC (rev 7183)
+++ trunk/gs/src/gxshade4.c	2006-11-09 19:25:53 UTC (rev 7184)
@@ -63,28 +63,20 @@
 }
 
 inline private int
-Gt_fill_triangle(mesh_fill_state_t * pfs, const shading_vertex_t * va,
+Gt_fill_triangle(patch_fill_state_t * pfs, const shading_vertex_t * va,
 		 const shading_vertex_t * vb, const shading_vertex_t * vc)
 {
-    patch_fill_state_t pfs1;
     int code = 0;
 
-    memcpy(&pfs1, (shading_fill_state_t *)pfs, sizeof(shading_fill_state_t));
-    pfs1.Function = pfs->pshm->params.Function;
-    pfs1.rect = pfs->rect;
-    code = init_patch_fill_state(&pfs1);
-    if (code < 0)
-	return code;
     if (INTERPATCH_PADDING) {
-	code = mesh_padding(&pfs1, &va->p, &vb->p, &va->c, &vb->c);
+	code = mesh_padding(pfs, &va->p, &vb->p, &va->c, &vb->c);
 	if (code >= 0)
-	    code = mesh_padding(&pfs1, &vb->p, &vc->p, &vb->c, &vc->c);
+	    code = mesh_padding(pfs, &vb->p, &vc->p, &vb->c, &vc->c);
 	if (code >= 0)
-	    code = mesh_padding(&pfs1, &vc->p, &va->p, &vc->c, &va->c);
+	    code = mesh_padding(pfs, &vc->p, &va->p, &vc->c, &va->c);
     }
     if (code >= 0)
-	code = mesh_triangle(&pfs1, va, vb, vc);
-    term_patch_fill_state(&pfs1);
+	code = mesh_triangle(pfs, va, vb, vc);
     return code;
 }
 
@@ -94,7 +86,8 @@
 			       gx_device * dev, gs_imager_state * pis)
 {
     const gs_shading_FfGt_t * const psh = (const gs_shading_FfGt_t *)psh0;
-    mesh_fill_state_t state;
+    patch_fill_state_t pfs;
+    const gs_shading_mesh_t *pshm = (const gs_shading_mesh_t *)psh;
     shade_coord_stream_t cs;
     int num_bits = psh->params.BitsPerFlag;
     int flag;
@@ -107,8 +100,11 @@
 	vd_set_scale(0.01);
 	vd_set_origin(0, 0);
     }
-    code = mesh_init_fill_state(&state, (const gs_shading_mesh_t *)psh, rect_clip,
-			 dev, pis);
+    shade_init_fill_state((shading_fill_state_t *)&pfs,
+			  (const gs_shading_t *)psh, dev, pis);
+    pfs.Function = pshm->params.Function;
+    pfs.rect = *rect_clip;
+    code = init_patch_fill_state(&pfs);
     if (code < 0)
 	return code;
     shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params,
@@ -118,28 +114,29 @@
 	    default:
 		return_error(gs_error_rangecheck);
 	    case 0:
-		if ((code = Gt_next_vertex(state.pshm, &cs, &va)) < 0 ||
+		if ((code = Gt_next_vertex(pshm, &cs, &va)) < 0 ||
 		    (code = shade_next_flag(&cs, num_bits)) < 0 ||
-		    (code = Gt_next_vertex(state.pshm, &cs, &vb)) < 0 ||
+		    (code = Gt_next_vertex(pshm, &cs, &vb)) < 0 ||
 		    (code = shade_next_flag(&cs, num_bits)) < 0
 		    )
-		    return code;
+		    break;
 		goto v2;
 	    case 1:
 		va = vb;
 	    case 2:
 		vb = vc;
-v2:		if ((code = Gt_next_vertex(state.pshm, &cs, &vc)) < 0)
-		    return code;
-		if ((code = Gt_fill_triangle(&state, &va, &vb, &vc)) < 0)
-		    return code;
+v2:		if ((code = Gt_next_vertex(pshm, &cs, &vc)) < 0)
+		    break;
+		if ((code = Gt_fill_triangle(&pfs, &va, &vb, &vc)) < 0)
+		    break;
 	}
     }
     if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
 	vd_release_dc;
+    term_patch_fill_state(&pfs);
     if (!cs.is_eod(&cs))
 	return_error(gs_error_rangecheck);
-    return 0;
+    return code;
 }
 
 int
@@ -148,7 +145,8 @@
 			       gx_device * dev, gs_imager_state * pis)
 {
     const gs_shading_LfGt_t * const psh = (const gs_shading_LfGt_t *)psh0;
-    mesh_fill_state_t state;
+    patch_fill_state_t pfs;
+    const gs_shading_mesh_t *pshm = (const gs_shading_mesh_t *)psh;
     shade_coord_stream_t cs;
     shading_vertex_t *vertex;
     shading_vertex_t next;
@@ -161,8 +159,11 @@
 	vd_set_scale(0.01);
 	vd_set_origin(0, 0);
     }
-    code = mesh_init_fill_state(&state, (const gs_shading_mesh_t *)psh, rect_clip,
-			 dev, pis);
+    shade_init_fill_state((shading_fill_state_t *)&pfs,
+			  (const gs_shading_t *)psh, dev, pis);
+    pfs.Function = pshm->params.Function;
+    pfs.rect = *rect_clip;
+    code = init_patch_fill_state(&pfs);
     if (code < 0)
 	return code;
     shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params,
@@ -173,21 +174,21 @@
     if (vertex == 0)
 	return_error(gs_error_VMerror);
     for (i = 0; i < per_row; ++i)
-	if ((code = Gt_next_vertex(state.pshm, &cs, &vertex[i])) < 0)
+	if ((code = Gt_next_vertex(pshm, &cs, &vertex[i])) < 0)
 	    goto out;
     while (!seofp(cs.s)) {
-	code = Gt_next_vertex(state.pshm, &cs, &next);
+	code = Gt_next_vertex(pshm, &cs, &next);
 	if (code < 0)
 	    goto out;
 	for (i = 1; i < per_row; ++i) {
-	    code = Gt_fill_triangle(&state, &vertex[i - 1], &vertex[i], &next);
+	    code = Gt_fill_triangle(&pfs, &vertex[i - 1], &vertex[i], &next);
 	    if (code < 0)
 		goto out;
 	    vertex[i - 1] = next;
-	    code = Gt_next_vertex(state.pshm, &cs, &next);
+	    code = Gt_next_vertex(pshm, &cs, &next);
 	    if (code < 0)
 		goto out;
-	    code = Gt_fill_triangle(&state, &vertex[i], &vertex[i - 1], &next);
+	    code = Gt_fill_triangle(&pfs, &vertex[i], &vertex[i - 1], &next);
 	    if (code < 0)
 		goto out;
 	}
@@ -197,5 +198,6 @@
     if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
 	vd_release_dc;
     gs_free_object(pis->memory, vertex, "gs_shading_LfGt_render");
+    term_patch_fill_state(&pfs);
     return code;
 }

Modified: trunk/gs/src/gxshade4.h
===================================================================
--- trunk/gs/src/gxshade4.h	2006-11-09 02:28:13 UTC (rev 7183)
+++ trunk/gs/src/gxshade4.h	2006-11-09 19:25:53 UTC (rev 7184)
@@ -93,6 +93,18 @@
 #define LAZY_WEDGES_MAX_LEVEL 9 /* memory consumption is 
     sizeof(wedge_vertex_list_elem_t) * LAZY_WEDGES_MAX_LEVEL * (1 << LAZY_WEDGES_MAX_LEVEL) */
 
+/* Define a color to be used in curve rendering. */
+/* This may be a real client color, or a parametric function argument. */
+typedef struct patch_color_s {
+    float t[2];			/* parametric value */
+    gs_client_color cc;
+    /* NOTE : The structure gs_client_color ends with a big array, but only few elements
+       are used in most cases. Therefore sometimes we allocate a shorter area,
+       so that ending elements are not allocated and must not be accessed/modified.
+       The number of allocated elements are known from the shading color space
+       and from patch_fill_state_s::num_components. */
+} patch_color_t;
+
 /* Define the common state for rendering Coons and tensor patches. */
 typedef struct patch_fill_state_s {
     mesh_fill_state_common;
@@ -112,13 +124,12 @@
     bool linear_color;
     bool unlinear;
     bool inside;
+    int color_stack_size;
+    int color_stack_step;
+    byte *color_stack; /* A storage for shortened patch_color_t structures. */
+    byte *color_stack_limit;
+    gs_memory_t *memory; /* Where color_buffer is allocated. */
 } patch_fill_state_t;
-/* Define a color to be used in curve rendering. */
-/* This may be a real client color, or a parametric function argument. */
-typedef struct patch_color_s {
-    float t[2];			/* parametric value */
-    gs_client_color cc;
-} patch_color_t;
 
 /* Define a structure for mesh or patch vertex. */
 struct shading_vertex_s {

Modified: trunk/gs/src/gxshade6.c
===================================================================
--- trunk/gs/src/gxshade6.c	2006-11-09 02:28:13 UTC (rev 7183)
+++ trunk/gs/src/gxshade6.c	2006-11-09 19:25:53 UTC (rev 7184)
@@ -149,6 +149,11 @@
     pfs->n_color_args = 1;
     pfs->fixed_flat = float2fixed(pfs->pis->flatness);
     pfs->smoothness = pfs->pis->smoothness;
+    pfs->color_stack_size = 0;
+    pfs->color_stack_step = 0;
+    pfs->color_stack = NULL;
+    pfs->color_stack_limit = NULL;
+    pfs->memory = NULL;
 #   if LAZY_WEDGES
 	code = wedge_vertex_list_elem_buffer_alloc(pfs);
 	if (code < 0)
@@ -164,6 +169,8 @@
 #   if LAZY_WEDGES
 	wedge_vertex_list_elem_buffer_free(pfs);
 #   endif
+    if (pfs->color_stack)
+	gs_free_object(pfs->memory, pfs->color_stack, "term_patch_fill_state");
 }
 
 /* Resolve a patch color using the Function if necessary. */



More information about the gs-cvs mailing list