1 /*
2  *   Copyright (C) 1990-1992 Yale University
3  *
4  *   This work is distributed in the hope that it will be useful; you can
5  *   redistribute it and/or modify it under the terms of the
6  *   GNU General Public License as published by the Free Software Foundation;
7  *   either version 2 of the License,
8  *   or any later version, on the following conditions:
9  *
10  *   (a) YALE MAKES NO, AND EXPRESSLY DISCLAIMS
11  *   ALL, REPRESENTATIONS OR WARRANTIES THAT THE MANUFACTURE, USE, PRACTICE,
12  *   SALE OR
13  *   OTHER DISPOSAL OF THE SOFTWARE DOES NOT OR WILL NOT INFRINGE UPON ANY
14  *   PATENT OR
15  *   OTHER RIGHTS NOT VESTED IN YALE.
16  *
17  *   (b) YALE MAKES NO, AND EXPRESSLY DISCLAIMS ALL, REPRESENTATIONS AND
18  *   WARRANTIES
19  *   WHATSOEVER WITH RESPECT TO THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
20  *   INCLUDING,
21  *   BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
22  *   PARTICULAR
23  *   PURPOSE.
24  *
25  *   (c) LICENSEE SHALL MAKE NO STATEMENTS, REPRESENTATION OR WARRANTIES
26  *   WHATSOEVER TO
27  *   ANY THIRD PARTIES THAT ARE INCONSISTENT WITH THE DISCLAIMERS BY YALE IN
28  *   ARTICLE
29  *   (a) AND (b) above.
30  *
31  *   (d) IN NO EVENT SHALL YALE, OR ITS TRUSTEES, DIRECTORS, OFFICERS,
32  *   EMPLOYEES AND
33  *   AFFILIATES BE LIABLE FOR DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR
34  *   INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER YALE SHALL BE
35  *   ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE
36  *   POSSIBILITY OF THE FOREGOING.
37  *
38  */
39 
40 /* -----------------------------------------------------------------
41 FILE:	    merge.c
42 DESCRIPTION:How to merge tiles together to make row configuration
43 	    better.
44 CONTENTS:
45 DATE:	    Nov	29, 1990
46 REVISIONS:  Fri Jan 25 17:50:54 PST 1991 - added mirror row feature.
47 	    Sat Sep 21 15:41:10 EDT 1991 - updated for memory.
48 ----------------------------------------------------------------- */
49 
50 #include <stdio.h>
51 #include <yalecad/debug.h>
52 #include <yalecad/message.h>
53 #include <globals.h>
54 
55 
56 
57 static void check_max_length();
58 static void merge_adjacent_tiles();
59 void merge_downward( TILE_BOX *begin_tile );
60 void merge_upward( TILE_BOX *begin_tile );
61 
62 
63 
merge_tiles()64 void merge_tiles()
65 {
66     TILE_BOX *tileptr ; /* current tile */
67 
68     merge_adjacent_tiles() ;
69     /* now see if we can merge the start tile */
70     if( start_tileG ){
71 	merge_upward( start_tileG ) ;
72     }
73 } /* end merge_tiles */
74 
merge_upward(TILE_BOX * begin_tile)75 void merge_upward( TILE_BOX *begin_tile )
76 {
77     INT left ;          /* left edge of merge tile */
78     INT right ;         /* right edge of merge tile */
79     TILE_BOX *tileptr ; /* current tile */
80     TILE_BOX *temp ;    /* temp pointers to  tile */
81     TILE_BOX *tptr ;    /* temp pointers to  tile */
82     BOOL merge ;        /* TRUE if we merged at least one tile */
83 
84     /* we need to use the tile as a bound for left and right */
85     left = begin_tile->llx ;
86     right = begin_tile->urx ;
87     merge = FALSE ;
88     for( tileptr=tile_listG;tileptr;tileptr=tileptr->next ){
89 	/***********************************************************
90 	* See if we have any overlap with any tile in the tile set
91 	* in the y direction. If so, we can use this as a new top
92 	* The tile's left edge must be <= left and the tile's right
93 	* edge must be >= to right.
94 	***********************************************************/
95 	if( tileptr == last_tileG || tileptr == begin_tile ){
96 	    continue ;
97 	}
98 	if( tileptr->llx > left ){
99 	    continue ;
100 	}
101 	if( tileptr->urx < right ){
102 	    continue ;
103 	}
104 	/* Does it touch the begin tile in the y direction ? */
105 	if( projectY( tileptr->lly,tileptr->ury,begin_tile->lly,begin_tile->ury)){
106 	    /* this tile may be merged with the bottom tile */
107 	    if( begin_tile->ury < tileptr->ury ){
108 		begin_tile->ury = tileptr->ury ;
109 		begin_tile->merged = MERGED_UP ;
110 		merge = TRUE ;
111 		/***************************************************
112 		* Now check the four cases:
113 		* Case I:
114 
115 		+--------------------------------+
116 		+                                |
117 		+--------------------------------+
118 			     |                   |
119 			     |                   |
120 			     +-------------------+
121 		****************************************************/
122 		if( tileptr->llx < left && tileptr->urx == right ){
123 		    tileptr->urx = left ;
124 		    check_max_length( tileptr ) ;
125 
126 
127 		/***************************************************
128 		* Case II:
129 
130 		+--------------------------------+
131 		+                                |
132 		+--------------------------------+
133 		|                   |
134 		|                   |
135 		+-------------------+
136 		****************************************************/
137 		} else if( tileptr->llx == left && tileptr->urx > right ){
138 		    tileptr->llx = right ;
139 		    check_max_length( tileptr ) ;
140 
141 		/***************************************************
142 		* Case III:
143 
144 		+--------------------------------+
145 		+                                |
146 		+--------------------------------+
147 		     |                   |
148 		     |                   |
149 		     +-------------------+
150 		****************************************************/
151 		} else if( tileptr->llx < left && tileptr->urx > right ){
152 		    /* in this case we need to add a new tile */
153 		    temp = tileptr->next ;
154 		    tptr = tileptr->next = (TILE_BOX *)
155 			Ysafe_malloc( sizeof(TILE_BOX) ) ;
156 		    tptr->name = 0 ;
157 		    tptr->allocated = TRUE ;
158 		    tptr->llx = tileptr->llx ;
159 		    tptr->lly = tileptr->lly ;
160 		    tptr->urx = left ;
161 		    tptr->ury = tileptr->ury ;
162 		    tptr->merged = MERGED_NONE ;
163 		    tptr->actual_row_height = tileptr->actual_row_height ;
164 		    tptr->channel_separation = tileptr->channel_separation ;
165 		    tptr->min_length = tileptr->min_length ;
166 		    tptr->max_length = tptr->urx - tptr->llx - 2 * spacingG ;
167 		    tptr->row_start = 1 ;
168 		    tptr->numrows = 0 ;
169 		    tptr->illegal = FALSE ;
170 		    tptr->add_no_more_than = 0 ;
171 		    tptr->next = temp ;
172 		    tptr->prev = tileptr ;
173 		    temp->prev = tptr ;
174 		    tptr->class = tileptr->class ;
175 		    tptr->mirror = tileptr->mirror ;
176 		    /* see if we need to reset last_tileG */
177 		    if(!(tptr->next)){
178 			last_tileG = tptr ;
179 		    }
180 		    /* now reset tileptr values */
181 		    tileptr->llx = right ;
182 		    check_max_length( tileptr ) ;
183 
184 		/***************************************************
185 		* Case IV:
186 
187 		    +-------------------+
188 		    +                   |
189 		    +-------------------+
190 		    |                   |
191 		    |                   |
192 		    +-------------------+
193 		****************************************************/
194 		} else if( tileptr->llx == left && tileptr->urx == right ){
195 		    /* merge these adjacent tiles; delete tileptr2 */
196 
197 		    if( tileptr == tile_listG ) {
198 			tile_listG = tile_listG->next ;
199 			tile_listG->prev = NULL ;
200 			/* Ysafe_free( tileptr ) ; */
201 			tileptr->allocated = FALSE ;
202 		    } else {
203 			tileptr->prev->next = tileptr->next ;
204 			tileptr->next->prev = tileptr->prev ;
205 			temp = tileptr ;
206 			tileptr = tileptr->prev ;
207 			/* Ysafe_free( temp ) ; */
208 			temp->allocated = FALSE ;
209 		    }
210 		} /* end case IV */
211 
212 		if( limitMergeG ){
213 		    return ;
214 		}
215 	    }
216 	}
217     }
218     if( merge ){
219 	/* we merged tiles call merge right till we can't do no more */
220 	merge_upward( begin_tile ) ;
221     }
222 
223 } /* end merge_upward */
224 
merge_downward(TILE_BOX * begin_tile)225 void merge_downward( TILE_BOX *begin_tile )
226 {
227     INT left ;          /* left edge of merge tile */
228     INT right ;         /* right edge of merge tile */
229     TILE_BOX *tileptr ; /* current tile */
230     TILE_BOX *temp ;    /* temp pointers to  tile */
231     TILE_BOX *tptr ;    /* temp pointers to  tile */
232     BOOL merge ;        /* TRUE if we merged at least one tile */
233 
234     /* we need to use the tile as a bound for left and right */
235     left = begin_tile->llx ;
236     right = begin_tile->urx ;
237     merge = FALSE ;
238     for( tileptr=last_tileG->prev;tileptr;tileptr=tileptr->prev ){
239 	/***********************************************************
240 	* See if we have any overlap with any tile in the tile set
241 	* in the y direction. If so, we can use this as a new top
242 	* The tile's left edge must be <= left and the tile's right
243 	* edge must be >= to right.
244 	***********************************************************/
245 	if( tileptr == last_tileG || tileptr == begin_tile ){
246 	    continue ;
247 	}
248 	if( tileptr->llx > left ){
249 	    continue ;
250 	}
251 	if( tileptr->urx < right ){
252 	    continue ;
253 	}
254 	/* Does it touch the begin tile in the y direction ? */
255 	if( projectY( tileptr->lly,tileptr->ury,begin_tile->lly,begin_tile->ury)){
256 	    /* this tile may be merged with the bottom tile */
257 	    if( begin_tile->lly > tileptr->lly ){
258 		begin_tile->lly = tileptr->lly ;
259 		begin_tile->merged = MERGED_DOWN ;
260 		merge = TRUE ;
261 		/***************************************************
262 		* Now check the four cases:
263 		* Case I:
264 
265 			     +-------------------+
266 			     |                   |
267 			     |                   |
268 		+--------------------------------+
269 		+                                |
270 		+--------------------------------+
271 		****************************************************/
272 		if( tileptr->llx < left && tileptr->urx == right ){
273 		    tileptr->urx = left ;
274 		    check_max_length( tileptr ) ;
275 
276 
277 		/***************************************************
278 		* Case II:
279 
280 		+-------------------+
281 		|                   |
282 		|                   |
283 		+--------------------------------+
284 		+                                |
285 		+--------------------------------+
286 		****************************************************/
287 		} else if( tileptr->llx == left && tileptr->urx > right ){
288 		    tileptr->llx = right ;
289 		    check_max_length( tileptr ) ;
290 
291 		/***************************************************
292 		* Case III:
293 
294 		     +-------------------+
295 		     |                   |
296 		     |                   |
297 		+--------------------------------+
298 		+                                |
299 		+--------------------------------+
300 		****************************************************/
301 		} else if( tileptr->llx < left && tileptr->urx > right ){
302 		    /* in this case we need to add a new tile */
303 		    temp = tileptr->next ;
304 		    tptr = tileptr->next = (TILE_BOX *)
305 			Ysafe_malloc( sizeof(TILE_BOX) ) ;
306 		    tptr->name = 0 ;
307 		    tptr->allocated = TRUE ;
308 		    tptr->llx = tileptr->llx ;
309 		    tptr->lly = tileptr->lly ;
310 		    tptr->urx = left ;
311 		    tptr->ury = tileptr->ury ;
312 		    tptr->merged = MERGED_NONE ;
313 		    tptr->actual_row_height = tileptr->actual_row_height ;
314 		    tptr->channel_separation = tileptr->channel_separation ;
315 		    tptr->min_length = tileptr->min_length ;
316 		    tptr->max_length = tptr->urx - tptr->llx - 2 * spacingG ;
317 		    tptr->row_start = 1 ;
318 		    tptr->numrows = 0 ;
319 		    tptr->illegal = FALSE ;
320 		    tptr->add_no_more_than = 0 ;
321 		    tptr->class = tileptr->class ;
322 		    tptr->mirror = tileptr->mirror ;
323 		    tptr->next = temp ;
324 		    tptr->prev = tileptr ;
325 		    temp->prev = tptr ;
326 		    /* see if we need to reset last_tileG */
327 		    if(!(tptr->next)){
328 			last_tileG = tptr ;
329 		    }
330 		    /* now reset tileptr values */
331 		    tileptr->llx = right ;
332 		    check_max_length( tileptr ) ;
333 
334 		/***************************************************
335 		* Case IV:
336 
337 		    +-------------------+
338 		    |                   |
339 		    |                   |
340 		    +-------------------+
341 		    |                   |
342 		    +-------------------+
343 		****************************************************/
344 		} else if( tileptr->llx == left && tileptr->urx == right ){
345 		    /* merge these adjacent tiles; delete tileptr2 */
346 
347 		    if( tileptr == tile_listG ) {
348 			tile_listG = tile_listG->next ;
349 			tile_listG->prev = NULL ;
350 			/* Ysafe_free( tileptr ) ; */
351 			tileptr->allocated = FALSE ;
352 		    } else {
353 			tileptr->prev->next = tileptr->next ;
354 			tileptr->next->prev = tileptr->prev ;
355 			temp = tileptr ;
356 			tileptr = tileptr->next ;
357 			/* Ysafe_free( temp ) ; */
358 			temp->allocated = FALSE ;
359 		    }
360 		} /* end case IV */
361 
362 		if( limitMergeG ){
363 		    return ;
364 		}
365 	    }
366 
367 	}
368 
369     }
370     if( merge ){
371 	/* we merged tiles call merge right till we can't do no more */
372 	merge_downward( begin_tile ) ;
373     }
374 
375 } /* end merge_downward */
376 
merge_right(begin_tile)377 void merge_right( begin_tile )
378 TILE_BOX *begin_tile ;
379 {
380     INT bottom ;        /* bottom edge of merge tile */
381     INT top ;           /* top edge of merge tile */
382     TILE_BOX *tileptr ; /* current tile */
383     TILE_BOX *temp ;    /* temp pointers to  tile */
384     TILE_BOX *tptr ;    /* temp pointers to  tile */
385     BOOL merge ;        /* TRUE if we merged at least one tile */
386 
387     /* we need to use the tile as a bound for bottom and top */
388     bottom = begin_tile->lly ;
389     top = begin_tile->ury ;
390     merge = FALSE ;
391     for( tileptr=tile_listG;tileptr;tileptr=tileptr->next ){
392 	/***********************************************************
393 	* See if we have any overlap with any tile in the tile set
394 	* in the x direction. If so, we can use this as a new right
395 	* The tile's bottom edge must be <= bottom and the tile's top
396 	* edge must be >= to top.
397 	***********************************************************/
398 	if( tileptr == last_tileG || tileptr == begin_tile ){
399 	    continue ;
400 	}
401 	if( tileptr->lly > bottom ){
402 	    continue ;
403 	}
404 	if( tileptr->ury < top ){
405 	    continue ;
406 	}
407 	/* Does it touch the begin tile in the y direction ? */
408 	if( projectX( tileptr->llx,tileptr->urx,begin_tile->llx,begin_tile->urx)){
409 	    /* this tile may be merged with the right tile */
410 	    if( begin_tile->urx < tileptr->urx ){
411 		begin_tile->urx = tileptr->urx ;
412 		begin_tile->merged = MERGED_RITE ;
413 		merge = TRUE ;
414 		check_max_length( begin_tile ) ;
415 		/***************************************************
416 		* Now check the four cases:
417 		* Case I:
418 
419 		+-------------------+-------------------+
420 		+    begin          |    tileptr        |
421 		+-------------------+                   |
422 			            |                   |
423 			            +-------------------+
424 		****************************************************/
425 		if( tileptr->lly < bottom && tileptr->ury == top ){
426 		    tileptr->ury = bottom ;
427 		    check_max_length( tileptr ) ;
428 
429 
430 		/***************************************************
431 		* Case II:
432 
433 			            +-------------------+
434 			            |                   |
435 		+-------------------+                   |
436 		+    begin          |    tileptr        |
437 		+-------------------+-------------------+
438 		****************************************************/
439 		} else if( tileptr->lly == bottom && tileptr->ury > top ){
440 		    tileptr->lly = top ;
441 		    check_max_length( tileptr ) ;
442 
443 		/***************************************************
444 		* Case III:
445 
446 			            +-------------------+
447 		+-------------------+                   |
448 		+    begin          |    tileptr        |
449 		+-------------------+                   |
450 				    +-------------------+ new tile here
451 		****************************************************/
452 		} else if( tileptr->lly < bottom && tileptr->ury > top ){
453 		    /* in this case we need to add a new tile */
454 		    temp = tileptr->next ;
455 		    tptr = tileptr->next = (TILE_BOX *)
456 			Ysafe_malloc( sizeof(TILE_BOX) ) ;
457 		    tptr->name = 0 ;
458 		    tptr->allocated = TRUE ;
459 		    tptr->llx = tileptr->llx ;
460 		    tptr->lly = tileptr->lly ;
461 		    tptr->urx = tileptr->urx ;
462 		    tptr->ury = bottom ;
463 		    tptr->merged = MERGED_NONE ;
464 		    tptr->actual_row_height = tileptr->actual_row_height ;
465 		    tptr->channel_separation = tileptr->channel_separation ;
466 		    tptr->min_length = tileptr->min_length ;
467 		    tptr->max_length = tptr->urx - tptr->llx - 2 * spacingG ;
468 		    tptr->row_start = 1 ;
469 		    tptr->numrows = 0 ;
470 		    tptr->illegal = FALSE ;
471 		    tptr->add_no_more_than = 0 ;
472 		    tptr->next = temp ;
473 		    tptr->prev = tileptr ;
474 		    temp->prev = tptr ;
475 		    tptr->class = tileptr->class ;
476 		    tptr->mirror = tileptr->mirror ;
477 		    /* see if we need to reset last_tileG */
478 		    if(!(tptr->next)){
479 			last_tileG = tptr ;
480 		    }
481 		    /* now reset tileptr values */
482 		    tileptr->lly = top ;
483 		    check_max_length( tileptr ) ;
484 
485 		/***************************************************
486 		* Case IV:
487 		+-------------------+-------------------+
488 		+    begin          |    tileptr        |
489 		+-------------------+-------------------+
490 		****************************************************/
491 		} else if( tileptr->lly == bottom && tileptr->ury==top ){
492 		    /* merge these adjacent tiles; delete tileptr2 */
493 
494 		    if( tileptr == tile_listG ) {
495 			tile_listG = tile_listG->next ;
496 			tile_listG->prev = NULL ;
497 			/* Ysafe_free( tileptr ) ;*/
498 			tileptr->allocated = FALSE ;
499 			tileptr = tile_listG ;
500 		    } else {
501 			tileptr->prev->next = tileptr->next ;
502 			tileptr->next->prev = tileptr->prev ;
503 			temp = tileptr ;
504 			tileptr = tileptr->prev ;
505 			/* Ysafe_free( temp ) ; */
506 			temp->allocated = FALSE ;
507 		    }
508 		} /* end case IV */
509 
510 		if( limitMergeG ){
511 		    return ;
512 		}
513 	    }
514 
515 	}
516     }
517     if( merge ){
518 	/* we merged tiles call merge right till we can't do no more */
519 	merge_right( begin_tile ) ;
520     }
521 
522 } /* end merge_right */
523 
merge_left(begin_tile)524 void merge_left( begin_tile )
525 TILE_BOX *begin_tile ;
526 {
527     INT bottom ;        /* bottom edge of merge tile */
528     INT top ;           /* top edge of merge tile */
529     TILE_BOX *tileptr ; /* current tile */
530     TILE_BOX *temp ;    /* temp pointers to  tile */
531     TILE_BOX *tptr ;    /* temp pointers to  tile */
532     BOOL merge ;        /* TRUE if we merged at least one tile */
533 
534     /* we need to use the tile as a bound for bottom and top */
535     bottom = begin_tile->lly ;
536     top = begin_tile->ury ;
537     merge = FALSE ;
538     for( tileptr=tile_listG;tileptr;tileptr=tileptr->next ){
539 	/***********************************************************
540 	* See if we have any overlap with any tile in the tile set
541 	* in the x direction. If so, we can use this as a new right
542 	* The tile's bottom edge must be <= bottom and the tile's top
543 	* edge must be >= to top.
544 	***********************************************************/
545 	if( tileptr == last_tileG || tileptr == begin_tile ){
546 	    continue ;
547 	}
548 	if( tileptr->lly > bottom ){
549 	    continue ;
550 	}
551 	if( tileptr->ury < top ){
552 	    continue ;
553 	}
554 	/* Does it touch the begin tile in the y direction ? */
555 	if( projectX( tileptr->llx,tileptr->urx,begin_tile->llx,begin_tile->urx)){
556 	    /* this tile may be merged with the right tile */
557 	    if( begin_tile->llx > tileptr->llx ){
558 		begin_tile->llx = tileptr->llx ;
559 		begin_tile->merged = MERGED_LEFT ;
560 		merge = TRUE ;
561 		check_max_length( begin_tile ) ;
562 		/***************************************************
563 		* Now check the four cases:
564 		* Case I:
565 		+-------------------+-------------------+
566 		|    tileptr        |    begin          |
567 	        |                   +-------------------+
568 		+-------------------+
569 		****************************************************/
570 		if( tileptr->lly < bottom && tileptr->ury == top ){
571 		    tileptr->ury = bottom ;
572 		    check_max_length( tileptr ) ;
573 
574 
575 		/***************************************************
576 		* Case II:
577 		+-------------------+
578 		|                   +-------------------+
579 		|    tileptr        |    begin          |
580 		+-------------------+-------------------+
581 
582 		****************************************************/
583 		} else if( tileptr->lly == bottom && tileptr->ury > top ){
584 		    tileptr->lly = top ;
585 		    check_max_length( tileptr ) ;
586 
587 		/***************************************************
588 		* Case III:
589 
590 		+-------------------+
591 		|                   +-------------------+
592 		|    tileptr        |    begin          |
593 	        |                   +-------------------+
594 		+-------------------+ new tile here
595 		****************************************************/
596 		} else if( tileptr->lly < bottom && tileptr->ury > top ){
597 		    /* in this case we need to add a new tile */
598 		    temp = tileptr->next ;
599 		    tptr = tileptr->next = (TILE_BOX *)
600 			Ysafe_malloc( sizeof(TILE_BOX) ) ;
601 		    tptr->name = 0 ;
602 		    tptr->allocated = TRUE ;
603 		    tptr->llx = tileptr->llx ;
604 		    tptr->lly = tileptr->lly ;
605 		    tptr->urx = tileptr->urx ;
606 		    tptr->ury = bottom ;
607 		    tptr->merged = MERGED_NONE ;
608 		    tptr->actual_row_height = tileptr->actual_row_height ;
609 		    tptr->channel_separation = tileptr->channel_separation ;
610 		    tptr->min_length = tileptr->min_length ;
611 		    tptr->max_length = tptr->urx - tptr->llx - 2 * spacingG ;
612 		    tptr->row_start = 1 ;
613 		    tptr->numrows = 0 ;
614 		    tptr->illegal = FALSE ;
615 		    tptr->add_no_more_than = 0 ;
616 		    tptr->next = temp ;
617 		    tptr->prev = tileptr ;
618 		    temp->prev = tptr ;
619 		    tptr->class = tileptr->class ;
620 		    tptr->mirror = tileptr->mirror ;
621 		    /* see if we need to reset last_tileG */
622 		    if(!(tptr->next)){
623 			last_tileG = tptr ;
624 		    }
625 		    /* now reset tileptr values */
626 		    tileptr->lly = top ;
627 		    check_max_length( tileptr ) ;
628 
629 		/***************************************************
630 		* Case IV:
631 		+-------------------+-------------------+
632 		+    tileptr        |    begin          |
633 		+-------------------+-------------------+
634 		****************************************************/
635 		} else if( tileptr->lly == bottom && tileptr->ury==top ){
636 		    /* merge these adjacent tiles; delete tileptr2 */
637 
638 		    if( tileptr == tile_listG ) {
639 			tile_listG = tile_listG->next ;
640 			tile_listG->prev = NULL ;
641 			/* Ysafe_free( tileptr ) ; */
642 			tileptr->allocated = FALSE ;
643 			tileptr = tile_listG ;
644 		    } else {
645 			tileptr->prev->next = tileptr->next ;
646 			tileptr->next->prev = tileptr->prev ;
647 			temp = tileptr ;
648 			tileptr = tileptr->prev ;
649 			/* Ysafe_free( temp ) ; */
650 			temp->allocated = FALSE ;
651 		    }
652 		} /* end case IV */
653 
654 		if( limitMergeG ){
655 		    return ;
656 		}
657 	    }
658 
659 	}
660     }
661     if( merge ){
662 	/* we merged tiles call merge left till we can't do no more */
663 	merge_left( begin_tile ) ;
664     }
665 
666 } /* end merge_left */
667 
check_max_length(tileptr)668 static void check_max_length( tileptr )
669 TILE_BOX *tileptr ;
670 {
671     INT length ;              /* length of tile */
672 
673     length = tileptr->urx - tileptr->llx - 2 * spacingG ;
674     tileptr->max_length = length ;
675 
676 }/* end check_max_length */
677 
renumber_tiles()678 void renumber_tiles()
679 {
680     INT count ;              /* count the tiles */
681     TILE_BOX *tileptr ;      /* current tile */
682     count = 0 ;
683     for( tileptr=tile_listG;tileptr;tileptr=tileptr->next ){
684 	tileptr->name = ++count ;
685     }
686 } /* end renumber_tiles() */
687 
merge_adjacent_tiles()688 static void merge_adjacent_tiles()
689 {
690 
691     TILE_BOX *tileptr1 , *tileptr2 , *tileptr ;
692 
693 REDO:
694     for( tileptr1 = tile_listG;tileptr1->next;tileptr1 = tileptr1->next ){
695 	// for( tileptr2=tile_listG;tileptr2->next;tileptr2=tileptr2->next ){
696 	for( tileptr2=tile_listG;tileptr2;tileptr2=tileptr2->next ){
697 	    if( tileptr2 == tileptr1 ) {
698 		continue ;
699 	    }
700 	    if( tileptr1->llx == tileptr2->llx &&
701 			    tileptr1->urx == tileptr2->urx &&
702 			    tileptr1->ury == tileptr2->lly ) {
703 		/* merge these adjacent tiles; delete tileptr2 */
704 		tileptr1->ury = tileptr2->ury ;
705 
706 		if( tileptr2 == tile_listG ) {
707 		    tile_listG = tile_listG->next ;
708 		    tile_listG->prev = NULL ;
709 		    /* Ysafe_free( tileptr2 ) ; */
710 		    tileptr2->allocated = FALSE ;
711 		    goto REDO ;
712 		} else {
713 		    tileptr = tile_listG ;
714 		    while( tileptr->next != tileptr2 ) {
715 			tileptr = tileptr->next ;
716 		    }
717 		    tileptr->next = tileptr2->next ;
718 		    if( tileptr2->next ){
719 		        tileptr2->next->prev = tileptr ;
720 		    }
721 		    /* Ysafe_free( tileptr2 ) ; */
722 		    tileptr2->allocated = FALSE ;
723 		    goto REDO ;
724 		}
725 	    }
726 
727 	} /* end inner loop */
728     } /* end outer loop */
729     return ;
730 }/* end merge_adjacent_tiles */
731 
dtiles()732 void dtiles()
733 {
734     TILE_BOX *tptr ;      /* current tile */
735 
736     fprintf( stderr, "The forward tiles\n" ) ;
737     for( tptr=tile_listG;tptr;tptr=tptr->next ){
738 	fprintf( stderr, "\tTile:%d l:%5d b:%5d r:%5d t:%5d\n",
739 	    tptr->name, tptr->llx, tptr->lly, tptr->urx, tptr->ury ) ;
740     }
741     fprintf( stderr, "The backward tiles\n" ) ;
742     for( tptr=last_tileG;tptr;tptr=tptr->prev ){
743 	fprintf( stderr, "\tTile:%d l:%5d b:%5d r:%5d t:%5d\n",
744 	    tptr->name, tptr->llx, tptr->lly, tptr->urx, tptr->ury ) ;
745     }
746 
747 }
748