[gs-cvs] rev 7190 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Mon Nov 13 06:32:16 PST 2006
Author: leonardo
Date: 2006-11-13 06:32:07 -0800 (Mon, 13 Nov 2006)
New Revision: 7190
Modified:
trunk/gs/src/gxshade1.c
trunk/gs/src/gxshade4.c
trunk/gs/src/gxshade4.h
trunk/gs/src/gxshade6.c
Log:
Fix (shadings) : Remove colors from C stack.
DETAILS :
This is the 4th step of fixing the bug 688955
"64K stack overflows with shadings".
This change is algorithmically equivalent.
Providing a color stack pointer field in the shading fill state structure.
When some colors are reserved, we advance the color stack pointer.
A new function release_colors work for releasing them.
This patch inserts some asserts, which to be removed soon.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gxshade1.c
===================================================================
--- trunk/gs/src/gxshade1.c 2006-11-13 11:18:36 UTC (rev 7189)
+++ trunk/gs/src/gxshade1.c 2006-11-13 14:32:07 UTC (rev 7190)
@@ -469,17 +469,17 @@
p1.c = c;
p2.c = c;
code = gs_point_transform2fixed(&pfs->pis->ctm, x0, y0, &p0.p);
- if (code < 0)
- return code;
- code = gs_point_transform2fixed(&pfs->pis->ctm, x1, y1, &p1.p);
- if (code < 0)
- return code;
- code = gs_point_transform2fixed(&pfs->pis->ctm, x2, y2, &p2.p);
- if (code < 0)
- return code;
- c->t[0] = c->t[1] = t;
- patch_resolve_color(c, pfs);
- return mesh_triangle(pfs, &p0, &p1, &p2, color_stack_ptr1);
+ if (code >= 0)
+ code = gs_point_transform2fixed(&pfs->pis->ctm, x1, y1, &p1.p);
+ if (code >= 0)
+ code = gs_point_transform2fixed(&pfs->pis->ctm, x2, y2, &p2.p);
+ if (code >= 0) {
+ c->t[0] = c->t[1] = t;
+ patch_resolve_color(c, pfs);
+ code = mesh_triangle(pfs, &p0, &p1, &p2, color_stack_ptr1);
+ }
+ release_colors(pfs, pfs->color_stack, 1);
+ return code;
}
private int
Modified: trunk/gs/src/gxshade4.c
===================================================================
--- trunk/gs/src/gxshade4.c 2006-11-13 11:18:36 UTC (rev 7189)
+++ trunk/gs/src/gxshade4.c 2006-11-13 14:32:07 UTC (rev 7190)
@@ -147,6 +147,7 @@
}
if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
vd_release_dc;
+ release_colors(&pfs, pfs.color_stack, 3);
term_patch_fill_state(&pfs);
if (!cs.is_eod(&cs))
return_error(gs_error_rangecheck);
@@ -242,6 +243,7 @@
gs_free_object(pis->memory, vertex, "gs_shading_LfGt_render");
gs_free_object(pis->memory, color_buffer, "gs_shading_LfGt_render");
gs_free_object(pis->memory, color_buffer_ptrs, "gs_shading_LfGt_render");
+ release_colors(&pfs, pfs.color_stack, 1);
term_patch_fill_state(&pfs);
return code;
}
Modified: trunk/gs/src/gxshade4.h
===================================================================
--- trunk/gs/src/gxshade4.h 2006-11-13 11:18:36 UTC (rev 7189)
+++ trunk/gs/src/gxshade4.h 2006-11-13 14:32:07 UTC (rev 7190)
@@ -135,6 +135,7 @@
bool inside;
int color_stack_size;
int color_stack_step;
+ byte *color_stack_ptr;
byte *color_stack; /* A storage for shortened patch_color_t structures. */
byte *color_stack_limit;
gs_memory_t *memory; /* Where color_buffer is allocated. */
@@ -182,5 +183,6 @@
const gx_device_color *pdevc, gs_logical_operation_t log_op);
byte *reserve_colors(patch_fill_state_t *pfs, byte *ptr, patch_color_t *c0[], int n);
+void release_colors(patch_fill_state_t *pfs, byte *ptr, int n);
#endif /* gxshade4_INCLUDED */
Modified: trunk/gs/src/gxshade6.c
===================================================================
--- trunk/gs/src/gxshade6.c 2006-11-13 11:18:36 UTC (rev 7189)
+++ trunk/gs/src/gxshade6.c 2006-11-13 14:32:07 UTC (rev 7190)
@@ -33,6 +33,7 @@
#include "stdint_.h"
#include "math_.h"
#include "vdtrace.h"
+#include <assert.h>
#define VD_TRACE_TENSOR_PATCH 1
@@ -64,6 +65,7 @@
if (pfs->color_stack == NULL)
return_error(gs_error_VMerror);
pfs->color_stack_limit = pfs->color_stack + pfs->color_stack_size;
+ pfs->color_stack_ptr = pfs->color_stack;
pfs->memory = memory;
return 0;
}
@@ -73,13 +75,18 @@
{
int i;
+ if ((byte *)pfs->color_stack_ptr != ptr) {
+ c[0] = NULL; /* safety. */
+ return NULL;
+ }
if (pfs->color_stack_limit - ptr < pfs->color_stack_step * n) {
c[0] = NULL; /* safety. */
return NULL;
}
for (i = 0; i < n; i++)
c[i] = (patch_color_t *)(ptr + i * pfs->color_stack_step);
- return ptr + pfs->color_stack_step * n;
+ pfs->color_stack_ptr += pfs->color_stack_step * n;
+ return pfs->color_stack_ptr;
}
byte *
@@ -88,6 +95,17 @@
return reserve_colors_inline(pfs, ptr, c, n);
}
+private inline void
+release_colors_inline(patch_fill_state_t *pfs, byte *ptr, int n)
+{
+ pfs->color_stack_ptr -= pfs->color_stack_step * n;
+ assert((byte *)pfs->color_stack_ptr == ptr);
+}
+void
+release_colors(patch_fill_state_t *pfs, byte *ptr, int n)
+{
+ release_colors_inline(pfs, ptr, n);
+}
/* Get colors for patch vertices. */
private int
@@ -189,6 +207,7 @@
pfs->smoothness = pfs->pis->smoothness;
pfs->color_stack_size = 0;
pfs->color_stack_step = 0;
+ pfs->color_stack_ptr = NULL;
pfs->color_stack = NULL;
pfs->color_stack_limit = NULL;
pfs->memory = NULL;
@@ -207,6 +226,7 @@
# if LAZY_WEDGES
wedge_vertex_list_elem_buffer_free(pfs);
# endif
+ assert(pfs->color_stack_ptr == pfs->color_stack);
if (pfs->color_stack)
gs_free_object(pfs->memory, pfs->color_stack, "term_patch_fill_state");
}
@@ -1110,13 +1130,13 @@
byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, &c, 1);
if (color_stack_ptr1 == NULL)
- return_error(gs_error_unregistered);
+ return_error(gs_error_unregistered); /* Must not happen. */
/* Use the recursive decomposition due to isnt_color_monotonic
based on fn_is_monotonic_proc_t is_monotonic,
which applies to intervals. */
patch_interpolate_color(c, c0, c1, pfs, 0.5);
if (ytop - ybot < fixed_1 / 2) /* Prevent an infinite color decomposition. */
- return constant_color_trapezoid(pfs, le, re, ybot, ytop, swap_axes, c);
+ code = constant_color_trapezoid(pfs, le, re, ybot, ytop, swap_axes, c);
else {
bool monotonic_color_save = pfs->monotonic_color;
bool linear_color_save = pfs->linear_color;
@@ -1124,14 +1144,14 @@
if (!pfs->monotonic_color) {
code = isnt_color_monotonic(pfs, c0, c1);
if (code < 0)
- return code;
+ goto out;
if (!code)
pfs->monotonic_color = true;
}
if (pfs->monotonic_color && !pfs->linear_color) {
code = is_color_linear(pfs, c0, c1);
if (code < 0)
- return code;
+ goto out;
if (code > 0)
pfs->linear_color = true;
}
@@ -1161,12 +1181,12 @@
fa.yend = ytop;
code = patch_color_to_device_color(pfs, c0, &dc[0]);
if (code < 0)
- return code;
+ goto out;
if (dc[0].type == &gx_dc_type_data_pure) {
dc2fc(pfs, dc[0].colors.pure, fc[0]);
code = patch_color_to_device_color(pfs, c1, &dc[1]);
if (code < 0)
- return code;
+ goto out;
dc2fc(pfs, dc[1].colors.pure, fc[1]);
code = dev_proc(pdev, fill_linear_color_trapezoid)(pdev, &fa,
&le->start, &le->end, &re->start, &re->end,
@@ -1174,12 +1194,14 @@
if (code == 1) {
pfs->monotonic_color = monotonic_color_save;
pfs->linear_color = linear_color_save;
- return 0; /* The area is filled. */
+ code = 0; /* The area is filled. */
+ goto out;
}
if (code < 0)
- return code;
+ goto out;
else /* code == 0, the device requested to decompose the area. */
- return_error(gs_error_unregistered); /* Must not happen. */
+ code = gs_note_error(gs_error_unregistered); /* Must not happen. */
+ goto out;
}
}
if (!pfs->unlinear || !pfs->linear_color ||
@@ -1193,8 +1215,10 @@
code = constant_color_trapezoid(pfs, le, re, ybot, ytop, swap_axes, c);
pfs->monotonic_color = monotonic_color_save;
pfs->linear_color = linear_color_save;
- return code;
}
+out:
+ release_colors_inline(pfs, color_stack_ptr0, 1);
+ return code;
}
private inline int
@@ -1727,6 +1751,7 @@
shading_vertex_t p[3];
patch_color_t *c;
byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, &c, 1);
+ int code;
if (color_stack_ptr1 == NULL)
return_error(gs_error_unregistered); /* Must not happen. */
@@ -1737,7 +1762,9 @@
p[1].c = c1;
p[2].p = mid->p;
patch_interpolate_color(c, c0, c1, pfs, 0.5);
- return fill_triangle_wedge(pfs, &p[0], &p[1], &p[2], color_stack_ptr1);
+ code = fill_triangle_wedge(pfs, &p[0], &p[1], &p[2], color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 1);
+ return code;
}
private int
@@ -1772,16 +1799,16 @@
return_error(gs_error_unregistered); /* Must not happen. */
patch_interpolate_color(c, c0, c1, pfs, 0.5);
code = fill_wedge_from_list_rec(pfs, beg, e, level + 1, c0, c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_wedge_from_list_rec(pfs, e, end, level + 1, c, c1, color_stack_ptr1);
- if (code < 0)
- return code;
- if (e->divide_count != 1 && e->divide_count != 2)
- return_error(gs_error_unregistered); /* Must not happen. */
- if (e->divide_count != 1)
- return 0;
- return fill_triangle_wedge_from_list(pfs, beg, end, e, c0, c1, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_wedge_from_list_rec(pfs, e, end, level + 1, c, c1, color_stack_ptr1);
+ if (code >= 0) {
+ if (e->divide_count != 1 && e->divide_count != 2)
+ return_error(gs_error_unregistered); /* Must not happen. */
+ if (e->divide_count == 1)
+ code = fill_triangle_wedge_from_list(pfs, beg, end, e, c0, c1, color_stack_ptr1);
+ }
+ release_colors_inline(pfs, color_stack_ptr0, 1);
+ return code;
}
}
@@ -1829,14 +1856,16 @@
p[2].p = q[0][3];
patch_interpolate_color(c, c0, c1, pfs, 0.5);
code = fill_triangle_wedge(pfs, &p[0], &p[1], &p[2], color_stack_ptr1);
- if (code < 0)
- return code;
- if (ka == 2)
- return 0;
- code = wedge_by_triangles(pfs, ka / 2, q[0], c0, p[2].c, color_stack_ptr1);
- if (code < 0)
- return code;
- return wedge_by_triangles(pfs, ka / 2, q[1], p[2].c, c1, color_stack_ptr1);
+ if (code >= 0) {
+ if (ka == 2)
+ goto out;
+ code = wedge_by_triangles(pfs, ka / 2, q[0], c0, p[2].c, color_stack_ptr1);
+ }
+ if (code >= 0)
+ code = wedge_by_triangles(pfs, ka / 2, q[1], p[2].c, c1, color_stack_ptr1);
+out:
+ release_colors_inline(pfs, color_stack_ptr0, 1);
+ return code;
}
private inline bool
@@ -1925,9 +1954,10 @@
patch_interpolate_color(c, c0, c1, pfs, 0.5);
split_curve(pole, q[0], q[1]);
code = fill_wedges_aux(pfs, k / 2, ka, q[0], c0, c, wedge_type, color_stack_ptr1);
- if (code < 0)
- return code;
- return fill_wedges_aux(pfs, k / 2, ka, q[1], c, c1, wedge_type, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_wedges_aux(pfs, k / 2, ka, q[1], c, c1, wedge_type, color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 1);
+ return code;
} else {
if (INTERPATCH_PADDING && (wedge_type & interpatch_padding)) {
vd_bar(pole[0].x, pole[0].y, pole[3].x, pole[3].y, 0, RGB(255, 0, 0));
@@ -2041,7 +2071,7 @@
gs_fixed_edge le, re;
fixed dx0, dy0, dx1, dy1;
const shading_vertex_t *pp;
- int i;
+ int i, code;
byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, c, 2);
if (color_stack_ptr1 == NULL)
@@ -2061,19 +2091,22 @@
dx1 = re.end.x - re.start.x;
dy1 = re.end.y - re.start.y;
if ((int64_t)dx0 * dy1 < (int64_t)dy0 * dx1)
- return ordered_triangle(pfs, &le, &re, c[1]);
+ code = ordered_triangle(pfs, &le, &re, c[1]);
else
- return ordered_triangle(pfs, &re, &le, c[1]);
+ code = ordered_triangle(pfs, &re, &le, c[1]);
+ if (code < 0)
+ break;
}
pp = p0; p0 = p1; p1 = p2; p2 = pp;
}
- return 0;
+ release_colors_inline(pfs, color_stack_ptr0, 2);
+ return code;
}
-private int
-constant_color_quadrangle(patch_fill_state_t *pfs, const quadrangle_patch *p, bool self_intersecting,
- byte *color_stack_ptr0)
+private inline int
+constant_color_quadrangle_aux(patch_fill_state_t *pfs, const quadrangle_patch *p, bool self_intersecting,
+ patch_color_t *c[3])
{
/* Assuming the XY span is restricted with curve_samples.
It is important for intersection_of_small_bars to compute faster. */
@@ -2082,12 +2115,8 @@
int code;
bool swap_axes = false;
gx_device_color dc;
- patch_color_t *c[3];
bool orient;
- byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, c, 3);
- if (color_stack_ptr1 == NULL)
- return_error(gs_error_unregistered); /* Must not happen. */
draw_quadrangle(p, RGB(0, 255, 0));
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);
@@ -2270,6 +2299,20 @@
}
}
+constant_color_quadrangle(patch_fill_state_t *pfs, const quadrangle_patch *p, bool self_intersecting,
+ byte *color_stack_ptr0)
+{
+ patch_color_t *c[3];
+ byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, c, 3);
+ int code;
+
+ if (color_stack_ptr1 == NULL)
+ return_error(gs_error_unregistered); /* Must not happen. */
+ code = constant_color_quadrangle_aux(pfs, p, self_intersecting, c);
+ release_colors_inline(pfs, color_stack_ptr0, 3);
+ return code;
+}
+
private inline void
divide_quadrangle_by_v(patch_fill_state_t *pfs, quadrangle_patch *s0, quadrangle_patch *s1,
shading_vertex_t q[2], const quadrangle_patch *p, patch_color_t *c[2])
@@ -2407,7 +2450,7 @@
wedge_vertex_list_t L01, L12, L20, L[3];
bool inside_save = pfs->inside;
gs_fixed_rect r, r1;
- int code;
+ int code = 0;
byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, c, 3);
if(color_stack_ptr1 == NULL)
@@ -2419,16 +2462,20 @@
bbox_of_points(&r, &p0->p, &p1->p, &p2->p, NULL);
r1 = r;
rect_intersect(r, pfs->rect);
- if (r.q.x <= r.p.x || r.q.y <= r.p.y)
- return 0; /* Outside. */
+ if (r.q.x <= r.p.x || r.q.y <= r.p.y) { /* Outside. */
+ code = 0;
+ goto out;
+ }
}
code = try_device_linear_color(pfs, false, p0, p1, p2);
switch(code) {
case 0: /* The area is filled. */
- return 0;
+ goto out;
case 2: /* decompose to constant color areas */
- if (sd < fixed_1 * 4)
- return constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ if (sd < fixed_1 * 4) {
+ code = constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ goto out;
+ }
if (pfs->Function != NULL) {
double d01 = color_span(pfs, p1->c, p0->c);
double d12 = color_span(pfs, p2->c, p1->c);
@@ -2436,17 +2483,23 @@
if (d01 <= pfs->smoothness / COLOR_CONTIGUITY &&
d12 <= pfs->smoothness / COLOR_CONTIGUITY &&
- d20 <= pfs->smoothness / COLOR_CONTIGUITY)
- return constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
- } else if (cd <= pfs->smoothness / COLOR_CONTIGUITY)
- return constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ d20 <= pfs->smoothness / COLOR_CONTIGUITY) {
+ code = constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ goto out;
+ }
+ } else if (cd <= pfs->smoothness / COLOR_CONTIGUITY) {
+ code = constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ goto out;
+ }
break;
case 1: /* decompose to linear color areas */
- if (sd < fixed_1)
- return constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ if (sd < fixed_1) {
+ code = constant_color_triangle(pfs, p2, p0, p1, color_stack_ptr1);
+ goto out;
+ }
break;
default: /* Error. */
- return code;
+ goto out;
}
if (!pfs->inside) {
if (r.p.x == r1.p.x && r.p.y == r1.p.y &&
@@ -2459,66 +2512,53 @@
if (LAZY_WEDGES) {
init_wedge_vertex_list(L, count_of(L));
code = make_wedge_median(pfs, &L01, l01, true, &p0->p, &p1->p, &p01.p);
- if (code < 0)
- return code;
- code = make_wedge_median(pfs, &L12, l12, true, &p1->p, &p2->p, &p12.p);
- if (code < 0)
- return code;
- code = make_wedge_median(pfs, &L20, l20, false, &p2->p, &p0->p, &p20.p);
- if (code < 0)
- return code;
+ if (code >= 0)
+ code = make_wedge_median(pfs, &L12, l12, true, &p1->p, &p2->p, &p12.p);
+ if (code >= 0)
+ code = make_wedge_median(pfs, &L20, l20, false, &p2->p, &p0->p, &p20.p);
} else {
code = fill_triangle_wedge(pfs, p0, p1, &p01, color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_triangle_wedge(pfs, p1, p2, &p12, color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_triangle_wedge(pfs, p2, p0, &p20, color_stack_ptr1);
- if (code < 0)
- return code;
+ if (code >= 0)
+ code = fill_triangle_wedge(pfs, p1, p2, &p12, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_triangle_wedge(pfs, p2, p0, &p20, color_stack_ptr1);
}
- code = triangle_by_4(pfs, p0, &p01, &p20, &L01, &L[0], &L20, cd / 2, sd / 2, color_stack_ptr1);
- if (code < 0)
- return code;
- if (LAZY_WEDGES) {
- move_wedge(&L01, l01, true);
- move_wedge(&L20, l20, false);
+ if (code >= 0)
+ code = triangle_by_4(pfs, p0, &p01, &p20, &L01, &L[0], &L20, cd / 2, sd / 2, color_stack_ptr1);
+ if (code >= 0) {
+ if (LAZY_WEDGES) {
+ move_wedge(&L01, l01, true);
+ move_wedge(&L20, l20, false);
+ }
+ code = triangle_by_4(pfs, p1, &p12, &p01, &L12, &L[1], &L01, cd / 2, sd / 2, color_stack_ptr1);
}
- code = triangle_by_4(pfs, p1, &p12, &p01, &L12, &L[1], &L01, cd / 2, sd / 2, color_stack_ptr1);
- if (code < 0)
- return code;
- if (LAZY_WEDGES)
- move_wedge(&L12, l12, true);
- code = triangle_by_4(pfs, p2, &p20, &p12, &L20, &L[2], &L12, cd / 2, sd / 2, color_stack_ptr1);
- if (code < 0)
- return code;
- L[0].last_side = L[1].last_side = L[2].last_side = true;
- code = triangle_by_4(pfs, &p01, &p12, &p20, &L[1], &L[2], &L[0], cd / 2, sd / 2, color_stack_ptr1);
- if (code < 0)
- return code;
+ if (code >= 0) {
+ if (LAZY_WEDGES)
+ move_wedge(&L12, l12, true);
+ code = triangle_by_4(pfs, p2, &p20, &p12, &L20, &L[2], &L12, cd / 2, sd / 2, color_stack_ptr1);
+ }
+ if (code >= 0) {
+ L[0].last_side = L[1].last_side = L[2].last_side = true;
+ code = triangle_by_4(pfs, &p01, &p12, &p20, &L[1], &L[2], &L[0], cd / 2, sd / 2, color_stack_ptr1);
+ }
if (LAZY_WEDGES) {
- code = close_wedge_median(pfs, l01, p0->c, p1->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = close_wedge_median(pfs, l12, p1->c, p2->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = close_wedge_median(pfs, l20, p2->c, p0->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &L[0], p01.c, p20.c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &L[1], p12.c, p01.c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &L[2], p20.c, p12.c, color_stack_ptr1);
- if (code < 0)
- return code;
+ if (code >= 0)
+ code = close_wedge_median(pfs, l01, p0->c, p1->c, color_stack_ptr1);
+ if (code >= 0)
+ code = close_wedge_median(pfs, l12, p1->c, p2->c, color_stack_ptr1);
+ if (code >= 0)
+ code = close_wedge_median(pfs, l20, p2->c, p0->c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &L[0], p01.c, p20.c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &L[1], p12.c, p01.c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &L[2], p20.c, p12.c, color_stack_ptr1);
}
pfs->inside = inside_save;
- return 0;
+out:
+ release_colors_inline(pfs, color_stack_ptr0, 3);
+ return code;
}
private inline int
@@ -2604,24 +2644,20 @@
divide_bar(pfs, p1, p2, 2, &p12, c[1]);
divide_bar(pfs, p2, p0, 2, &p20, c[2]);
code = fill_triangle_wedge(pfs, p0, p1, &p01, color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_triangle_wedge(pfs, p1, p2, &p12, color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_triangle_wedge(pfs, p2, p0, &p20, color_stack_ptr1);
- if (code < 0)
- return code;
- code = mesh_triangle_rec(pfs, p0, &p01, &p20, color_stack_ptr1);
- if (code < 0)
- return code;
- code = mesh_triangle_rec(pfs, p1, &p12, &p01, color_stack_ptr1);
- if (code < 0)
- return code;
- code = mesh_triangle_rec(pfs, p2, &p20, &p12, color_stack_ptr1);
- if (code < 0)
- return code;
- return mesh_triangle_rec(pfs, &p01, &p12, &p20, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_triangle_wedge(pfs, p1, p2, &p12, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_triangle_wedge(pfs, p2, p0, &p20, color_stack_ptr1);
+ if (code >= 0)
+ code = mesh_triangle_rec(pfs, p0, &p01, &p20, color_stack_ptr1);
+ if (code >= 0)
+ code = mesh_triangle_rec(pfs, p1, &p12, &p01, color_stack_ptr1);
+ if (code >= 0)
+ code = mesh_triangle_rec(pfs, p2, &p20, &p12, color_stack_ptr1);
+ if (code >= 0)
+ code = mesh_triangle_rec(pfs, &p01, &p12, &p20, color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 3);
+ return code;
}
}
@@ -2680,34 +2716,29 @@
divide_bar(pfs, p->p[1][0], p->p[1][1], 2, &p1011, c[1]);
divide_bar(pfs, &p0001, &p1011, 2, &q, c[2]);
code = fill_triangle(pfs, p->p[0][0], p->p[0][1], &q, p->l0001, &l[0], &l[3], color_stack_ptr1);
- if (code < 0)
- return code;
- l[0].last_side = true;
- l[3].last_side = true;
- code = fill_triangle(pfs, p->p[0][1], p->p[1][1], &q, p->l0111, &l[1], &l[0], color_stack_ptr1);
- if (code < 0)
- return code;
- l[1].last_side = true;
- code = fill_triangle(pfs, p->p[1][1], p->p[1][0], &q, p->l1110, &l[2], &l[1], color_stack_ptr1);
- if (code < 0)
- return code;
- l[2].last_side = true;
- code = fill_triangle(pfs, p->p[1][0], p->p[0][0], &q, p->l1000, &l[3], &l[2], color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &l[0], p->p[0][1]->c, q.c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &l[1], p->p[1][1]->c, q.c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &l[2], p->p[1][0]->c, q.c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &l[3], q.c, p->p[0][0]->c, color_stack_ptr1);
- if (code < 0)
- return code;
- return 0;
+ if (code >= 0) {
+ l[0].last_side = true;
+ l[3].last_side = true;
+ code = fill_triangle(pfs, p->p[0][1], p->p[1][1], &q, p->l0111, &l[1], &l[0], color_stack_ptr1);
+ }
+ if (code >= 0) {
+ l[1].last_side = true;
+ code = fill_triangle(pfs, p->p[1][1], p->p[1][0], &q, p->l1110, &l[2], &l[1], color_stack_ptr1);
+ }
+ if (code >= 0) {
+ l[2].last_side = true;
+ code = fill_triangle(pfs, p->p[1][0], p->p[0][0], &q, p->l1000, &l[3], &l[2], color_stack_ptr1);
+ }
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &l[0], p->p[0][1]->c, q.c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &l[1], p->p[1][1]->c, q.c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &l[2], p->p[1][0]->c, q.c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &l[3], q.c, p->p[0][0]->c, color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 3);
+ return code;
}
private inline int
@@ -3033,43 +3064,38 @@
divide_quadrangle_by_v(pfs, &s0, &s1, q, p, c);
if (LAZY_WEDGES) {
code = make_wedge_median(pfs, &l1, p->l0111, true, &p->p[0][1]->p, &p->p[1][1]->p, &s0.p[1][1]->p);
- if (code < 0)
- return code;
- code = make_wedge_median(pfs, &l2, p->l1000, false, &p->p[1][0]->p, &p->p[0][0]->p, &s0.p[1][0]->p);
- if (code < 0)
- return code;
- s0.l1110 = s1.l0001 = &l0;
- s0.l0111 = s1.l0111 = &l1;
- s0.l1000 = s1.l1000 = &l2;
- s0.l0001 = p->l0001;
- s1.l1110 = p->l1110;
+ if (code >= 0)
+ code = make_wedge_median(pfs, &l2, p->l1000, false, &p->p[1][0]->p, &p->p[0][0]->p, &s0.p[1][0]->p);
+ if (code >= 0) {
+ s0.l1110 = s1.l0001 = &l0;
+ s0.l0111 = s1.l0111 = &l1;
+ s0.l1000 = s1.l1000 = &l2;
+ s0.l0001 = p->l0001;
+ s1.l1110 = p->l1110;
+ }
} else {
code = fill_triangle_wedge(pfs, s0.p[0][0], s1.p[1][0], s0.p[1][0], color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_triangle_wedge(pfs, s0.p[0][1], s1.p[1][1], s0.p[1][1], color_stack_ptr1);
- if (code < 0)
- return code;
+ if (code >= 0)
+ code = fill_triangle_wedge(pfs, s0.p[0][1], s1.p[1][1], s0.p[1][1], color_stack_ptr1);
}
- code = fill_quadrangle(pfs, &s0, big, color_stack_ptr1);
- if (code < 0)
- return code;
- if (LAZY_WEDGES) {
- l0.last_side = true;
- move_wedge(&l1, p->l0111, true);
- move_wedge(&l2, p->l1000, false);
+ if (code >= 0)
+ code = fill_quadrangle(pfs, &s0, big, color_stack_ptr1);
+ if (code >= 0) {
+ if (LAZY_WEDGES) {
+ l0.last_side = true;
+ move_wedge(&l1, p->l0111, true);
+ move_wedge(&l2, p->l1000, false);
+ }
+ code = fill_quadrangle(pfs, &s1, big1, color_stack_ptr1);
}
- code = fill_quadrangle(pfs, &s1, big1, color_stack_ptr1);
if (LAZY_WEDGES) {
- if (code < 0)
- return code;
- code = close_wedge_median(pfs, p->l0111, p->p[0][1]->c, p->p[1][1]->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = close_wedge_median(pfs, p->l1000, p->p[1][0]->c, p->p[0][0]->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &l0, s0.p[1][0]->c, s0.p[1][1]->c, color_stack_ptr1);
+ if (code >= 0)
+ code = close_wedge_median(pfs, p->l0111, p->p[0][1]->c, p->p[1][1]->c, color_stack_ptr1);
+ if (code >= 0)
+ code = close_wedge_median(pfs, p->l1000, p->p[1][0]->c, p->p[0][0]->c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &l0, s0.p[1][0]->c, s0.p[1][1]->c, color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 2);
}
} else if (divide_u) {
patch_color_t *c[2];
@@ -3082,43 +3108,38 @@
divide_quadrangle_by_u(pfs, &s0, &s1, q, p, c);
if (LAZY_WEDGES) {
code = make_wedge_median(pfs, &l1, p->l0001, true, &p->p[0][0]->p, &p->p[0][1]->p, &s0.p[0][1]->p);
- if (code < 0)
- return code;
- code = make_wedge_median(pfs, &l2, p->l1110, false, &p->p[1][1]->p, &p->p[1][0]->p, &s0.p[1][1]->p);
- if (code < 0)
- return code;
- s0.l0111 = s1.l1000 = &l0;
- s0.l0001 = s1.l0001 = &l1;
- s0.l1110 = s1.l1110 = &l2;
- s0.l1000 = p->l1000;
- s1.l0111 = p->l0111;
+ if (code >= 0)
+ code = make_wedge_median(pfs, &l2, p->l1110, false, &p->p[1][1]->p, &p->p[1][0]->p, &s0.p[1][1]->p);
+ if (code >= 0) {
+ s0.l0111 = s1.l1000 = &l0;
+ s0.l0001 = s1.l0001 = &l1;
+ s0.l1110 = s1.l1110 = &l2;
+ s0.l1000 = p->l1000;
+ s1.l0111 = p->l0111;
+ }
} else {
code = fill_triangle_wedge(pfs, s0.p[0][0], s1.p[0][1], s0.p[0][1], color_stack_ptr1);
- if (code < 0)
- return code;
- code = fill_triangle_wedge(pfs, s0.p[1][0], s1.p[1][1], s0.p[1][1], color_stack_ptr1);
- if (code < 0)
- return code;
+ if (code >= 0)
+ code = fill_triangle_wedge(pfs, s0.p[1][0], s1.p[1][1], s0.p[1][1], color_stack_ptr1);
}
- code = fill_quadrangle(pfs, &s0, big1, color_stack_ptr1);
- if (code < 0)
- return code;
- if (LAZY_WEDGES) {
- l0.last_side = true;
- move_wedge(&l1, p->l0001, true);
- move_wedge(&l2, p->l1110, false);
+ if (code >= 0)
+ code = fill_quadrangle(pfs, &s0, big1, color_stack_ptr1);
+ if (code >= 0) {
+ if (LAZY_WEDGES) {
+ l0.last_side = true;
+ move_wedge(&l1, p->l0001, true);
+ move_wedge(&l2, p->l1110, false);
+ }
+ code = fill_quadrangle(pfs, &s1, big1, color_stack_ptr1);
}
- code = fill_quadrangle(pfs, &s1, big1, color_stack_ptr1);
if (LAZY_WEDGES) {
- if (code < 0)
- return code;
- code = close_wedge_median(pfs, p->l0001, p->p[0][0]->c, p->p[0][1]->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = close_wedge_median(pfs, p->l1110, p->p[1][1]->c, p->p[1][0]->c, color_stack_ptr1);
- if (code < 0)
- return code;
- code = terminate_wedge_vertex_list(pfs, &l0, s0.p[0][1]->c, s0.p[1][1]->c, color_stack_ptr1);
+ if (code >= 0)
+ code = close_wedge_median(pfs, p->l0001, p->p[0][0]->c, p->p[0][1]->c, color_stack_ptr1);
+ if (code >= 0)
+ code = close_wedge_median(pfs, p->l1110, p->p[1][1]->c, p->p[1][0]->c, color_stack_ptr1);
+ if (code >= 0)
+ code = terminate_wedge_vertex_list(pfs, &l0, s0.p[0][1]->c, s0.p[1][1]->c, color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 2);
}
} else
code = (QUADRANGLES || !pfs->maybe_self_intersecting ?
@@ -3187,9 +3208,10 @@
draw_patch(&s1, true, RGB(0, 128, 128));
}
code = decompose_stripe(pfs, &s0, ku / 2, color_stack_ptr1);
- if (code < 0)
- return code;
- return decompose_stripe(pfs, &s1, ku / 2, color_stack_ptr1);
+ if (code >= 0)
+ code = decompose_stripe(pfs, &s1, ku / 2, color_stack_ptr1);
+ release_colors_inline(pfs, color_stack_ptr0, 2);
+ return code;
} else {
quadrangle_patch q;
shading_vertex_t qq[2][2];
@@ -3442,7 +3464,7 @@
{ tensor_patch s0, s1;
patch_color_t *c[2];
shading_vertex_t q0, q1, q2;
- int code;
+ int code = 0;
byte *color_stack_ptr1 = reserve_colors_inline(pfs, color_stack_ptr0, c, 2);
if (color_stack_ptr1 == NULL)
@@ -3456,10 +3478,8 @@
q2.p = s0.pole[3][0];
q2.c = s0.c[1][0];
code = fill_triangle_wedge(pfs, &q0, &q1, &q2, color_stack_ptr1);
- if (code < 0)
- return code;
}
- if (kv1 <= 1) {
+ if (kv1 <= 1 && code >= 0) {
q0.p = s0.pole[0][3];
q0.c = s0.c[0][1];
q1.p = s1.pole[3][3];
@@ -3467,13 +3487,11 @@
q2.p = s0.pole[3][3];
q2.c = s0.c[1][1];
code = fill_triangle_wedge(pfs, &q0, &q1, &q2, color_stack_ptr1);
- if (code < 0)
- return code;
}
- code = fill_patch(pfs, &s0, kv / 2, kv0 / 2, kv1 / 2, color_stack_ptr1);
- if (code < 0)
- return code;
- return fill_patch(pfs, &s1, kv / 2, kv0 / 2, kv1 / 2, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_patch(pfs, &s0, kv / 2, kv0 / 2, kv1 / 2, color_stack_ptr1);
+ if (code >= 0)
+ code = fill_patch(pfs, &s1, kv / 2, kv0 / 2, kv1 / 2, color_stack_ptr1);
/* fixme : To privide the precise filling order, we must
decompose left and right wedges into pieces by intersections
with stripes, and fill each piece with its stripe.
@@ -3493,6 +3511,8 @@
Delaying this improvement because it is low important.
*/
+ release_colors_inline(pfs, color_stack_ptr0, 2);
+ return code;
}
}
@@ -3681,7 +3701,7 @@
code = (*dev_proc(pfs->dev, fill_path))(pdev, NULL, &path, NULL, NULL, NULL);
gx_path_free(&path, "patch_fill");
if (code < 0)
- return code;
+ goto out;
}
/* draw_patch(&p, true, RGB(0, 0, 0)); */
kv[0] = curve_samples(pfs, &p.pole[0][0], 4, pfs->fixed_flat);
@@ -3715,5 +3735,7 @@
if (code >= 0)
code = fill_wedges(pfs, ku[3], kum, p.pole[3], 1, p.c[1][0], p.c[1][1],
interpatch_padding | inpatch_wedge, color_stack_ptr1);
+out:
+ release_colors_inline(pfs, pfs->color_stack, 4);
return code;
}
More information about the gs-cvs
mailing list