[gs-cvs] gs/src

Igor Melichev igor at casper.ghostscript.com
Tue Jan 7 09:54:03 PST 2003


Update of /cvs/ghostscript/gs/src
In directory casper:/tmp/cvs-serv25941/gs/src

Modified Files:
	gxfill.c 
Log Message:
Dropout prevention : (1) Replace the horizontal line processing.
(2) Returning the hack about horizontal lines for non-character fills.
This patch changes a disabled code only.

DETAILS:

With the old type 1 hinter, hinted outlines get
self-intersections at small resolution. It's a problem
of the old hinter. Perhaps it discovered a defect
in horizontal line handling.

With self-intersections, the side of spot interior
may be different for different parts of same line.
This patch completely replaces the handling of
horizontal lines. It maintains 2 lists of
horizontal lines, which correspond to y and y1
in fill_loop_by_trapezoids. Then we intersect those
lines with margins and add corresponding segments
of boundaries separately for each part delimited
with an intersection.

The
     "* This is a hack to make sure that isolated horizontal
      * lines get stroked."
was erroneously disabled for non-character fills,
causing a regression with QA_Inv.pdf .
Restoring it now, except for characters.

This patch removes the contour area computation,
which was introduced in revision 1.19 .


Index: gxfill.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxfill.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- gxfill.c	6 Jan 2003 19:57:39 -0000	1.25
+++ gxfill.c	7 Jan 2003 17:54:01 -0000	1.26
@@ -48,9 +48,6 @@
 #define ADJUST_SERIF 1 /* See comments near occurances. */
 #define CHECK_SPOT_CONTIGUITY 1 /* See comments near occurances. */
 
-#define CONTOUR_AREA_WITH_FIXED_POINT 1
-#define CONTOUR_AREA_WITH_FLOATING_POINT 0
-
 /*
  * Define which fill algorithm(s) to use.  At least one of the following
  * two #defines must be included (not commented out).
@@ -311,6 +308,7 @@
     Perhaps we could store trapeziod vertices to active_line,
     and delay rendering a trapezoid until stem changes boundary segments.
     This also would make calls to the margin staff less frequent.
+
 */
 
 typedef struct margin_s
@@ -350,6 +348,7 @@
     active_line *y_line;	/* most recently inserted line */
     active_line x_head; 	/* X-sorted list of active lines */
 #define x_list x_head.next
+    active_line *h_list0, *h_list1; /* lists of horizontal lines for y, y1 */
     margin_set margin_set0, margin_set1;
     margin *free_margin_list; 
     int local_margin_alloc_count;
@@ -799,6 +798,7 @@
     ll->close_count = 0;
     ll->y_list = 0;
     ll->y_line = 0;
+    ll->h_list0 = ll->h_list1 = 0;
     ll->margin_set0.margin_list = ll->margin_set1.margin_list = 0;
     ll->margin_set0.margin_touched = ll->margin_set1.margin_touched = 0;
     ll->free_margin_list = 0;
@@ -847,167 +847,6 @@
     free_all_margins(ll);
 }
 
-#   if PSEUDO_RASTERIZATION
-
-/* Compute contour area.
- * Returns multiple 2 of the area in square pixels.
- */
-private double
-compute_contour_area(subpath *psub, const gs_fixed_rect * pbox)
-{
-    double area;
-    segment *pseg = (segment *)psub, *pseg_prev = psub->last;
-    fixed x0 = pbox->p.x, y0 = pbox->p.y;
-
-#   if CONTOUR_AREA_WITH_FIXED_POINT
-	/* We assume that area is computed for small characters only,
-	 * i.e. the contour size < 128 pixels, and fixed_shift <= 15.
-	 */
-	struct { 
-	    int s;              /* sign */
-	    unsigned long i, f; /* integer, fraction */
-	} s, a, b, c;
-	double area1;
-	fixed aa, bb;
-	int k;
-
-	s.s = 1; s.i = s.f = 0;
-#   endif
-#   if CONTOUR_AREA_WITH_FLOATING_POINT
-    area = 0;
-#endif
-    for (;; pseg_prev = pseg, pseg = pseg->next) {
-#	if CONTOUR_AREA_WITH_FLOATING_POINT
-	    double dx = pseg->pt.x - pseg_prev->pt.x;
-	    double dy = pseg->pt.y - pseg_prev->pt.y;
-	    double vp = (pseg->pt.x - x0) * dy - (pseg->pt.y - y0) * dx;
-
-	    area += vp;
-	    /* In general, the products may be truncated here.
-	     * But it cannot happen with small characters.
-	     * Note : It may be slow on processors which have no floating point.
-	     */
-#   endif
-#   if CONTOUR_AREA_WITH_FIXED_POINT
-	/* We don't want subroutine calls here, use 2-step cycle instead. */
-	for (k = 0, aa = pseg->pt.x - x0, bb = pseg->pt.y - pseg_prev->pt.y; 
-	     k < 2; 
-	     k++,   aa = y0 - pseg->pt.y, bb = pseg->pt.x - pseg_prev->pt.x
-	    ) {
-	    fixed p, q;
-
-	    /* a = aa; */
-	    if (aa == 0 || bb == 0)
-		continue;
-	    a.s = (aa >= 0 ? 1 : -1);
-	    aa = any_abs(aa);
-	    a.i = aa >> _fixed_shift;
-	    a.f = aa & _fixed_fraction_v;
-
-	    /* b = bb; */
-	    b.s = (bb >= 0 ? 1 : -1);
-	    bb = any_abs(bb);
-	    b.i = bb >> _fixed_shift;
-	    b.f = bb & _fixed_fraction_v;
-
-	    /* c = a * b; */
-	    c.s = a.s * b.s;
-	    c.i = a.i * b.i;
-	    c.f = a.f * b.f;
-	    p = a.i * b.f;
-	    q = a.f * b.i;
-	    c.i += (p >> _fixed_shift) + (q >> _fixed_shift);
-	    c.f += ((p & _fixed_fraction_v) + (q & _fixed_fraction_v)) << _fixed_shift;
-	    c.i += c.f >> _fixed_shift * 2;  /* normalize */
-	    c.f &= ((1 << _fixed_shift * 2) - 1);
-
-	    /* s += c; */
-	    if (s.s == c.s) {
-		/* add mantiss */
-		s.i += c.i;
-		s.f += c.f;
-	    } else {
-		/* subtract mantiss */
-		if (s.i > c.i) {
-		    s.i -= c.i;
-		    if (s.f < c.f) {
-			s.i--;
-			s.f += (1 << _fixed_shift * 2);
-		    }
-		    s.f -= c.f;
-		} else if (s.i < c.i) {
-		    s.s = - s.s;
-		    s.i = c.i - s.i;
-		    if (c.f < s.f) {
-			s.i--;
-			c.f += (1 << _fixed_shift * 2);
-		    }
-		    s.f = c.f - s.f;
-		} else if (s.f >= c.f) {
-		    s.i = 0;
-		    s.f -= c.f;
-		} else {
-		    s.i = 0;
-		    s.s = - s.s;
-		    s.f = c.f - s.f;
-		}
-	    }
-	    s.i += s.f >> _fixed_shift * 2;  /* normalize */
-	    s.f &= ((1 << _fixed_shift * 2) - 1);
-	}
-#	endif
-#	if CONTOUR_AREA_WITH_FIXED_POINT && CONTOUR_AREA_WITH_FLOATING_POINT
-	    area1 = (s.i + s.f / (double)(fixed_1 * fixed_1)) * s.s;
-	    /* assert(any_abs(area / (double)(fixed_1 * fixed_1) - area1) < 10 / (double)(fixed_1 * fixed_1)); */
-	    assert(area / (double)(fixed_1 * fixed_1) == area1);
-#	endif
-	if (pseg == psub->last)
-	    break;
-    }
-#   if CONTOUR_AREA_WITH_FLOATING_POINT
-	area /= (double)(fixed_1 * fixed_1);
-#   endif
-#   if CONTOUR_AREA_WITH_FIXED_POINT
-	area1 = (s.i + s.f / (double)(fixed_1 * fixed_1)) * s.s;
-#   endif
-#   if CONTOUR_AREA_WITH_FIXED_POINT && CONTOUR_AREA_WITH_FLOATING_POINT
-	/* assert(any_abs(area - area1) < 10 / (double)(fixed_1 * fixed_1)); */
-	assert(area == area1);
-#   endif
-#   if CONTOUR_AREA_WITH_FIXED_POINT
-	area = area1;
-#   endif
-    return area;
-}
-
-/* Compute sign of the maximal contour. */
-private int
-compute_max_contour_sign(gx_path *ppath, const gs_fixed_rect * pbox)
-{
-    /* According to specification all outer contours in characters 
-     * must be positive. Perhaps a font in comparefiles/a.pdf is not such.
-     * The non-zero winding rule implies that inner contours have opposite 
-     * direction to outer ones. We compute sign of the outermost contour,
-     * and if it is in wrong direction, we reverse all horizintal lines
-     * in all contours to allow add_horiz_mrgine to determine properly, 
-     * at which side of the line the spot interior appears.
-     */
-
-    subpath *psub = ppath->first_subpath;
-    double max_area = 0;
-
-    for (; psub != NULL; psub = (subpath *)psub->last->next) {
-	double a = compute_contour_area(psub, pbox);
-
-	if (any_abs(a) > any_abs(max_area)) {
-	    max_area = a;
-	}
-    }
-    return max_area < 0 ? -1 : max_area > 0 ? 1 : 0;
-}
-
-#   endif
-
 /*
  * Construct a Y-sorted list of segments for rasterizing a path.  We assume
  * the path is non-empty.  Only include non-horizontal lines or (monotonic)
@@ -1025,7 +864,6 @@
     /* fixed xmax = pbox->q.x; *//* not currently used */
     fixed ymax = pbox->q.y;
 #   if PSEUDO_RASTERIZATION
-    int max_contour_sign;
     bool pseudo_rasterization = ll->pseudo_rasterization;
 #   endif
     int code;
@@ -1038,9 +876,6 @@
 	int first_dir, prev_dir;
 	segment *prev;
 
-#	if PSEUDO_RASTERIZATION
-	max_contour_sign = -2 /* unknown */;
-#	endif
 	if (plast->type != s_line_close) {
 	    /* Create a fake s_line_close */
 	    line_close_segment *lp = &psub->closer;
@@ -1092,18 +927,6 @@
 		    fixed2int_pixround(iy + adjust_above)
 		    ) {
 		    INCR(horiz);
-#		    if PSEUDO_RASTERIZATION
-		    if (pseudo_rasterization && max_contour_sign == -2)
-			max_contour_sign = compute_max_contour_sign(ppath, pbox);
-		    if (pseudo_rasterization && max_contour_sign < 0) {
-			/* Add reversed line, because add_horiz_margin needs a right direction. */
-			if ((code = add_y_line(pseg, prev, 
-					       DIR_HORIZONTAL, ll)) < 0
-			    )
-			    return code;
-		    } else if (!pseudo_rasterization || max_contour_sign > 0)
-			/* Skip zero area contours from characters. */
-#		    endif
 		    if ((code = add_y_line(prev, pseg,
 					   DIR_HORIZONTAL, ll)) < 0
 			)
@@ -1171,12 +994,8 @@
 	    y_start = this.y;	/* = prev.y */
 	    alp->start = prev;
 	    alp->end = this;
-#	    if !DROPOUT_PREVINTION
 	    /* Don't need to set dx or y_fast_max */
 	    alp->pseg = prev_lp;	/* may not need this either */
-#	    else
-	    alp->pseg = 0;	/* safety (the line may be reversed) */
-#	    endif
 	    break;
 	default:		/* can't happen */
 	    return_error(gs_error_unregistered);
@@ -1243,6 +1062,29 @@
     prev->next = alp;
 }
 
+/* Insert a newly active line in the h list. */
+/* h list isn't ordered because x intervals may overlap. */
+/* todo : optimize with maintaining ordered interval list;
+   Unite contacting inrevals, like we did in add_margin.
+ */
+private inline void
+insert_h_new(active_line * alp, ll_ptr ll)
+{
+    alp->next = ll->h_list0;
+    alp->prev = 0;
+    if (ll->h_list0 != 0)
+	ll->h_list0->prev = alp;
+    ll->h_list0 = alp;
+    /*
+     * h list keeps horizontal lines for a given y.
+     * There are 2 lists, corresponding to upper and lower ends 
+     * of the Y-interval, which fill_loop_by_trapezoids currently proceeds.
+     * Parts of horizontal lines, which do not contact a filled trapezoid,
+     * are parts of the spot bondairy. They to be marked in
+     * the 'sect' array.  - see process_h_lists.
+     */
+}
+
 /*
  * Handle a line segment that just ended.  Return true iff this was
  * the end of a line sequence.
@@ -1475,7 +1317,8 @@
 {   return alp->start.y + fixed_mult_quo(xp - alp->start.x,  alp->diff.y, alp->diff.x);
 }
 
-private int margin_boundary(line_list * ll, margin_set * set, active_line * alp, fixed yy0, fixed yy1, int dir)
+private int margin_boundary(line_list * ll, margin_set * set, active_line * alp, 
+			    fixed xx0, fixed xx1, fixed yy0, fixed yy1, int dir)
 {   section *sect = set->sect;
     fixed x0, x1, xmin, xmax;
     int xp0, xp;
@@ -1488,8 +1331,8 @@
 	return 0;
     /* enumerate integral x's in [yy0,yy1] : */
 
-    if (alp->start.y == alp->end.y)
-	x0 = alp->start.x, x1 = alp->end.x;
+    if (alp == 0)
+	x0 = xx0, x1 = xx1;
     else
 	x0 = AL_X_AT_Y(alp, yy0), x1 = AL_X_AT_Y(alp, yy1);
     xmin = min(x0, x1);
@@ -1503,7 +1346,7 @@
 	}
 	assert(i0 >= 0);
 	for (i = i0, xp = xp0; xp < xmax && i < ll->bbox_width; xp += fixed_1, i++) {
-	    fixed y = (alp->start.y == alp->end.y ? alp->start.y : Y_AT_X(alp, xp));
+	    fixed y = (alp == 0 ? yy0 : Y_AT_X(alp, xp));
 	    fixed dy = y - set->y;
 	    bool ud;
 	    short *b, h;
@@ -1514,7 +1357,7 @@
 	    if (dy >= fixed_1)
 		dy = fixed_1; /* safety */
 	    vd_circle(xp, y, 2, 0);
-	    ud = ((alp->start.x - alp->end.x) * dir > 0);
+	    ud = (alp == 0 ? (dir > 0) : ((alp->start.x - alp->end.x) * dir > 0));
 	    b = (ud ? &s->y0 : &s->y1);
 	    h = (short)dy;
 	    if (*b == -1 || (*b != -2 && ( ud ? *b > h : *b < h)))
@@ -1529,7 +1372,7 @@
 	}
 	for (i = i0, xp = xp0; xp < xmax; xp += fixed_1, i++) {
 	    section *s = &sect[i];
-	    fixed y = (alp->start.y == alp->end.y ? alp->start.y : Y_AT_X(alp, xp));
+	    fixed y = (alp==0 ? yy0 : Y_AT_X(alp, xp));
 	    fixed dy = y - set->y;
 	    bool ud;
 	    short *b, h;
@@ -1539,7 +1382,7 @@
 	    if (dy >= fixed_1)
 		dy = fixed_1; /* safety */
 	    vd_circle(xp, y, 2, 0);
-	    ud = ((alp->start.x - alp->end.x) * dir > 0);
+	    ud = (alp == 0 ? (dir > 0) : ((alp->start.x - alp->end.x) * dir > 0));
 	    b = (ud ? &s->y0 : &s->y1);
 	    h = (short)dy;
 	    if (*b == -1 || (*b != -2 && ( ud ? *b > h : *b < h)))
@@ -1586,10 +1429,10 @@
     }
 #   endif
 
-    code = margin_boundary(ll, set, flp, yy0, yy1, 1);
+    code = margin_boundary(ll, set, flp, 0, 0, yy0, yy1, 1);
     if (code < 0)
 	return code;
-    return margin_boundary(ll, set, alp, yy0, yy1, -1);
+    return margin_boundary(ll, set, alp, 0, 0, yy0, yy1, -1);
 }
 
 private int add_margin(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1)
@@ -1598,10 +1441,6 @@
     return continue_margin_common(ll, &ll->margin_set0, flp, alp, y0, y1);
 }
 
-private int add_horiz_margin(line_list * ll, active_line * alp)
-{   vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 1, RGB(128, 0, 255));
-    return margin_boundary(ll, &ll->margin_set0, alp, alp->start.y, alp->start.y, -1);
-}
 
 private inline const segment * PrevSeg(const segment *pseg)
 {   return pseg->type == s_start ? ((const subpath *)pseg)->last->prev : pseg->prev;
@@ -1622,10 +1461,9 @@
 
 private inline int mark_margin_interior(line_list * ll, margin_set * set, active_line * flp, active_line * alp, fixed y)
 {
-    int i, code;
     section *sect = set->sect;
     fixed x0 = AL_X_AT_Y(flp, y), x1 = AL_X_AT_Y(alp, y);
-    int i0 = fixed2int(x0), ii0, ii1;
+    int i0 = fixed2int(x0), ii0, ii1, i, code;
 
     if (int2fixed(i0) + fixed_half < x0)
 	i0++;
@@ -1663,8 +1501,82 @@
     return 0;
 }
 
+private inline int process_h_sect(line_list * ll, margin_set * set, active_line * hlp0, active_line * plp, active_line * flp, int side)
+{
+    active_line *hlp = hlp0;
+    fixed y = hlp->start.y;
+    fixed x0 = (plp != 0 ? AL_X_AT_Y(plp, y) : int2fixed(ll->bbox_left));
+    fixed x1 = (flp != 0 ? AL_X_AT_Y(flp, y) : int2fixed(ll->bbox_left + ll->bbox_width));
+    int code;
 
-static inline int compute_padding(section *s)
+    for (; hlp != 0; hlp = hlp->next) {
+	fixed xx0 = max(x0, min(hlp->start.x, hlp->end.x));
+	fixed xx1 = min(x1, max(hlp->start.x, hlp->end.x));
+
+	if (xx0 < xx1) {
+	    vd_bar(xx0, y, xx1, y, 1, RGB(255, 0, 255));
+	    code =  margin_boundary(ll, set, 0, xx0, xx1, y, y, side);
+	    if (code < 0)
+		return code;
+	}
+    }
+    return 0;	
+}
+
+private inline int process_h_side(line_list * ll, margin_set * set, active_line * hlp, active_line * plp, active_line * flp, active_line * alp, int side)
+{   if (plp != 0 || flp != 0 || (plp == 0 && flp == 0 && alp == 0)) {
+	/* We don't know here, whether the opposite (-) side is painted with
+	 * a trapezoid. mark_margin_interior may rewrite it later.
+	 */
+	int code = process_h_sect(ll, set, hlp, plp, flp, -side);
+
+	if (code < 0)
+	    return code;
+    }
+    if (flp != 0 && alp != 0) {
+	int code = process_h_sect(ll, set, hlp, flp, alp, side);
+
+	if (code < 0)
+	    return code;
+    }
+    return 0;
+}
+
+private inline int process_h_list(line_list * ll, active_line * hlp, active_line * plp, active_line * flp, active_line * alp, int side)
+{   fixed y = hlp->start.y;
+
+    if (ll->margin_set0.y <= y && y <= ll->margin_set0.y + fixed_1) {
+	int code = process_h_side(ll, &ll->margin_set0, hlp, plp, flp, alp, side);
+
+	if (code < 0)
+	    return code;
+    }
+    if (ll->margin_set1.y <= y && y <= ll->margin_set1.y + fixed_1) {
+	int code = process_h_side(ll, &ll->margin_set1, hlp, plp, flp, alp, side);
+
+	if (code < 0)
+	    return code;
+    }
+    return 0;
+}
+
+private inline int process_h_lists(line_list * ll, active_line * plp, active_line * flp, active_line * alp)
+{   if (ll->h_list0 != 0) {
+	int code = process_h_list(ll, ll->h_list0, plp, flp, alp, 1);
+
+	if (code < 0)
+	    return code;
+    }
+    if (ll->h_list1 != 0) {
+	int code = process_h_list(ll, ll->h_list1, plp, flp, alp, -1);
+
+	if (code < 0)
+	    return code;
+    }
+    return 0;
+}
+
+private inline int compute_padding(section *s)
 {
     return (s->y0 < 0 || s->y1 < 0 ? -2 : /* contacts a trapezoid - don't paint */
 	    s->y1 < fixed_half ? 0 : 
@@ -1898,14 +1810,9 @@
     y = yll->start.y;		/* first Y value */
     ll->x_list = 0;
     ll->x_head.x_current = min_fixed;	/* stop backward scan */
-    if (pseudo_rasterization) {
-	code = start_margin_set(dev, ll, y, fill_direct, cindex, pdevc, lop, fill_rect);
-	if (code < 0)
-	    return code;
-    }
     while (1) {
 	fixed y1;
-	active_line *endp, *alp, *stopx;
+	active_line *endp, *alp, *stopx, *plp = NULL;
 	fixed x;
 	int draw;
 
@@ -1915,12 +1822,12 @@
 	    active_line *ynext = yll->next;	/* insert smashes next/prev links */
 
 	    if (yll->direction == DIR_HORIZONTAL) {
-#		if !PSEUDO_RASTERIZATION
-		/*
-		 * This is a hack to make sure that isolated horizontal
-		 * lines get stroked.
-		 */
-		{   int yi = fixed2int_pixround(y - adjust_below);
+		if (!PSEUDO_RASTERIZATION || !pseudo_rasterization) {
+		    /*
+		     * This is a hack to make sure that isolated horizontal
+		     * lines get stroked.
+		     */
+		    int yi = fixed2int_pixround(y - adjust_below);
 		    int xi, wi;
 
 		    if (yll->start.x <= yll->end.x)
@@ -1937,14 +1844,8 @@
 		    code = LOOP_FILL_RECTANGLE_DIRECT(xi, yi, wi, 1);
 		    if (code < 0)
 			return code;
-		}
-#		else
-		if (pseudo_rasterization) {
-		    code = add_horiz_margin(ll, yll);
-		    if (code < 0)
-			return code;
-		}
-#		endif
+		} else if (pseudo_rasterization)
+		    insert_h_new(yll, ll);
 	    } else
 		insert_x_new(yll, ll);
 	    yll = ynext;
@@ -1958,6 +1859,8 @@
 	    /* We don't close margin set here because the next set
 	     * may fall into same window. */
 	    y = yll->start.y;
+	    ll->h_list1 = ll->h_list0;
+	    ll->h_list0 = 0;
 	    continue;
 	}
 	if (vd_enabled) {
@@ -2170,13 +2073,13 @@
 		    fixed2int_var_pixround(xlbot) &&
 		    (xi = fixed2int_var_pixround(xtop)) ==
 		    fixed2int_var_pixround(xbot)
-		    ) {		/* Rectangle. */
+		    ) 		/* Rectangle. */
 #		else
 		xli = fixed2int_var_pixround(xltop);
 		xi = fixed2int_var_pixround(xtop);
-		if (xltop == xlbot && xtop == xbot) {
+		if (xltop == xlbot && xtop == xbot)
 #		endif
-		    int yi = fixed2int_pixround(y - adjust_below);
+		{   int yi = fixed2int_pixround(y - adjust_below);
 		    int wi = fixed2int_pixround(y1 + adjust_above) - yi;
 
 		    if (PSEUDO_RASTERIZATION && xli == xi) {
@@ -2206,6 +2109,10 @@
 			if (code < 0)
 			    return code;
 			code = add_margin(ll, &flp, &als, y, y1);
+			if (code < 0)
+			    return code;
+			code = process_h_lists(ll, plp, &flp, &als);
+			plp = alp;
 		    }
 #		    endif
 		} else if ((adjust_below | adjust_above) != 0) {
@@ -2262,23 +2169,23 @@
 			}
 		    }
 		} else {	/* No Y adjustment. */
-#		    if PSEUDO_RASTERIZATION
-		    if (pseudo_rasterization) {
-			code = complete_margin(ll, &flp, &als, y, y1);
-			if (code < 0)
-			    return code;
-		    }
-#		    endif
 		    code = LOOP_FILL_TRAPEZOID_FIXED(xlbot, xbot - xlbot,
 						     y, xltop, wtop, height);
 #		    if PSEUDO_RASTERIZATION
 		    if (pseudo_rasterization) {
 			if (code < 0)
 			    return code;
+			code = complete_margin(ll, &flp, &als, y, y1);
+			if (code < 0)
+			    return code;
 			code = margin_interior(ll, &flp, &als, y, y1);
 			if (code < 0)
 			    return code;
 			code = add_margin(ll, &flp, &als, y, y1);
+			if (code < 0)
+			    return code;
+			code = process_h_lists(ll, plp, &flp, &als);
+			plp = alp;
 		    }
 #		    endif
 		}
@@ -2336,6 +2243,10 @@
 		    code = continue_margin(ll, &flp, &als, y, y1);
 		    if (code < 0)
 			return code;
+		    code = process_h_lists(ll, plp, &flp, &als);
+		    plp = alp;
+		    if (code < 0)
+			return code;
 		}
 #		endif
 	    }
@@ -2348,10 +2259,20 @@
 		return code;
 	}
 #endif
+	if (plp != 0) {
+	    code = process_h_lists(ll, plp, 0, 0);
+	    if (code < 0)
+		return code;
+	}
 	y = y1;
+	ll->h_list1 = ll->h_list0;
+	ll->h_list0 = 0;
     }
 #   if PSEUDO_RASTERIZATION
     if (pseudo_rasterization) {
+	code = process_h_lists(ll, 0, 0, 0);
+	if (code < 0)
+	    return code;
 	code = close_margins(dev, ll, &ll->margin_set1, fill_direct, cindex, pdevc, lop, fill_rect);
 	if (code < 0)
 	    return code;




More information about the gs-cvs mailing list