~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to grid/cutbox.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <grid.h>
 
2
 
 
3
#ifdef DMALLOC
 
4
#include "dmalloc.h"
 
5
#endif
 
6
 
 
7
        /* utility fn for cut_tile */
 
8
static void ERmovesegs(ERview_t *D, Tile_t *old, Tile_t *new, Dir_t side)
 
9
{
 
10
        Seglist_t       *seglist;
 
11
        Seg_t           *seg;
 
12
        int                     i;
 
13
 
 
14
        seglist = old->segs[side];
 
15
        for (i = 0; (seg = seglist->list[i]); i++) {
 
16
                if (seg->b[0] == old) seg->b[0] = new;
 
17
                else if (seg->b[1] == old) seg->b[1] = new;
 
18
                else abort();
 
19
                ERseglist_append(D,new->segs[side],seg);
 
20
                seglist->list[i] = NIL(Seg_t*);
 
21
        }
 
22
        old->segs[side]->size = 0;
 
23
}
 
24
 
 
25
        /* utility fn for cut_tile */
 
26
static void ERsortsegs(ERview_t *D, Tile_t *old, Tile_t *b0, Tile_t *b1, Dir_t side)
 
27
{
 
28
        Tile_t          *nb,*ob;
 
29
        Seglist_t       *seglist,*s0,*s1;
 
30
        Seg_t           *seg;
 
31
        int                     i,c;
 
32
 
 
33
        seglist = old->segs[side];
 
34
        s0 = b0->segs[side]; s1 = b1->segs[side];
 
35
        if ((side == north) || (side == south)) c = 0; else c = 1;
 
36
        for (i = 0; (seg = seglist->list[i]); i++) {
 
37
                if (seg->p[1].c[c] <= b0->UR.c[c]) {ERseglist_append(D,s0,seg); nb=b0;}
 
38
                else if (seg->p[0].c[c] >= b1->LL.c[c]) {ERseglist_append(D,s1,seg);nb=b1;}
 
39
                else {
 
40
                        assert(NONDECREASING(seg->p[0].c[c],b0->UR.c[c],seg->p[1].c[c]));
 
41
                        if (seg->b[0] != old) ob = seg->b[0]; else ob = seg->b[1];
 
42
                        ERseglist_delete(ob->segs[opposite(side)],seg);
 
43
                        /*install_new_seg(seg->p[0],b0->UR,seg->kind,b0,side,ob);
 
44
                        ERinstall_new_seg(D,b1->LL,seg->p[1],seg->kind,b1,side,ob);*/
 
45
 
 
46
                        ERinstall_new_seg(D,seg->p[0],ERcombine(seg->p[0],b0->UR,(ilbool)c),
 
47
                                seg->kind,b0,side,ob);
 
48
                        ERinstall_new_seg(D,ERcombine(seg->p[1],b1->LL,(ilbool)c),seg->p[1],
 
49
                                seg->kind,b1,side,ob);
 
50
 
 
51
                        ERfree_seg(D,seg);
 
52
                        continue;
 
53
                }
 
54
                if (seg->b[0] == old) seg->b[0] = nb;
 
55
                else seg->b[1] = nb;
 
56
 
 
57
                seglist->list[i] = NIL(Seg_t*);
 
58
        }
 
59
        seglist->size = 0;
 
60
}
 
61
 
 
62
 
 
63
/* slice a box in two.  destroys old box.  sub-boxes are installed
 
64
 * in the diagram with the new segment lists.  try to re-use old segs.
 
65
 */
 
66
void ERcut_tile(ERview_t *D, Tile_t *b, ilbool horizontal, Pt_t p)
 
67
{
 
68
        Pt_t    p0,p1;
 
69
        Tile_t  *b0,*b1;
 
70
        Dir_t   lowside;
 
71
 
 
72
        if (horizontal) {
 
73
                p0 = ERmkpoint(x(b->LL),y(p));
 
74
                p1 = ERmkpoint(x(b->UR),y(p));
 
75
                lowside = north;
 
76
        }
 
77
        else {
 
78
                p0 = ERmkpoint(x(p),y(b->LL));
 
79
                p1 = ERmkpoint(x(p),y(b->UR));
 
80
                lowside = east;
 
81
        }
 
82
        b0 = ERtile(D,b->LL,p1);
 
83
        b1 = ERtile(D,p0,b->UR);
 
84
        ERinstall_new_seg(D,p0, p1, s_plain, b0, lowside, b1);
 
85
        ERmovesegs(D,b,b0,opposite(lowside));
 
86
        ERmovesegs(D,b,b1,lowside);
 
87
        ERsortsegs(D,b,b0,b1,(lowside+1)%NSIDES);
 
88
        ERsortsegs(D,b,b0,b1,(lowside+3)%NSIDES);
 
89
        ERtileset_delete(D->config,b);
 
90
        ERtileset_append(D,D->config,b0);
 
91
        ERtileset_append(D,D->config,b1);
 
92
        ERfree_tile(D,b);
 
93
}
 
94
 
 
95
static ilbool tile_in_set(Tile_t *b, Tileset_t *set)
 
96
{
 
97
        int             i;
 
98
        Tile_t  *cb;
 
99
 
 
100
        for (i = 0; (cb = set->list[i]); i++)
 
101
                if (cb == b) return TRUE;
 
102
        return FALSE;
 
103
}
 
104
 
 
105
static ilbool seg_in_list(Seg_t *seg, Seglist_t *set)
 
106
{
 
107
        int             i;
 
108
        Seg_t   *cseg;
 
109
 
 
110
        for (i = 0; (cseg = set->list[i]); i++)
 
111
                if (cseg == seg) return TRUE;
 
112
        return FALSE;
 
113
}
 
114
 
 
115
 
 
116
static void erchecksegs(ERview_t *d)
 
117
{
 
118
        int             i,j,side;
 
119
        Tile_t  *b;
 
120
        Seg_t   *seg;
 
121
 
 
122
        for (i = 0; (b = d->config->list[i]); i++) {
 
123
                for (side = 0; side < NSIDES; side++) {
 
124
                        for (j = 0; (seg = b->segs[side]->list[j]); j++) {
 
125
                                if (seg->b[0] == b) {
 
126
                                        assert(seg->b[1] != b);
 
127
                                        assert(tile_in_set(seg->b[1],d->config));
 
128
                                        assert(seg_in_list(seg,seg->b[1]->segs[opposite(side)]));
 
129
                                }
 
130
                                else if (seg->b[1] == b) {
 
131
                                        assert(seg->b[0] != b);
 
132
                                        assert(tile_in_set(seg->b[0],d->config));
 
133
                                        assert(seg_in_list(seg,seg->b[0]->segs[opposite(side)]));
 
134
                                }
 
135
                                else abort();
 
136
                        }
 
137
                }
 
138
        }
 
139
}
 
140
 
 
141
        /* split the configuration by a given line segment */
 
142
void ERsplit_config(ERview_t *D, Pt_t p, Pt_t q)
 
143
{
 
144
        Tile_t  *this_b, *last_b,  *prev_b, *next_b;
 
145
        int             c,d;
 
146
 
 
147
        if (pt_eq(p,q)) return;
 
148
 
 
149
        if (y(p) == y(q)) {c = 0; d = 1;} else {c = 1; d = 0;}
 
150
        if (p.c[c] > q.c[c]) {Pt_t tmp; tmp = p; p = q; q = tmp;}
 
151
 
 
152
        this_b = ERlocate(D,p);
 
153
        last_b = ERlocate(D,q);
 
154
 
 
155
        do  {
 
156
                next_b = ERneighbor(this_b, q);
 
157
                        /* need nondegenerate intersection */
 
158
                if ((p.c[c] < this_b->UR.c[c]) && (q.c[c] > this_b->LL.c[c])) {
 
159
                        if ((this_b->LL.c[d] < p.c[d]) && (p.c[d] < this_b->UR.c[d]))
 
160
                                ERcut_tile(D, this_b, (ilbool)d, p);
 
161
                }
 
162
                prev_b = this_b;
 
163
                this_b = next_b;
 
164
erchecksegs(D);
 
165
        } while ((prev_b != last_b) && (prev_b != this_b));
 
166
}