Bug Summary

File:Clip.c
Location:line 700, column 6
Description:Value stored to 'p' is never read

Annotated Source Code

1/*
2 * Copyright (c) 1998 by The XFree86 Project, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the XFree86 Project shall
23 * not be used in advertising or otherwise to promote the sale, use or other
24 * dealings in this Software without prior written authorization from the
25 * XFree86 Project.
26 */
27
28#ifdef HAVE_CONFIG_H1
29#include <config.h>
30#endif
31#include <stdlib.h>
32
33#include <X11/IntrinsicP.h>
34#include <X11/Xmu/Xmu.h>
35
36#define XmuMax(a, b)((a) > (b) ? (a) : (b)) ((a) > (b) ? (a) : (b))
37#define XmuMin(a, b)((a) < (b) ? (a) : (b)) ((a) < (b) ? (a) : (b))
38
39/*
40 * Function:
41 * XmuNewArea
42 *
43 * Parameters:
44 * x1 - Coordinates of the rectangle
45 * y1 - ""
46 * x2 - ""
47 * y2 - ""
48 *
49 * Description:
50 * Creates a new rectangular clipping area
51 */
52XmuArea *
53XmuNewArea(int x1, int y1, int x2, int y2)
54{
55 XmuArea *area;
56
57 area = (XmuArea *)XtMalloc(sizeof(XmuArea));
58 if (x2 > x1 && y2 > y1)
59 {
60 area->scanline = XmuNewScanline(y1, x1, x2);
61 area->scanline->next = XmuNewScanline(y2, 0, 0);
62 }
63 else
64 area->scanline = (XmuScanline *)NULL((void*)0);
65
66 return (area);
67}
68
69/*
70 * Function:
71 * XmuAreaDup
72 *
73 * Parameters:
74 * area - Area to copy
75 *
76 * Description:
77 * Returns a copy of its argument
78 */
79XmuArea *
80XmuAreaDup(XmuArea *area)
81{
82 XmuArea *dst;
83
84 if (!area)
85 return ((XmuArea *)NULL((void*)0));
86
87 dst = XmuCreateArea()XmuNewArea(0, 0, 0, 0);
88 XmuAreaCopy(dst, area);
89 return (dst);
90}
91
92/*
93 * Function:
94 * XmuAreaCopy
95 *
96 * Parameters:
97 * dst - destination area
98 * src - source area
99 *
100 * Description:
101 * Minimizes memory alocation, trying to use already alocated memory
102 * in dst, freeing what is not required anymore.
103 */
104XmuArea *
105XmuAreaCopy(XmuArea *dst, XmuArea *src)
106{
107 XmuScanline *z, *p, *Z;
108
109 if (!dst || !src || dst == src)
110 return (dst);
111
112 z = p = dst->scanline;
113 Z = src->scanline;
114
115 /*CONSTCOND*/
116 while (1)
117 {
118 if (!Z)
119 {
120 if (z == dst->scanline)
121 {
122 XmuDestroyScanlineList(dst->scanline);
123 dst->scanline = (XmuScanline *)NULL((void*)0);
124 }
125 else
126 {
127 XmuDestroyScanlineList(p->next);
128 p->next = (XmuScanline *)NULL((void*)0);
129 }
130 return (dst);
131 }
132 if (z)
133 {
134 XmuScanlineCopy(z, Z);
135 z->y = Z->y;
136 }
137 else
138 {
139 z = XmuNewScanline(Z->y, 0, 0);
140 XmuScanlineCopy(z, Z);
141 if (p == dst->scanline && !dst->scanline)
142 p = dst->scanline = z;
143 else
144 p->next = z;
145 }
146 p = z;
147 z = z->next;
148 Z = Z->next;
149 }
150
151 return (dst);
152}
153
154/*
155 * Function:
156 * XmuAreaNot
157 *
158 * Parameters:
159 * area - area to operate
160 * x1 - retangle to clip the result against
161 * y1 - ""
162 * x2 - ""
163 * y2 - ""
164 *
165 * Description:
166 * (Input)
167 * (x1, y1) (x2, y1)
168 * +-------------+
169 * +------------+ +----+
170 * | +--------------+
171 * +----------------+
172 * (x1, y2) (x2, y2)
173 *
174 * (Output)
175 * (x1, y1) (x2, y1)
176 * +--------------+ +--------------------------+
177 * | +------------+ +----+ |
178 * | | +--------------+ |
179 * +-+ +------------------------------------+
180 * (x1, y2) (x2, y2)
181 */
182XmuArea *
183XmuAreaNot(XmuArea *area, int x1, int y1, int x2, int y2)
184{
185 XmuScanline *z;
186 XmuArea *and;
187
188 if (!area)
189 return (area);
190
191 if (x1 > x2)
192 {
193 x1 ^= x2; x2 ^= x1; x1 ^= x2;
194 }
195 if (y1 > y2)
196 {
197 y1 ^= y2; y2 ^= y1; y1 ^= y2;
198 }
199 if (!area->scanline)
200 {
201 if ((area->scanline = XmuNewScanline(y1, x1, x2)) != NULL((void*)0))
202 area->scanline->next = XmuNewScanline(y2, 0, 0);
203 return (area);
204 }
205 and = XmuNewArea(x1, y1, x2, y2);
206 XmuAreaAnd(area, and);
207 XmuDestroyArea(and)do { XmuDestroyScanlineList((and)->scanline); XtFree((char
*)(and)); } while (0)
;
208 z = area->scanline;
209 if (z->y != y1)
210 {
211 XmuScanline *q = XmuNewScanline(y1, x1, x2);
212 q->next = z;
213 area->scanline = q;
214 }
215 else
216 {
217 area->scanline = area->scanline->next;
218 XmuDestroyScanline(z)do { XmuDestroySegmentList((z)->segment); XtFree((char*)(z
)); } while (0)
;
219 XmuOptimizeArea(area);
220 if((z = area->scanline) == (XmuScanline *)NULL((void*)0))
221 return (area);
222 }
223
224 /* CONSTCOND */
225 while (1)
226 {
227 XmuScanlineNot(z, x1, x2);
228 if (!z->next)
229 {
230 z->next = XmuNewScanline(y2, 0, 0);
231 break;
232 }
233 if (z->next->y == y2)
234 {
235 XmuDestroyScanlineList(z->next);
236 z->next = XmuNewScanline(y2, 0, 0);
237 break;
238 }
239 z = z->next;
240 }
241
242 return (area);
243}
244
245/*
246 * Function:
247 * XmuAreaOrXor
248 *
249 * Parameters:
250 * dst - destination area
251 * src - source area
252 * or - or operation if true, else xor operation
253 *
254 * Description:
255 * Executes Or (Union) or Xor (Reverse intesection) of the areas
256 */
257XmuArea *
258XmuAreaOrXor(XmuArea *dst, XmuArea *src, Boolint or)
259{
260 XmuScanline *z, *p, *Z, *P, *ins, *top;
261
262 if (!dst || !src)
263 return (dst);
264
265 if (dst == src)
266 {
267 if (or)
268 return (dst);
269 XmuDestroyScanlineList(dst->scanline);
270 dst->scanline = (XmuScanline *)NULL((void*)0);
271 return (dst);
272 }
273 if (!XmuValidArea(src))
274 return (dst);
275 if (!XmuValidArea(dst))
276 {
277 XmuAreaCopy(dst, src);
278 return (dst);
279 }
280
281 p = z = dst->scanline;
282 P = Z = src->scanline;
283 ins = XmuNewScanline(dst->scanline->y, 0, 0);
284 top = XmuNewScanline(dst->scanline->y, 0, 0);
285 XmuScanlineCopy(ins, dst->scanline);
286 XmuScanlineCopy(top, dst->scanline);
287
288 /*CONSTCOND*/
289 while (1)
290 {
291 if (!Z)
292 break;
293 else if (Z->y < z->y)
294 {
295 XmuScanline *q = XmuNewScanline(Z->y, 0, 0);
296 XmuScanlineCopy(q, Z);
297
298 if (z == dst->scanline)
299 {
300 dst->scanline = p = q;
301 q->next = z;
302 }
303 else
304 {
305 p->next = q;
306 q->next = z;
307 if (Z->y >= p->y)
308 {
309 if (ins->y >= top->y
310 && (p->y != P->y || !XmuScanlineEqu(p, P)
311 || (ins->y <= P->y && !XmuScanlineEqu(ins, P))))
312 {
313 if (or)
314 XmuScanlineOr(q, ins);
315 else
316 XmuScanlineXor(q, ins);
317 }
318 else if (Z->y >= top->y
319 && (top->y == p->y || top->y > ins->y
320 || !XmuValidScanline(Z)
321 || (p->y == P->y && XmuValidScanline(p)
322 && XmuValidScanline(P))
323 || XmuScanlineEqu(ins, top)))
324 {
325 if (or)
326 XmuScanlineOr(q, top);
327 else
328 XmuScanlineXor(q, top);
329 }
330 if (ins->y != p->y && p->y != P->y)
331 {
332 XmuScanlineCopy(ins, p);
333 ins->y = p->y;
334 }
335 }
336 if (!XmuValidScanline(p) || Z->y <= p->y)
337 {
338 XmuScanlineCopy(top, p);
339 top->y = p->y;
340 }
341 p = q;
342 }
343 P = Z;
344 Z = Z->next;
345 continue;
346 }
347 else if (Z->y == z->y)
348 {
349 if (top->y != z->y)
350 {
351 XmuScanlineCopy(top, z);
352 top->y = z->y;
353 }
354 if (or)
355 XmuScanlineOr(z, Z);
356 else
357 XmuScanlineXor(z, Z);
358 P = Z;
359 Z = Z->next;
360 }
361 else if (P != Z) /* && Z->y > z->y */
362 {
363 if (top->y == ins->y && top->y != z->y)
364 {
365 XmuScanlineCopy(top, z);
366 top->y = z->y;
367 }
368 if (ins->y != z->y)
369 {
370 XmuScanlineCopy(ins, z);
371 ins->y = z->y;
372 }
373 if (or)
374 XmuScanlineOr(z, P);
375 else
376 XmuScanlineXor(z, P);
377 }
378 else if (ins->y != z->y)
379 {
380 XmuScanlineCopy(ins, z);
381 ins->y = z->y;
382 }
383 p = z;
384 z = z->next;
385 if (!z)
386 {
387 while (Z)
388 {
389 p->next = XmuNewScanline(Z->y, 0, 0);
390 XmuScanlineCopy(p->next, Z);
391 p = p->next;
392 Z = Z->next;
393 }
394 break;
395 }
396 else if (ins->y > top->y && !XmuValidScanline(z)
397 && XmuValidScanline(ins))
398 {
399 XmuScanlineCopy(top, ins);
400 top->y = ins->y;
401 }
402 }
403 XmuOptimizeArea(dst);
404 XmuDestroyScanline(ins)do { XmuDestroySegmentList((ins)->segment); XtFree((char*)
(ins)); } while (0)
;
405 XmuDestroyScanline(top)do { XmuDestroySegmentList((top)->segment); XtFree((char*)
(top)); } while (0)
;
406
407 return (dst);
408}
409
410/*
411 * Function:
412 * XmuAreaAnd(dst, src)
413 *
414 * Parameters:
415 * dst - destination area
416 * src - source area
417 *
418 * Description:
419 * Executes And (intersection) of the areas
420 */
421XmuArea *
422XmuAreaAnd(XmuArea *dst, XmuArea *src)
423{
424 XmuScanline *z, *p, *Z, *P, *top;
425
426 if (!dst || !src || dst == src)
427 return (dst);
428 if (!XmuValidArea(dst) || !XmuValidArea(src))
429 {
430 XmuDestroyScanlineList(dst->scanline);
431 dst->scanline = (XmuScanline *)NULL((void*)0);
432 return (dst);
433 }
434 z = p = dst->scanline;
435 Z = P = src->scanline;
436 top = XmuNewScanline(dst->scanline->y, 0, 0);
437 XmuScanlineCopy(top, dst->scanline);
438
439 while (z)
440 {
441 while (Z->next && Z->next->y < z->y)
442 {
443 P = Z;
444 Z = Z->next;
445 if (Z->y >= p->y)
446 {
447 XmuScanline *q = XmuNewScanline(Z->y, 0, 0);
448 XmuScanlineCopy(q, Z);
449
450 XmuScanlineAnd(q, top);
451 if (p->y != P->y)
452 {
453 XmuScanlineAnd(p, P);
454 p->y = XmuMax(p->y, P->y)((p->y) > (P->y) ? (p->y) : (P->y));
455 }
456 p->next = q;
457 q->next = z;
458 p = q;
459 }
460 }
461 if (!z->next)
462 {
463 z->y = XmuMax(z->y, Z->y)((z->y) > (Z->y) ? (z->y) : (Z->y));
464 break;
465 }
466 while (Z->y >= z->next->y)
467 {
468 if (z == dst->scanline)
469 {
470 p = dst->scanline = dst->scanline->next;
471 XmuDestroyScanline(z)do { XmuDestroySegmentList((z)->segment); XtFree((char*)(z
)); } while (0)
;
472 z = dst->scanline;
473 }
474 else
475 {
476 p->next = z->next;
477 XmuDestroyScanline(z)do { XmuDestroySegmentList((z)->segment); XtFree((char*)(z
)); } while (0)
;
478 z = p;
479 }
480 if (!z || !z->next)
481 {
482 XmuOptimizeArea(dst);
483 XmuDestroyScanline(top)do { XmuDestroySegmentList((top)->segment); XtFree((char*)
(top)); } while (0)
;
484
485 return (dst);
486 }
487 }
488 if (Z->y > p->y)
489 z->y = XmuMax(z->y, Z->y)((z->y) > (Z->y) ? (z->y) : (Z->y));
490 if (top->y != z->y)
491 {
492 XmuScanlineCopy(top, z);
493 top->y = z->y;
494 }
495 XmuScanlineAnd(z, Z);
496 p = z;
497 z = z->next;
498 }
499 XmuOptimizeArea(dst);
500 XmuDestroyScanline(top)do { XmuDestroySegmentList((top)->segment); XtFree((char*)
(top)); } while (0)
;
501
502 return (dst);
503}
504
505/*
506 * Function:
507 * XmuValidArea(area)
508 *
509 * Parameters:
510 * area - area to verify
511 *
512 * Description:
513 * Verifies if the area is valid and/or useful
514 */
515Boolint
516XmuValidArea(XmuArea *area)
517{
518 XmuScanline *at;
519
520 if (!area || !area->scanline)
521 return (False0);
522
523 at = area->scanline;
524 while (at)
525 {
526 if (XmuValidScanline(at))
527 return (True1);
528 at = at->next;
529 }
530
531 return (False0);
532}
533
534/*
535 * Function:
536 * XmuValidScanline
537 *
538 * Parameters:
539 * scanline - scanline to verify
540 *
541 * Description:
542 * Verifies if a scanline is useful
543 */
544Boolint
545XmuValidScanline(XmuScanline *scanline)
546{
547 XmuSegment *z;
548
549 if (!scanline)
550 return (False0);
551
552 z = scanline->segment;
553 while (z)
554 {
555 if (XmuValidSegment(z)((z)->x1 < (z)->x2))
556 return (True1);
557 z = z->next;
558 }
559
560 return (False0);
561}
562
563/*
564 * Function:
565 * XmuScanlineEqu
566 *
567 * Parameters:
568 * s1 - scanline 1
569 * s2 - scanline 2
570 *
571 * Description:
572 * Checks if s1 and s2 are equal
573 */
574Boolint
575XmuScanlineEqu(XmuScanline *s1, XmuScanline *s2)
576{
577 XmuSegment *z, *Z;
578
579 if ((!s1 && !s2) || s1 == s2)
580 return (True1);
581 if (!s1 || !s2)
582 return (False0);
583
584 z = s1->segment;
585 Z = s2->segment;
586
587 /*CONSTCOND*/
588 while (1)
589 {
590 if (!z && !Z)
591 return (True1);
592 if (!z || !Z)
593 return (False0);
594 if (!XmuSegmentEqu(z, Z)((z)->x1 == (Z)->x1 && (z)->x2 == (Z)->x2
)
)
595 return (False0);
596 z = z->next;
597 Z = Z->next;
598 }
599 /*NOTREACHED*/
600}
601
602/*
603 * Function:
604 * XmuNewSegment
605 *
606 * Parameters:
607 * x1 - coordinates of the segment
608 * x2 - ""
609 *
610 * Description:
611 * Creates a new segments with the coordinates x1 and x2
612 *
613 * Returns:
614 * New Segment of NULL
615 */
616XmuSegment *
617XmuNewSegment(int x1, int x2)
618{
619 XmuSegment *segment;
620
621 if ((segment = (XmuSegment *)XtMalloc(sizeof(XmuSegment))) == NULL((void*)0))
622 return (segment);
623
624 segment->x1 = x1;
625 segment->x2 = x2;
626 segment->next = (XmuSegment *)NULL((void*)0);
627
628 return (segment);
629}
630
631/*
632 * Function:
633 * XmuDestroySegmentList
634 *
635 * Parameters:
636 * segment - Segment to destroy
637 *
638 * Description:
639 * Frees the memory used by the list headed by segment
640 */
641void
642XmuDestroySegmentList(XmuSegment *segment)
643{
644 XmuSegment *z;
645
646 if (!segment)
647 return;
648
649 while (segment)
650 {
651 z = segment;
652 segment = segment->next;
653 XmuDestroySegment(z)XtFree((char *)(z));
654 }
655}
656
657/*
658 * Function:
659 * XmuScanlineCopy
660 *
661 * Parameters:
662 * dst - destination scanline
663 * src - source scanline
664 *
665 * Description:
666 * Makes dst contain the same data as src
667 */
668XmuScanline *
669XmuScanlineCopy(XmuScanline *dst, XmuScanline *src)
670{
671 XmuSegment *z, *p, *Z;
672
673 if (!dst || !src || dst == src)
674 return (dst);
675
676 z = p = dst->segment;
677 Z = src->segment;
678
679 /*CONSTCOND*/
680 while (1)
681 {
682 if (!Z)
683 {
684 if (z == dst->segment)
685 dst->segment = (XmuSegment *)NULL((void*)0);
686 else
687 p->next = (XmuSegment *)NULL((void*)0);
688 XmuDestroySegmentList(z);
689 return (dst);
690 }
691 if (z)
692 {
693 z->x1 = Z->x1;
694 z->x2 = Z->x2;
695 }
696 else
697 {
698 z = XmuNewSegment(Z->x1, Z->x2);
699 if (p == dst->segment && !dst->segment)
700 p = dst->segment = z;
Value stored to 'p' is never read
701 else
702 p->next = z;
703 }
704 p = z;
705 z = z->next;
706 Z = Z->next;
707 }
708 /*NOTREACHED*/
709}
710
711/*
712 * Function:
713 * XmuAppendSegment
714 *
715 * Parameters:
716 * segment - destination segment
717 * append - segment to add
718 *
719 * Description:
720 * Adds a copy of the append list at the end of the segment list
721 */
722Boolint
723XmuAppendSegment(XmuSegment *segment, XmuSegment *append)
724{
725 if (!segment || !append)
726 return (False0);
727
728 if (segment->next)
729 /* Should not happen! */
730 XmuDestroySegmentList(segment->next);
731
732 while (append)
733 {
734 if (XmuValidSegment(append)((append)->x1 < (append)->x2))
735 {
736 if ((segment->next = XmuNewSegment(append->x1, append->x2)) == NULL((void*)0))
737 return (False0);
738 segment = segment->next;
739 }
740 append = append->next;
741 }
742
743 return (True1);
744}
745
746/*
747 * Function:
748 * XmuOptimizeScanline
749 *
750 * Parameters:
751 * scanline - scanline to optimize
752 *
753 * Description:
754 * Some functions, when transforming Segments of Scanlines, left these
755 * with unnecessary data (that may cause error in these same functions).
756 * This function corrects these incorrect segments.
757 */
758XmuScanline *
759XmuOptimizeScanline(XmuScanline *scanline)
760{
761 XmuSegment *z, *p;
762
763 while (scanline->segment && !XmuValidSegment(scanline->segment)((scanline->segment)->x1 < (scanline->segment)->
x2)
)
764 {
765 XmuSegment *s = scanline->segment;
766
767 scanline->segment = scanline->segment->next;
768 XmuDestroySegment(s)XtFree((char *)(s));
769 }
770 for (z = p = scanline->segment; z; p = z, z = z->next)
771 {
772 if (!XmuValidSegment(z)((z)->x1 < (z)->x2))
773 {
774 p->next = z->next;
775 XmuDestroySegment(z)XtFree((char *)(z));
776 z = p;
777 }
778 }
779 return (scanline);
780}
781
782/*
783 * Name:
784 * XmuScanlineNot(scanline, minx, maxx)
785 *
786 * Parameters:
787 * scanline - scanlines operate
788 * minx - minimum x coordinate
789 * maxx - maximum x coordinate
790 *
791 * Description:
792 * (minx) (maxx)
793 * + +
794 * (input) +---------+ +--------+ +--------+
795 * (output) +-----+ +-----+ +--------+ +------------+
796 */
797XmuScanline *
798XmuScanlineNot(XmuScanline *scanline, int minx, int maxx)
799{
800 XmuSegment *z;
801 static XmuSegment x = { 0, 0, NULL((void*)0) };
802 static XmuScanline and = { 0, &x, NULL((void*)0) };
803
804 if (!scanline)
805 return (scanline);
806
807 XmuOptimizeScanline(scanline);
808 if (minx > maxx)
809 {
810 minx ^= maxx; maxx ^= minx; minx ^= maxx;
811 }
812 and.segment->x1 = minx;
813 and.segment->x2 = maxx;
814 XmuScanlineAnd(scanline, &and);
815 if (!scanline->segment)
816 {
817 scanline->segment = XmuNewSegment(minx, maxx);
818 return (scanline);
819 }
820 z = scanline->segment;
821 if (z->x1 != minx)
822 {
823 XmuSegment *q = XmuNewSegment(minx, z->x1);
824
825 q->next = z;
826 scanline->segment = q;
827 }
828
829 /*CONSTCOND*/
830 while (1)
831 {
832 z->x1 = z->x2;
833 if (!z->next)
834 {
835 z->x2 = maxx;
836 break;
837 }
838 z->x2 = z->next->x1;
839 if (z->next->x2 == maxx)
840 {
841 XmuDestroySegment(z->next)XtFree((char *)(z->next));
842 z->next = (XmuSegment *)NULL((void*)0);
843 break;
844 }
845 z = z->next;
846 }
847
848 return (scanline);
849}
850
851
852#ifndef notdef
853/*
854 * Function:
855 * XmuScanlineOrSegment
856 *
857 * Parameters:
858 * dst - destionation scanline
859 * src - source segment
860 *
861 * Description:
862 * (input) +-----------+ +--------+ +---------+
863 * (src) +-------------------+
864 * (output) +-------------------------+ +---------+
865 */
866XmuScanline *
867XmuScanlineOrSegment(XmuScanline *dst, XmuSegment *src)
868{
869 XmuSegment *z, *p, ins;
870
871 if (!src || !dst || !XmuValidSegment(src)((src)->x1 < (src)->x2))
872 return (dst);
873
874 if (!dst->segment)
875 {
876 dst->segment = XmuNewSegment(src->x1, src->x2);
877 return (dst);
878 }
879
880 z = p = dst->segment;
881 ins.x1 = src->x1;
882 ins.x2 = src->x2;
883
884 /*CONSTCOND*/
885 while (1)
886 {
887 if (!z)
888 {
889 XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
890
891 if (p == dst->segment && z == p)
892 dst->segment = q;
893 else
894 p->next = q;
895 break;
896 }
897 else if (ins.x2 < z->x1)
898 {
899 XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
900
901 if (p == dst->segment && z == p)
902 {
903 q->next = dst->segment;
904 dst->segment = q;
905 }
906 else
907 {
908 p->next = q;
909 q->next = z;
910 }
911 break;
912 }
913 else if (ins.x2 <= z->x2)
914 {
915 z->x1 = XmuMin(z->x1, ins.x1)((z->x1) < (ins.x1) ? (z->x1) : (ins.x1));
916 break;
917 }
918 else if (ins.x1 <= z->x2)
919 {
920 ins.x1 = XmuMin(z->x1, ins.x1)((z->x1) < (ins.x1) ? (z->x1) : (ins.x1));
921 if (!z->next)
922 {
923 z->x1 = ins.x1;
924 z->x2 = ins.x2;
925 break;
926 }
927 else
928 {
929 if (z == dst->segment)
930 {
931 p = dst->segment = dst->segment->next;
932 XmuDestroySegment(z)XtFree((char *)(z));
933 z = dst->segment;
934 continue;
935 }
936 else
937 {
938 p->next = z->next;
939 XmuDestroySegment(z)XtFree((char *)(z));
940 z = p;
941 }
942 }
943 }
944 p = z;
945 z = z->next;
946 }
947
948 return (dst);
949}
950
951/*
952 * Function:
953 * XmuScanlineAndSegment
954 *
955 * Parameters:
956 * dst - destination scanline
957 * src - source segment
958 *
959 * Description:
960 * (input) +------------+ +------+ +----------+
961 * (src) +---------------------+
962 * (output) +-------+ +------+
963 */
964XmuScanline *
965XmuScanlineAndSegment(XmuScanline *dst, XmuSegment *src)
966{
967 XmuSegment *z, *p;
968
969 if (!dst || !src)
970 return (dst);
971
972 if (!XmuValidSegment(src)((src)->x1 < (src)->x2))
973 {
974 XmuDestroySegmentList(dst->segment);
975 dst->segment = (XmuSegment *)NULL((void*)0);
976 return (dst);
977 }
978 if (!dst->segment)
979 return (dst);
980
981 z = p = dst->segment;
982 while (z)
983 {
984 if (src->x2 <= z->x1 || src->x1 >= z->x2)
985 {
986 if (z == dst->segment)
987 {
988 p = dst->segment = dst->segment->next;
989 XmuDestroySegment(z)XtFree((char *)(z));
990 z = dst->segment;
991 continue;
992 }
993 else
994 {
995 p->next = z->next;
996 XmuDestroySegment(z)XtFree((char *)(z));
997 z = p;
998 }
999 }
1000 else
1001 {
1002 z->x1 = XmuMax(z->x1, src->x1)((z->x1) > (src->x1) ? (z->x1) : (src->x1));
1003 z->x2 = XmuMin(z->x2, src->x2)((z->x2) < (src->x2) ? (z->x2) : (src->x2));
1004 }
1005 p = z;
1006 z = z->next;
1007 }
1008
1009 return (dst);
1010}
1011
1012/*
1013 * Function:
1014 * XmuScanlineXorSegment
1015 *
1016 * Parameters:
1017 * dst - destionation scanline
1018 * src - source segment
1019 *
1020 * Descriptipn:
1021 * (input) +------------+ +----------+ +-----------+
1022 * (src) +------------------------+
1023 * (output) +---+ +--+ +-+ +-----------+
1024 */
1025XmuScanline *
1026XmuScanlineXorSegment(XmuScanline *dst, XmuSegment *src)
1027{
1028 XmuSegment *p, *z, ins;
1029 int tmp1, tmp2;
1030
1031 if (!dst || !src || !XmuValidSegment(src)((src)->x1 < (src)->x2))
1032 return (dst);
1033 if (!dst->segment)
1034 {
1035 dst->segment = XmuNewSegment(src->x1, src->x2);
1036 return (dst);
1037 }
1038
1039 p = z = dst->segment;
1040 ins.x1 = src->x1;
1041 ins.x2 = src->x2;
1042
1043 /*CONSTCOND*/
1044 while (1)
1045 {
1046 if (!XmuValidSegment((&ins))(((&ins))->x1 < ((&ins))->x2))
1047 break;
1048 if (!z || ins.x2 < z->x1)
1049 {
1050 XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
1051
1052 q->next = z;
1053 if (z == dst->segment)
1054 dst->segment = q;
1055 else
1056 p->next = q;
1057 break;
1058 }
1059 else if (ins.x2 == z->x1)
1060 {
1061 z->x1 = ins.x1;
1062 break;
1063 }
1064 else if (ins.x1 < z->x2)
1065 {
1066 if (ins.x1 < z->x1)
1067 {
1068 tmp1 = ins.x2;
1069 tmp2 = z->x2;
1070 ins.x2 = XmuMax(ins.x2, z->x2)((ins.x2) > (z->x2) ? (ins.x2) : (z->x2));
1071 z->x2 = z->x1;
1072 z->x1 = ins.x1;
1073 ins.x1 = XmuMin(tmp1, tmp2)((tmp1) < (tmp2) ? (tmp1) : (tmp2));
1074 }
1075 else if (ins.x1 > z->x1)
1076 {
1077 tmp1 = ins.x1;
1078 ins.x1 = XmuMin(ins.x2, z->x2)((ins.x2) < (z->x2) ? (ins.x2) : (z->x2));
1079 ins.x2 = XmuMax(z->x2, ins.x2)((z->x2) > (ins.x2) ? (z->x2) : (ins.x2));
1080 z->x2 = tmp1;
1081 }
1082 else /* ins.x1 == z->x1 */
1083 {
1084 if (ins.x2 < z->x2)
1085 {
1086 z->x1 = ins.x2;
1087 break;
1088 }
1089 else
1090 {
1091 ins.x1 = z->x2;
1092 if (z == dst->segment)
1093 p = dst->segment = dst->segment->next;
1094 else
1095 p->next = z->next;
1096 XmuDestroySegment(z)XtFree((char *)(z));
1097 z = p;
1098 continue;
1099 }
1100 }
1101 }
1102 else if (ins.x1 == z->x2)
1103 {
1104 ins.x1 = z->x1;
1105 if (z == dst->segment)
1106 p = dst->segment = dst->segment->next;
1107 else
1108 p->next = z->next;
1109 XmuDestroySegment(z)XtFree((char *)(z));
1110 z = p;
1111 continue;
1112 }
1113 p = z;
1114 z = z->next;
1115 }
1116
1117 return (dst);
1118}
1119#endif /* notdef */
1120
1121/*
1122 * Function:
1123 * ScanlineOr
1124 *
1125 * Parameters:
1126 * dst - destionation scanline
1127 * src - source scanline
1128 *
1129 * Description:
1130 * (input) +--------------+ +-----+ +----------+
1131 * (src) +---------------------+ +-----------+
1132 * (output) +-------------------------+ +----------------+
1133 */
1134XmuScanline *
1135XmuScanlineOr(XmuScanline *dst, XmuScanline *src)
1136{
1137 XmuSegment *z, *p, *Z, ins;
1138
1139 if (!src || !src->segment || !dst || dst == src)
1140 return (dst);
1141 if (!dst->segment)
1142 {
1143 XmuScanlineCopy(dst, src);
1144 return (dst);
1145 }
1146
1147 z = p = dst->segment;
1148 Z = src->segment;
1149 ins.x1 = Z->x1;
1150 ins.x2 = Z->x2;
1151
1152 /*CONSTCOND*/
1153 while (1)
1154 {
1155 while (!XmuValidSegment((&ins))(((&ins))->x1 < ((&ins))->x2))
1156 {
1157 if ((Z = Z->next) == (XmuSegment *)NULL((void*)0))
1158 return (dst);
1159 ins.x1 = Z->x1;
1160 ins.x2 = Z->x2;
1161 }
1162 if (!z)
1163 {
1164 XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
1165
1166 if (p == dst->segment && z == p)
1167 dst->segment = p = q;
1168 else
1169 {
1170 p->next = q;
1171 p = q;
1172 }
1173 Z = Z->next;
1174 XmuAppendSegment(p, Z);
1175 break;
1176 }
1177 else if (ins.x2 < z->x1)
1178 {
1179 XmuSegment *r = XmuNewSegment(ins.x1, ins.x2);
1180
1181 if (p == dst->segment && z == p)
1182 {
1183 r->next = dst->segment;
1184 dst->segment = p = r;
1185 }
1186 else
1187 {
1188 p->next = r;
1189 r->next = z;
1190 p = r;
1191 }
1192 Z = Z->next;
1193 if (!Z)
1194 break;
1195 else
1196 {
1197 ins.x1 = Z->x1;
1198 ins.x2 = Z->x2;
1199 continue;
1200 }
1201 }
1202 else if (ins.x2 <= z->x2)
1203 {
1204 z->x1 = XmuMin(z->x1, ins.x1)((z->x1) < (ins.x1) ? (z->x1) : (ins.x1));
1205 Z = Z->next;
1206 if (!Z)
1207 break;
1208 else
1209 {
1210 ins.x1 = Z->x1;
1211 ins.x2 = Z->x2;
1212 continue;
1213 }
1214 }
1215 else if (ins.x1 <= z->x2)
1216 {
1217 ins.x1 = XmuMin(z->x1, ins.x1)((z->x1) < (ins.x1) ? (z->x1) : (ins.x1));
1218 if (!z->next)
1219 {
1220 z->x1 = ins.x1;
1221 z->x2 = ins.x2;
1222 p = z;
1223 Z = Z->next;
1224 XmuAppendSegment(p, Z);
1225 break;
1226 }
1227 else
1228 {
1229 if (z == dst->segment)
1230 {
1231 p = dst->segment = dst->segment->next;
1232 XmuDestroySegment(z)XtFree((char *)(z));
1233 z = p;
1234 continue;
1235 }
1236 else
1237 {
1238 p->next = z->next;
1239 XmuDestroySegment(z)XtFree((char *)(z));
1240 z = p;
1241 }
1242 }
1243 }
1244 p = z;
1245 z = z->next;
1246 }
1247
1248 return (dst);
1249}
1250
1251/*
1252 * Function:
1253 * XmuScanlineAnd
1254 *
1255 * Parameters:
1256 * dst - destination scanline
1257 * src - source scanline
1258 *
1259 * Description:
1260 * (input) +--------------+ +-----+ +----------+
1261 * (src) +---------------------+ +-----------+
1262 * (output) +----------+ +-----+ +-----+
1263 */
1264XmuScanline *
1265XmuScanlineAnd(XmuScanline *dst, XmuScanline *src)
1266{
1267 XmuSegment *z, *p, *Z;
1268
1269 if (!dst || !src || dst == src || !dst->segment) {
1270 return (dst);
1271 }
1272 if (!src->segment)
1273 {
1274 XmuDestroySegmentList(dst->segment);
1275 dst->segment = (XmuSegment *)NULL((void*)0);
1276 return (dst);
1277 }
1278 z = p = dst->segment;
1279 Z = src->segment;
1280
1281 while (z)
1282 {
1283 while (!XmuValidSegment(Z)((Z)->x1 < (Z)->x2) || Z->x2 <= z->x1)
1284 {
1285 Z = Z->next;
1286 if (!Z)
1287 {
1288 if (z == dst->segment)
1289 dst->segment = (XmuSegment *)NULL((void*)0);
1290 else
1291 p->next = (XmuSegment *)0;
1292 XmuDestroySegmentList(z);
1293 return (dst);
1294 }
1295 }
1296 if (Z->x1 >= z->x2)
1297 {
1298 if (z == dst->segment)
1299 {
1300 p = dst->segment = dst->segment->next;
1301 XmuDestroySegment(z)XtFree((char *)(z));
1302 z = dst->segment;
1303 }
1304 else
1305 {
1306 p->next = z->next;
1307 XmuDestroySegment(z)XtFree((char *)(z));
1308 z = p->next;
1309 }
1310 if (!z)
1311 return (dst);
1312 else
1313 continue;
1314 }
1315 z->x1 = XmuMax(z->x1, Z->x1)((z->x1) > (Z->x1) ? (z->x1) : (Z->x1));
1316 if (z->x2 > Z->x2)
1317 {
1318 if (Z->next)
1319 {
1320 XmuSegment *q = XmuNewSegment(Z->x2, z->x2);
1321
1322 q->next = z->next;
1323 z->next = q;
1324 }
1325 z->x2 = Z->x2;
1326 }
1327 p = z;
1328 z = z->next;
1329 }
1330
1331 return (dst);
1332}
1333
1334/*
1335 * Function:
1336 * ScanlineXor
1337 *
1338 * Parameters:
1339 * dst - destination scanline
1340 * src - source scanline
1341 *
1342 * Description:
1343 * (input) +--------------+ +-----+ +----------+
1344 * (src) +---------------------+ +-----------+
1345 * (output) +---+ +--+ +-+ +----+ +-----+
1346 */
1347XmuScanline *
1348XmuScanlineXor(XmuScanline *dst, XmuScanline *src)
1349{
1350 XmuSegment *z, *p, *Z, ins;
1351 int tmp1, tmp2;
1352
1353 if (!src || !dst || !src->segment)
1354 return (dst);
1355 if (src == dst)
1356 {
1357 XmuDestroySegmentList(dst->segment);
1358 dst->segment = (XmuSegment *)NULL((void*)0);
1359 return (dst);
1360 }
1361 if (!dst->segment)
1362 {
1363 XmuScanlineCopy(dst, src);
1364 return (dst);
1365 }
1366
1367 z = p = dst->segment;
1368 Z = src->segment;
1369 ins.x1 = Z->x1;
1370 ins.x2 = Z->x2;
1371
1372 /*CONSTCOND*/
1373 while (1)
1374 {
1375 while (!XmuValidSegment((&ins))(((&ins))->x1 < ((&ins))->x2))
1376 {
1377 if ((Z = Z->next) == (XmuSegment *)NULL((void*)0))
1378 return (dst);
1379 ins.x1 = Z->x1;
1380 ins.x2 = Z->x2;
1381 }
1382 if (!z)
1383 {
1384 XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
1385
1386 if (!dst->segment)
1387 dst->segment = q;
1388 else
1389 p->next = q;
1390 p = q;
1391 Z = Z->next;
1392 XmuAppendSegment(p, Z);
1393 break;
1394 }
1395 else if (ins.x2 < z->x1)
1396 {
1397 XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
1398
1399 q->next = z;
1400 if (z == dst->segment)
1401 dst->segment = q;
1402 else
1403 p->next = q;
1404 if ((Z = Z->next) == (XmuSegment *)NULL((void*)0))
1405 return (dst);
1406
1407 p = q;
1408 ins.x1 = Z->x1;
1409 ins.x2 = Z->x2;
1410 continue;
1411 }
1412 else if (ins.x2 == z->x1)
1413 {
1414 z->x1 = ins.x1;
1415 if ((Z = Z->next) == (XmuSegment *)NULL((void*)0))
1416 break;
1417 ins.x1 = Z->x1;
1418 ins.x2 = Z->x2;
1419 continue;
1420 }
1421 else if (ins.x1 < z->x2)
1422 {
1423 if (ins.x1 == z->x1)
1424 {
1425 if (ins.x2 < z->x2)
1426 {
1427 z->x1 = ins.x2;
1428 if ((Z = Z->next) == (XmuSegment *)NULL((void*)0))
1429 break;
1430 ins.x1 = Z->x1;
1431 ins.x2 = Z->x2;
1432 continue;
1433 }
1434 else
1435 {
1436 ins.x1 = z->x2;
1437 if (z == dst->segment)
1438 p = dst->segment = dst->segment->next;
1439 else
1440 p->next = z->next;
1441 XmuDestroySegment(z)XtFree((char *)(z));
1442 z = p;
1443 continue;
1444 }
1445 }
1446 else
1447 {
1448 if (Z->x2 < z->x2)
1449 {
1450 XmuSegment *q = XmuNewSegment(XmuMin(ins.x1, z->x1)((ins.x1) < (z->x1) ? (ins.x1) : (z->x1)),
1451 XmuMax(z->x1, ins.x1)((z->x1) > (ins.x1) ? (z->x1) : (ins.x1)));
1452
1453 q->next = z;
1454 if (z == dst->segment)
1455 dst->segment = q;
1456 else
1457 p->next = q;
1458 ins.x1 = z->x2;
1459 z->x1 = ins.x2;
1460 p = q;
1461 continue;
1462 }
1463 else
1464 {
1465 tmp1 = ins.x2;
1466 tmp2 = z->x2;
1467 ins.x2 = XmuMax(ins.x2, z->x2)((ins.x2) > (z->x2) ? (ins.x2) : (z->x2));
1468 z->x2 = XmuMax(z->x1, ins.x1)((z->x1) > (ins.x1) ? (z->x1) : (ins.x1));
1469 z->x1 = XmuMin(ins.x1, z->x1)((ins.x1) < (z->x1) ? (ins.x1) : (z->x1));
1470 ins.x1 = XmuMin(tmp1, tmp2)((tmp1) < (tmp2) ? (tmp1) : (tmp2));
1471 }
1472 }
1473 }
1474 else if (ins.x1 == z->x2)
1475 {
1476 ins.x1 = z->x1;
1477 if (z == dst->segment)
1478 p = dst->segment = dst->segment->next;
1479 else
1480 p->next = z->next;
1481 XmuDestroySegment(z)XtFree((char *)(z));
1482 z = p;
1483 continue;
1484 }
1485 p = z;
1486 z = z->next;
1487 }
1488
1489 return (dst);
1490}
1491
1492/*
1493 * Function:
1494 * XmuNewScanline
1495 *
1496 * Parameters:
1497 * y - y coordinate
1498 * x1 - left coordinate
1499 * x2 - right coordinate
1500 *
1501 * Description:
1502 * Creates a new Scanline
1503 */
1504XmuScanline *
1505XmuNewScanline(int y, int x1, int x2)
1506{
1507 XmuScanline *scanline;
1508
1509 scanline = (XmuScanline *)XtMalloc(sizeof(XmuScanline));
1510 scanline->y = y;
1511 if (x1 < x2)
1512 scanline->segment = XmuNewSegment(x1, x2);
1513 else
1514 scanline->segment = (XmuSegment *)NULL((void*)0);
1515
1516 scanline->next = (XmuScanline *)NULL((void*)0);
1517
1518 return (scanline);
1519}
1520
1521/*
1522 * Function:
1523 * XmuDestroyScanlineList
1524 *
1525 * Parameters:
1526 * scanline - scanline list to destroy
1527 *
1528 * Description:
1529 * Destroy a scanline list
1530 *
1531 * Observation:
1532 * Use as follow:
1533 * XmuDestroyScanlineList(area->scanline);
1534 * area->scanline = (XmuScanline *)NULL;
1535 */
1536void
1537XmuDestroyScanlineList(XmuScanline *scanline)
1538{
1539 XmuScanline *z;
1540
1541 if (!scanline)
1542 return;
1543
1544 while (scanline)
1545 {
1546 z = scanline;
1547 scanline = scanline->next;
1548 XmuDestroyScanline(z)do { XmuDestroySegmentList((z)->segment); XtFree((char*)(z
)); } while (0)
;
1549 }
1550}
1551
1552/*
1553 * Function:
1554 * XmuOptimizeArea
1555 *
1556 * Parameters:
1557 * area - area to optimize
1558 *
1559 * Description:
1560 * Optimizes an area. This function is called when finishing a
1561 * operation between areas, since they can end with redundant data,
1562 * and the algorithms for area combination waits a area with
1563 * correct data (but can left unnecessary data in the area, to avoid
1564 * to much paranoia tests).
1565 */
1566XmuArea *XmuOptimizeArea(XmuArea *area)
1567{
1568 XmuScanline *pr, *at;
1569
1570 if (!area || !area->scanline)
1571 return (area);
1572
1573 if (!area->scanline->next)
1574 {
1575 XmuDestroyScanlineList(area->scanline);
1576 area->scanline = (XmuScanline *)0;
1577 return (area);
1578 }
1579
1580 pr = area->scanline;
1581 at = area->scanline->next;
1582 while (area->scanline && (!XmuValidScanline(area->scanline)
1583 || (area->scanline->next && area->scanline->y
1584 >= area->scanline->next->y)))
1585 {
1586 area->scanline = area->scanline->next;
1587 XmuDestroyScanline(pr)do { XmuDestroySegmentList((pr)->segment); XtFree((char*)(
pr)); } while (0)
;
1588 pr = area->scanline;
1589 if (pr)
1590 at = pr->next;
1591 }
1592
1593 for (; at; pr = at, at = at->next)
1594 {
1595 if (XmuScanlineEqu(at, pr)
1596 || (!XmuValidScanline(at) && !XmuValidScanline(pr))
1597 || (at->next && at->y >= at->next->y))
1598 {
1599 pr->next = at->next;
1600 XmuDestroyScanline(at)do { XmuDestroySegmentList((at)->segment); XtFree((char*)(
at)); } while (0)
;
1601 at = pr;
1602 }
1603 }
1604 if (pr && XmuValidScanline(pr))
1605 {
1606 XmuDestroySegmentList(pr->segment);
1607 pr->segment = (XmuSegment *)NULL((void*)0);
1608 }
1609 if (area->scanline && !area->scanline->next)
1610 {
1611 XmuDestroyScanlineList(area->scanline);
1612 area->scanline = (XmuScanline *)NULL((void*)0);
1613 }
1614
1615 return (area);
1616}