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/] [mwin/] [winclip1.c] - Blame information for rev 174

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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