[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