1 /* $XConsortium: out_bl2d.c,v 1.5 94/02/07 10:01:15 gildea Exp $ */
5 Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
6 You are hereby granted permission under all Bitstream propriety rights to
7 use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
8 software and the Bitstream Charter outline font for any purpose and without
9 restrictions; provided, that this notice is left intact on all copies of such
10 software or font and that Bitstream's trademark is acknowledged as shown below
11 on all unmodified copies of such font.
13 BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
16 BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
17 WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
19 DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
20 INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
21 WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
25 /*************************** O U T _ B L 2 D . C *****************************
27 * This is an output module for screen writer using two dimensional scanning *
28 ****************************************************************************/
31 #include "spdo_prv.h" /* General definitions for speedo */
35 #define ABS(X) ( (X < 0) ? -X : X)
39 #define SHOW(X) printf("X = %d\n", X)
44 /***** GLOBAL VARIABLES *****/
46 /***** GLOBAL FUNCTIONS *****/
48 /***** EXTERNAL VARIABLES *****/
50 /***** EXTERNAL FUNCTIONS *****/
52 /***** STATIC VARIABLES *****/
54 /***** STATIC FUNCTIONS *****/
58 static void sp_draw_vector_to_2d(PROTO_DECL2 fix15 x0,fix15 y0,fix15 x1,fix15 y1,band_t GLOBALFAR *band);
59 static void sp_add_intercept_2d(PROTO_DECL2 fix15 y,fix15 x);
60 static void sp_proc_intercepts_2d(PROTO_DECL1);
62 static void sp_add_intercept_2d();
63 static void sp_proc_intercepts_2d();
64 static void sp_draw_vector_to_2d();
69 FUNCTION boolean init_2d(specsarg)
71 specs_t GLOBALFAR *specsarg;
73 * init_out_2d() is called by sp_set_specs() to initialize the output module.
74 * Returns TRUE if output module can accept requested specifications.
75 * Returns FALSE otherwise.
79 if (specsarg->flags & CURVES_OUT)
80 return FALSE; /* Curves out, clipping not supported */
83 printf("INIT_OUT__2d()\n");
90 FUNCTION boolean begin_char_2d(Psw, Pmin, Pmax)
95 /* Called once at the start of the character generation process
96 * Initializes intercept table, either calculates pixel maxima or
97 * decides that they need to be collected
101 printf("BEGIN_CHAR__2d(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
102 (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
103 (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
104 (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
106 /* Convert PIX.FRAC to 16.16 form */
107 sp_globals.x_scan_active = TRUE; /* Assume x-scanning from the start */
109 init_char_out(Psw,Pmin,Pmax);
116 FUNCTION void begin_contour_2d(P1, outside)
120 /* Called at the start of each contour
125 printf("BEGIN_CONTOUR__2d(%3.4f, %3.4f, %s)\n",
126 (real)P1.x / (real)sp_globals.onepix,
127 (real)P1.y / (real)sp_globals.onepix,
128 outside? "outside": "inside");
130 sp_globals.x0_spxl = P1.x;
131 sp_globals.y0_spxl = P1.y;
136 FUNCTION void line_2d(P1)
140 * Called for each vector in the transformed character
141 * "draws" vector into intercept table
146 printf("LINE_0(%3.4f, %3.4f)\n",
147 (real)P1.x / (real)sp_globals.onepix,
148 (real)P1.y / (real)sp_globals.onepix);
151 if (sp_globals.extents_running)
153 if (sp_globals.x0_spxl > sp_globals.bmap_xmax)
154 sp_globals.bmap_xmax = sp_globals.x0_spxl;
155 if (sp_globals.x0_spxl < sp_globals.bmap_xmin)
156 sp_globals.bmap_xmin = sp_globals.x0_spxl;
157 if (sp_globals.y0_spxl > sp_globals.bmap_ymax)
158 sp_globals.bmap_ymax = sp_globals.y0_spxl;
159 if (sp_globals.y0_spxl < sp_globals.bmap_ymin)
160 sp_globals.bmap_ymin = sp_globals.y0_spxl;
163 if (!sp_globals.intercept_oflo)
165 sp_draw_vector_to_2d(sp_globals.x0_spxl,
169 &sp_globals.y_band); /* y-scan */
171 if (sp_globals.x_scan_active)
172 sp_draw_vector_to_2d(sp_globals.y0_spxl,
176 &sp_globals.x_band); /* x-scan if selected */
179 sp_globals.x0_spxl = P1.x;
180 sp_globals.y0_spxl = P1.y; /* update endpoint */
183 FUNCTION static void sp_draw_vector_to_2d(x0, y0, x1, y1, band)
185 fix15 x0; /* X coordinate */
186 fix15 y0; /* Y coordinate */
189 band_t GLOBALFAR *band;
191 register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */
192 register fix15 yc; /* Current scan-line */
193 fix15 temp1; /* various uses */
194 fix15 temp2; /* various uses */
195 register fix31 dx_dy; /* slope of line in 16.16 form */
196 register fix31 xc; /* high-precision (16.16) x coordinate */
199 yc = (y0 + sp_globals.pixrnd) >> sp_globals.pixshift; /* current scan line = end of last line */
200 y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan line */
202 if ((how_many_y = y_pxl - yc) == 0) return; /* Don't draw a null line */
204 if (how_many_y < 0) yc--; /* Predecrment downward lines */
206 if (yc > band->band_max) /* Is start point above band? */
208 if (y_pxl > band->band_max) return; /* line has to go down! */
209 how_many_y = y_pxl - (yc = band->band_max) - 1; /* Yes, limit it */
212 if (yc < band->band_min) /* Is start point below band? */
214 if (y_pxl < band->band_min) return; /* line has to go up! */
215 how_many_y = y_pxl - (yc = band->band_min); /* Yes, limit it */
218 xc = (fix31)(x0 + sp_globals.pixrnd) << 16; /* Original x coordinate with built in */
219 /* rounding. int.16 + pixshift form */
221 if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */
223 dx_dy = 0L; /* Zero slope, leave xc alone */
227 /* calculate dx_dy at 16.16 fixed point */
229 dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0);
231 /* We have to check for a @#$%@# possible multiply overflow */
232 /* by doing another @#$*& multiply. In assembly language, */
233 /* the program could just check the OVerflow flag or whatever*/
234 /* works on the particular processor. This C code is meant */
235 /* to be processor independent. */
237 temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd;
238 /* This sees if the sign bits start at bit 15 */
239 /* if they do, no overflow has occurred */
241 temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15);
243 if ( (temp2 != (fix15)0xFFFF) &&
245 { /* Overflow. Pick point closest to yc + .5 */
246 if (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd))
247 { /* use x1 instead of x0 */
248 xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift);
252 /* calculate new xc at the center of the *current* scan line */
253 /* due to banding, yc may be several lines away from y0 */
254 /* xc += (yc + .5 - y0) * dx_dy */
255 /* This multiply generates a subpixel delta. */
256 /* So we leave it as an int.pixshift + 16 delta */
258 xc += (fix31)temp1 * dx_dy;
259 dx_dy <<= sp_globals.pixshift;
262 yc -= band->band_array_offset; /* yc is now an offset relative to the band */
266 if ((how_many_y += yc + 1) < band->band_floor)
267 how_many_y = band->band_floor; /* can't go below floor */
268 while(yc >= how_many_y)
270 temp1 = (fix15)(xc >> 16);
271 sp_add_intercept_2d(yc--,temp1);
277 /* check to see that line doesn't extend beyond top of band */
278 if ((how_many_y += yc) > band->band_ceiling)
279 how_many_y = band->band_ceiling;
280 while(yc < how_many_y)
282 temp1 = (fix15)(xc >> 16);
283 sp_add_intercept_2d(yc++,temp1);
292 FUNCTION boolean end_char_2d()
294 /* Called when all character data has been output
295 * Return TRUE if output process is complete
296 * Return FALSE to repeat output of the transformed data beginning
297 * with the first contour
304 fix31 em_max, em_min, bmap_max, bmap_min;
308 printf("END_CHAR__2d()\n");
311 if (sp_globals.first_pass)
313 if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin)
315 sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
316 sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
320 sp_globals.xmin = sp_globals.xmax = 0;
322 if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin)
326 switch(sp_globals.tcb0.xtype)
328 case 1: /* 180 degree rotation */
329 if (sp_globals.specs.flags & CLIP_TOP)
331 sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
332 sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
333 bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
334 sp_globals.clip_ymin = -1 * sp_globals.clip_ymin;
335 if (bmap_min < sp_globals.clip_ymin)
336 sp_globals.ymin = sp_globals.clip_ymin;
338 sp_globals.ymin = bmap_min;
340 if (sp_globals.specs.flags & CLIP_BOTTOM)
342 sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
343 sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
344 bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
345 if (bmap_max < sp_globals.clip_ymax)
346 sp_globals.ymax = bmap_max;
348 sp_globals.ymax = sp_globals.clip_ymax;
350 sp_globals.clip_xmax = -sp_globals.xmin;
351 sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) -
354 case 2: /* 90 degree rotation */
355 if (sp_globals.specs.flags & CLIP_TOP)
357 sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
358 sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
359 sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
360 bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
361 if (bmap_min > sp_globals.clip_xmin)
362 sp_globals.clip_xmin = bmap_min;
364 /* normalize to x origin */
365 sp_globals.clip_xmin -= sp_globals.xmin;
367 if (sp_globals.specs.flags & CLIP_BOTTOM)
369 sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
370 sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
371 bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
372 if (bmap_max < sp_globals.clip_xmax)
373 sp_globals.xmax = bmap_max;
375 sp_globals.xmax = sp_globals.clip_xmax;
376 sp_globals.clip_ymax = 0;
377 if ((sp_globals.specs.flags & CLIP_TOP) &&
378 (sp_globals.ymax > sp_globals.clip_ymax))
379 sp_globals.ymax = sp_globals.clip_ymax;
380 sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
381 if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
382 (sp_globals.ymin < sp_globals.clip_ymin))
383 sp_globals.ymin = sp_globals.clip_ymin;
384 /* normalize to x origin */
385 sp_globals.clip_xmax -= sp_globals.xmin;
388 case 3: /* 270 degree rotation */
389 if (sp_globals.specs.flags & CLIP_TOP)
391 sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
392 sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
393 sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
394 bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
396 /* let the minimum be the larger of these two values */
397 if (bmap_min > sp_globals.clip_xmin)
398 sp_globals.clip_xmin = bmap_min;
400 /* normalize the x value to new xorgin */
401 sp_globals.clip_xmin -= sp_globals.xmin;
403 if (sp_globals.specs.flags & CLIP_BOTTOM)
405 sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
406 sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
407 bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
409 /* let the max be the lesser of these two values */
410 if (bmap_max < sp_globals.clip_xmax)
412 sp_globals.xmax = bmap_max;
413 sp_globals.clip_xmax = bmap_max;
416 sp_globals.xmax = sp_globals.clip_xmax;
418 /* normalize the x value to new x origin */
419 sp_globals.clip_xmax -= sp_globals.xmin;
421 /* compute y clip values */
422 sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
423 if ((sp_globals.specs.flags & CLIP_TOP) &&
424 (sp_globals.ymax > sp_globals.clip_ymax))
425 sp_globals.ymax = sp_globals.clip_ymax;
426 sp_globals.clip_ymin = 0;
427 if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
428 (sp_globals.ymin < sp_globals.clip_ymin))
429 sp_globals.ymin = sp_globals.clip_ymin;
431 default: /* this is for zero degree rotation and arbitrary rotation */
432 if (sp_globals.specs.flags & CLIP_TOP)
434 sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
435 sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
436 bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
437 if (bmap_max > sp_globals.clip_ymax)
438 sp_globals.ymax = bmap_max;
440 sp_globals.ymax = sp_globals.clip_ymax;
442 if (sp_globals.specs.flags & CLIP_BOTTOM)
444 sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
445 sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
446 sp_globals.clip_ymin = - sp_globals.clip_ymin;
447 bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
448 if (bmap_min < sp_globals.clip_ymin)
449 sp_globals.ymin = sp_globals.clip_ymin;
451 sp_globals.ymin = bmap_min;
453 sp_globals.clip_xmin = -sp_globals.xmin;
454 sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) -
458 if ( !(sp_globals.specs.flags & CLIP_TOP))
460 sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
463 if ( !(sp_globals.specs.flags & CLIP_BOTTOM))
465 sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
469 sp_globals.ymin = sp_globals.ymax = 0;
472 /* add in the rounded out part (from xform.) of the left edge */
473 if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */
474 xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
476 if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */
477 xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ;
479 xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */
481 if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */
482 yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
484 if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */
485 yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift));
486 else /* all other cases have no round error on yorg */
487 yorg = (fix31)sp_globals.ymin << 16;
489 open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg,
490 sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin);
491 if (sp_globals.intercept_oflo)
493 sp_globals.y_band.band_min = sp_globals.ymin;
494 sp_globals.y_band.band_max = sp_globals.ymax;
495 sp_globals.x_scan_active = FALSE;
496 sp_globals.no_x_lists = 0;
497 init_intercepts_out();
498 sp_globals.first_pass = FALSE;
499 sp_globals.extents_running = FALSE;
504 sp_proc_intercepts_2d();
511 if (sp_globals.intercept_oflo)
513 reduce_band_size_out();
514 init_intercepts_out();
519 sp_proc_intercepts_2d();
522 init_intercepts_out();
533 FUNCTION static void sp_add_intercept_2d(y, x)
535 fix15 y; /* Y coordinate in relative pixel units */
536 /* (0 is lowest sample in band) */
537 fix15 x; /* X coordinate of intercept in subpixel units */
539 /* Called by line() to add an intercept to the intercept list structure
543 register fix15 from; /* Insertion pointers for the linked list sort */
547 /* Bounds checking IS done in debug mode */
548 if ((y >= MAX_INTERCEPTS) || (y < 0))
550 printf("Intercept out of table!!!!! (%d)\n",y);
554 if (y >= sp_globals.no_y_lists)
556 printf(" Add x intercept(%2d, %f)\n",
557 y + sp_globals.x_band.band_min - sp_globals.no_y_lists,
558 (real)x/(real)sp_globals.onepix);
559 if (y > (sp_globals.no_x_lists + sp_globals.no_y_lists))
561 printf(" Intercept too big for band!!!!!\007\n");
567 printf(" Add y intercept(%2d, %f)\n", y + sp_globals.y_band.band_min,(real)x/(real)sp_globals.onepix);
570 if (y < 0) /* Y value below bottom of current band? */
572 printf(" Intecerpt less than 0!!!\007\n");
577 /* Store new values */
579 sp_intercepts.car[sp_globals.next_offset] = x;
581 /* Find slot to insert new element (between from and to) */
583 from = y; /* Start at list head */
585 while( (to = sp_intercepts.cdr[from]) >= sp_globals.first_offset) /* Until to == end of list */
587 if (x <= sp_intercepts.car[to]) /* If next item is larger than or same as this one... */
588 goto insert_element; /* ... drop out and insert here */
589 from = to; /* move forward in list */
592 insert_element: /* insert element "next_offset" between elements "from" */
595 sp_intercepts.cdr[from] = sp_globals.next_offset;
596 sp_intercepts.cdr[sp_globals.next_offset] = to;
598 if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */
600 sp_globals.intercept_oflo = TRUE;
601 /* There may be a few more calls to "add_intercept" from the current line */
602 /* To avoid problems, we set next_offset to a safe value. We don't care */
603 /* if the intercept table gets trashed at this point */
604 sp_globals.next_offset = sp_globals.first_offset;
611 FUNCTION static void sp_proc_intercepts_2d()
613 /* Called by sp_make_char to output accumulated intercept lists
614 * Clips output to xmin, xmax, sp_globals.ymin, ymax boundaries
618 register fix15 from, to; /* Start and end of run in pixel units
619 relative to left extent of character */
621 register fix15 scan_line;
622 fix15 local_bmap_xmin;
623 fix15 local_bmap_xmax;
624 fix15 first_y, last_y;
627 boolean clipleft, clipright;
630 if ((sp_globals.specs.flags & CLIP_LEFT) != 0)
634 if ((sp_globals.specs.flags & CLIP_RIGHT) != 0)
638 if (clipleft || clipright)
640 xmax = sp_globals.clip_xmax << sp_globals.pixshift;
641 xmin = sp_globals.clip_xmin << sp_globals.pixshift;
644 xmax = ((sp_globals.set_width.x+32768L) >> 16);
647 if (sp_globals.x_scan_active) /* If xscanning, we need to make sure we don't miss any important pixels */
649 first_y = sp_globals.x_band.band_floor; /* start of x lists */
650 last_y = sp_globals.x_band.band_ceiling; /* end of x lists */
651 for (y = first_y; y != last_y; y++) /* scan all xlists */
653 i = sp_intercepts.cdr[y]; /* Index head of intercept list */
654 while (i != 0) /* Link to next intercept if present */
656 from = sp_intercepts.car[i];
658 i = sp_intercepts.cdr[i]; /* Link to next intercept */
659 if (i == 0) /* End of list? */
662 printf("****** proc_intercepts: odd number of intercepts in x list\n");
666 to = sp_intercepts.car[i];
667 k = sp_intercepts.cdr[i];
668 if (((to >> sp_globals.pixshift) >= (from >> sp_globals.pixshift)) &&
669 ((to - from) < (sp_globals.onepix + 1)))
671 from = ((fix31)to + (fix31)from - (fix31)sp_globals.onepix) >> (sp_globals.pixshift + 1);
672 if (from > sp_globals.y_band.band_max)
673 from = sp_globals.y_band.band_max;
674 if ((from -= sp_globals.y_band.band_min) < 0)
676 to = ((y - sp_globals.x_band.band_floor + sp_globals.x_band.band_min)
677 << sp_globals.pixshift)
679 sp_intercepts.car[j] = to;
680 sp_intercepts.car[i] = to + sp_globals.onepix;
681 sp_intercepts.cdr[i] = sp_intercepts.cdr[from];
682 sp_intercepts.cdr[from] = j;
689 printf("\nIntercept lists:\n");
692 if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax)
693 first_y = sp_globals.ymax - 1; /* Clip to ymax boundary */
695 if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin)
696 last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */
698 last_y -= sp_globals.y_band.band_array_offset;
700 local_bmap_xmin = sp_globals.xmin << sp_globals.pixshift;
701 local_bmap_xmax = (sp_globals.xmax << sp_globals.pixshift) + sp_globals.pixrnd;
704 /* Print out all of the intercept info */
705 scan_line = sp_globals.ymax - first_y - 1;
707 for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
709 i = y; /* Index head of intercept list */
710 while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
712 if ((from = sp_intercepts.car[i] - local_bmap_xmin) < 0)
713 from = 0; /* Clip to xmin boundary */
714 i = sp_intercepts.cdr[i]; /* Link to next intercept */
715 if (i == 0) /* End of list? */
717 printf("****** proc_intercepts: odd number of intercepts\n");
720 if ((to = sp_intercepts.car[i]) > sp_globals.bmap_xmax)
721 to = sp_globals.bmap_xmax - local_bmap_xmin; /* Clip to xmax boundary */
723 to -= local_bmap_xmin;
724 printf(" Y = %2d (scanline %2d): %3.4f %3.4f:\n",
725 y + sp_globals.y_band.band_min,
727 (real)from / (real)sp_globals.onepix,
728 (real)to / (real)sp_globals.onepix);
734 scan_line = sp_globals.ymax - first_y - 1;
736 for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
738 i = y; /* Index head of intercept list */
739 while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
741 if ((from = sp_intercepts.car[i] - local_bmap_xmin) < 0)
742 from = 0; /* Clip to xmin boundary */
743 i = sp_intercepts.cdr[i]; /* Link to next intercept */
745 if ((to = sp_intercepts.car[i]) > local_bmap_xmax)
746 to = sp_globals.bmap_xmax - local_bmap_xmin; /* Clip to xmax boundary */
748 to -= local_bmap_xmin;
765 if ( (to - from) <= sp_globals.onepix)
767 from = (to + from - sp_globals.onepix) >> (sp_globals.pixshift + 1);
768 set_bitmap_bits(scan_line, from, from + 1);
772 set_bitmap_bits(scan_line, from >> sp_globals.pixshift, to >> sp_globals.pixshift);