OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [nanox/] [srvclip1.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
 * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
3
 * Copyright (c) 1991 David I. Bell
4
 * Permission is granted to use, distribute, or modify this source,
5
 * provided that this copyright notice remains intact.
6
 */
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include "serv.h"
10
 
11
/*
12
 * Macro to distinguish cases of clipping.
13
 */
14
#define GAPVAL(leftgap, rightgap, topgap, bottomgap) \
15
        (((leftgap) << 3) + ((rightgap) << 2) + ((topgap) << 1) + (bottomgap))
16
 
17
static GR_COUNT GsSplitClipRect(MWCLIPRECT *srcrect, MWCLIPRECT *destrect,
18
                        GR_COORD minx, GR_COORD miny, GR_COORD maxx,
19
                        GR_COORD maxy);
20
/*
21
 * Set the clip rectangles for a window taking into account other
22
 * windows that may be obscuring it.  The windows that may be obscuring
23
 * this one are the siblings of each direct ancestor which are higher
24
 * in priority than those ancestors.  Also, each parent limits the visible
25
 * area of the window.  The clipping is not done if it is already up to
26
 * date of if the window is not outputtable.
27
 */
28
void
29
GsSetClipWindow(GR_WINDOW *wp, MWCLIPREGION *userregion, int flags)
30
{
31
        GR_WINDOW       *pwp;           /* parent window */
32
        GR_WINDOW       *sibwp;         /* sibling windows */
33
        MWCLIPRECT      *clip;          /* first clip rectangle */
34
        GR_COUNT        count;          /* number of clip rectangles */
35
        GR_COUNT        newcount;       /* number of new rectangles */
36
        GR_COUNT        i;              /* current index */
37
        GR_COORD        minx;           /* minimum clip x coordinate */
38
        GR_COORD        miny;           /* minimum clip y coordinate */
39
        GR_COORD        maxx;           /* maximum clip x coordinate */
40
        GR_COORD        maxy;           /* maximum clip y coordinate */
41
        GR_COORD        diff;           /* difference in coordinates */
42
        GR_SIZE         bs;             /* border size */
43
        GR_BOOL         toomany;        /* TRUE if too many clip rects */
44
        MWCLIPRECT      cliprects[MAX_CLIPRECTS];       /* clip rectangles */
45
 
46
        if (wp->unmapcount || !wp->output || (wp == clipwp))
47
                return;
48
 
49
        clipwp = wp;
50
 
51
        /*
52
         * Start with the rectangle for the complete window.
53
         * We will then cut pieces out of it as needed.
54
         */
55
        count = 1;
56
        clip = cliprects;
57
        clip->x = wp->x;
58
        clip->y = wp->y;
59
        clip->width = wp->width;
60
        clip->height = wp->height;
61
 
62
        /*
63
         * First walk upwards through all parent windows,
64
         * and restrict the visible part of this window to the part
65
         * that shows through all of those parent windows.
66
         */
67
        pwp = wp;
68
        while (pwp != rootwp) {
69
                pwp = pwp->parent;
70
 
71
                diff = pwp->x - clip->x;
72
                if (diff > 0) {
73
                        clip->width -= diff;
74
                        clip->x = pwp->x;
75
                }
76
 
77
                diff = (pwp->x + pwp->width) - (clip->x + clip->width);
78
                if (diff < 0)
79
                        clip->width += diff;
80
 
81
                diff = pwp->y - clip->y;
82
                if (diff > 0) {
83
                        clip->height -= diff;
84
                        clip->y = pwp->y;
85
                }
86
 
87
                diff = (pwp->y + pwp->height) - (clip->y + clip->height);
88
                if (diff < 0)
89
                        clip->height += diff;
90
        }
91
 
92
        /*
93
         * If the window is completely clipped out of view, then
94
         * set the clipping region to indicate that.
95
         */
96
        if ((clip->width <= 0) || (clip->height <= 0)) {
97
                GdSetClipRects(clipwp->psd, 1, cliprects);
98
                return;
99
        }
100
 
101
        /*
102
         * Now examine all windows that obscure this window, and
103
         * for each obscuration, break up the clip rectangles into
104
         * the smaller pieces that are still visible.  The windows
105
         * that can obscure us are the earlier siblings of all of
106
         * our parents.
107
         */
108
        toomany = GR_FALSE;
109
        pwp = wp;
110
/*while (pwp != rootwp) {*/
111
        while (pwp != NULL) {
112
                wp = pwp;
113
                pwp = wp->parent;
114
 
115
                if(!pwp) {
116
                        /* We're clipping the root window*/
117
                        sibwp = rootwp->children;
118
                        wp = NULL;
119
                } else
120
                        sibwp = pwp->children;
121
 
122
                for (; sibwp != wp; sibwp = sibwp->siblings) {
123
                        if (sibwp->unmapcount || !sibwp->output)
124
                                continue;
125
 
126
                        bs = sibwp->bordersize;
127
                        minx = sibwp->x - bs;
128
                        miny = sibwp->y - bs;
129
                        maxx = sibwp->x + sibwp->width + bs - 1;
130
                        maxy = sibwp->y + sibwp->height + bs - 1;
131
 
132
                        newcount = count;
133
                        for (i = 0; i < count; i++) {
134
                                if (newcount > MAX_CLIPRECTS - 3) {
135
                                        toomany = GR_TRUE;
136
                                        break;
137
                                }
138
                                newcount += GsSplitClipRect(&cliprects[i],
139
                                        &cliprects[newcount],
140
                                        minx, miny, maxx, maxy);
141
                        }
142
                        count = newcount;
143
                }
144
if(pwp == rootwp)
145
break;
146
        }
147
 
148
        if (toomany) {
149
                GsError(GR_ERROR_TOO_MUCH_CLIPPING, wp->id);
150
                clip->x = 0;
151
                clip->y = 0;
152
                clip->width = -1;
153
                clip->height = -1;
154
                count = 1;
155
        }
156
 
157
        /*
158
         * Set the clip rectangles.
159
         */
160
        GdSetClipRects(clipwp->psd, count, cliprects);
161
}
162
 
163
/*
164
 * Check the specified clip rectangle against the specified rectangular
165
 * region, and reduce it or split it up into multiple clip rectangles
166
 * such that the specified region is not contained in any of the clip
167
 * rectangles.  The source clip rectangle can be modified in place, and
168
 * in addition more clip rectangles can be generated, which are placed in
169
 * the indicated destination location.  The maximum number of new clip
170
 * rectangles needed is 3.  Returns the number of clip rectangles added.
171
 * If the source clip rectangle is totally obliterated, it is set to an
172
 * impossible region and 0 is returned.  When splits are done, we prefer
173
 * to create wide regions instead of high regions.
174
 */
175
static GR_COUNT
176
GsSplitClipRect(MWCLIPRECT *srcrect, MWCLIPRECT *destrect, GR_COORD minx,
177
        GR_COORD miny, GR_COORD maxx, GR_COORD maxy)
178
{
179
        GR_COORD        x;
180
        GR_COORD        y;
181
        GR_SIZE         width;
182
        GR_SIZE         height;
183
        GR_COORD        dx;
184
        GR_COORD        dy;
185
        int             gaps;
186
 
187
        /*
188
         * First see if there is any overlap at all.
189
         * If not, then nothing to do.
190
         */
191
        x = srcrect->x;
192
        y = srcrect->y;
193
        width = srcrect->width;
194
        height = srcrect->height;
195
 
196
        if ((minx > maxx) || (miny > maxy) || (maxx < x) || (maxy < y) ||
197
                (x + width <= minx) || (y + height <= miny))
198
                        return 0;
199
 
200
        /*
201
         * There is an overlap.  Calculate a value to differentiate
202
         * various cases, and then handle each case separately.  The
203
         * cases are classified on whether there are gaps on the left,
204
         * right, top, and bottom sides of the clip rectangle.
205
         */
206
        gaps = 0;
207
        if (x < minx)
208
                gaps |= GAPVAL(1, 0, 0, 0);
209
        if (x + width - 1 > maxx)
210
                gaps |= GAPVAL(0, 1, 0, 0);
211
        if (y < miny)
212
                gaps |= GAPVAL(0, 0, 1, 0);
213
        if (y + height - 1 > maxy)
214
                gaps |= GAPVAL(0, 0, 0, 1);
215
 
216
        switch (gaps) {
217
                case GAPVAL(0, 0, 0, 0):    /* no gaps at all */
218
                        srcrect->x = 0;
219
                        srcrect->y = 0;
220
                        srcrect->width = 0;
221
                        srcrect->height = 0;
222
                        return 0;
223
 
224
                case GAPVAL(0, 0, 0, 1):   /* gap on bottom */
225
                        dy = maxy - y + 1;
226
                        srcrect->y += dy;
227
                        srcrect->height -= dy;
228
                        return 0;
229
 
230
                case GAPVAL(0, 0, 1, 0):   /* gap on top */
231
                        srcrect->height = miny - y;
232
                        return 0;
233
 
234
                case GAPVAL(0, 0, 1, 1):  /* gap on top, bottom */
235
                        srcrect->height = miny - y;
236
                        destrect->x = x;
237
                        destrect->width = width;
238
                        destrect->y = maxy + 1;
239
                        destrect->height = y + height - maxy - 1;
240
                        return 1;
241
 
242
                case GAPVAL(0, 1, 0, 0):   /* gap on right */
243
                        dx = maxx - x + 1;
244
                        srcrect->x += dx;
245
                        srcrect->width -= dx;
246
                        return 0;
247
 
248
                case GAPVAL(0, 1, 0, 1):  /* gap on right, bottom */
249
                        dx = maxx - x + 1;
250
                        srcrect->x += dx;
251
                        srcrect->width -= dx;
252
                        srcrect->height = maxy - y + 1;
253
                        destrect->x = x;
254
                        destrect->width = width;
255
                        destrect->y = maxy + 1;
256
                        destrect->height = y + height - maxy - 1;
257
                        return 1;
258
 
259
                case GAPVAL(0, 1, 1, 0):  /* gap on right, top */
260
                        dx = maxx - x + 1;
261
                        srcrect->height = miny - y;
262
                        destrect->x = x + dx;
263
                        destrect->width = width - dx;
264
                        destrect->y = miny;
265
                        destrect->height = y + height - miny;
266
                        return 1;
267
 
268
                case GAPVAL(0, 1, 1, 1): /* gap on right, top, bottom */
269
                        dx = maxx - x + 1;
270
                        srcrect->height = miny - y;
271
                        destrect->x = x;
272
                        destrect->width = width;
273
                        destrect->y = maxy + 1;
274
                        destrect->height = y + height - maxy - 1;
275
                        destrect++;
276
                        destrect->x = x + dx;
277
                        destrect->width = width - dx;
278
                        destrect->y = miny;
279
                        destrect->height = maxy - miny + 1;
280
                        return 2;
281
 
282
                case GAPVAL(1, 0, 0, 0):   /* gap on left */
283
                        srcrect->width = minx - x;
284
                        return 0;
285
 
286
                case GAPVAL(1, 0, 0, 1):  /* gap on left, bottom */
287
                        srcrect->width = minx - x;
288
                        srcrect->height = maxy - y + 1;
289
                        destrect->x = x;
290
                        destrect->width = width;
291
                        destrect->y = maxy + 1;
292
                        destrect->height = y + height - maxy - 1;
293
                        return 1;
294
 
295
                case GAPVAL(1, 0, 1, 0):  /* gap on left, top */
296
                        srcrect->height = miny - y;
297
                        destrect->x = x;
298
                        destrect->width = minx - x;
299
                        destrect->y = miny;
300
                        destrect->height = y + height - miny;
301
                        return 1;
302
 
303
                case GAPVAL(1, 0, 1, 1): /* gap on left, top, bottom */
304
                        srcrect->height = miny - y;
305
                        destrect->x = x;
306
                        destrect->width = minx - x;
307
                        destrect->y = miny;
308
                        destrect->height = maxy - miny + 1;
309
                        destrect++;
310
                        destrect->x = x;
311
                        destrect->width = width;
312
                        destrect->y = maxy + 1;
313
                        destrect->height = y + height - maxy - 1;
314
                        return 2;
315
 
316
                case GAPVAL(1, 1, 0, 0):  /* gap on left, right */
317
                        destrect->x = maxx + 1;
318
                        destrect->width = x + width - maxx - 1;
319
                        destrect->y = y;
320
                        destrect->height = height;
321
                        srcrect->width = minx - x;
322
                        return 1;
323
 
324
                case GAPVAL(1, 1, 0, 1): /* gap on left, right, bottom */
325
                        dy = maxy - y + 1;
326
                        srcrect->y += dy;
327
                        srcrect->height -= dy;
328
                        destrect->x = x;
329
                        destrect->width = minx - x;
330
                        destrect->y = y;
331
                        destrect->height = dy;
332
                        destrect++;
333
                        destrect->x = maxx + 1;
334
                        destrect->width = x + width - maxx - 1;
335
                        destrect->y = y;
336
                        destrect->height = dy;
337
                        return 2;
338
 
339
                case GAPVAL(1, 1, 1, 0): /* gap on left, right, top */
340
                        srcrect->height = miny - y;
341
                        destrect->x = x;
342
                        destrect->width = minx - x;
343
                        destrect->y = miny;
344
                        destrect->height = y + height - miny;
345
                        destrect++;
346
                        destrect->x = maxx + 1;
347
                        destrect->width = x + width - maxx - 1;
348
                        destrect->y = miny;
349
                        destrect->height = y + height - miny;
350
                        return 2;
351
 
352
                case GAPVAL(1, 1, 1, 1):        /* gap on all sides */
353
                        srcrect->height = miny - y;
354
                        destrect->x = x;
355
                        destrect->width = minx - x;
356
                        destrect->y = miny;
357
                        destrect->height = maxy - miny + 1;
358
                        destrect++;
359
                        destrect->x = maxx + 1;
360
                        destrect->width = x + width - maxx - 1;
361
                        destrect->y = miny;
362
                        destrect->height = maxy - miny + 1;
363
                        destrect++;
364
                        destrect->x = x;
365
                        destrect->width = width;
366
                        destrect->y = maxy + 1;
367
                        destrect->height = y + height - maxy - 1;
368
                        return 3;
369
        }
370
        return 0; /* NOTREACHED */
371
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.