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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
 * Portions Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
3
 *      Somewhat less shamelessly ripped from the Wine distribution
4
 *
5
 * Win32 API Region Management Routines.
6
 * Win32 API Complex Rectangle Routines.
7
 *
8
 * GDI region objects. Shamelessly ripped out from the X11 distribution
9
 * Thanks for the nice licence.
10
 *
11
 * Copyright 1993, 1994, 1995 Alexandre Julliard
12
 * Modifications and additions: Copyright 1998 Huw Davies
13
 */
14
#include "windows.h"
15
#include "device.h"
16
#include <stdlib.h>
17
#include <string.h>
18
 
19
/* later, error checking can be built into this get*/
20
#define GDI_GetObjPtr(hrgn,type)        (hrgn)
21
 
22
/* local functions*/
23
static HRGN REGION_CreateRegion(void);
24
/*BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect );*/
25
/*BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y );*/
26
 
27
#define EMPTY_REGION(pReg) { \
28
    (pReg)->numRects = 0; \
29
    (pReg)->extents.left = (pReg)->extents.top = 0; \
30
    (pReg)->extents.right = (pReg)->extents.bottom = 0; \
31
    (pReg)->type = NULLREGION; \
32
 }
33
 
34
/*
35
 *          Create a new empty region.
36
 */
37
static HRGN
38
REGION_CreateRegion(void)
39
{
40
    MWRGNOBJ *obj;
41
 
42
    obj = GdItemNew(MWRGNOBJ);
43
    if(!obj)
44
        return NULL;
45
    obj->hdr.type = OBJ_REGION;
46
    obj->hdr.stockobj = FALSE;
47
    if(!(obj->rgn = GdAllocRegion())) {
48
        GdItemFree(obj);
49
        return NULL;
50
    }
51
    return (HRGN)obj;
52
}
53
 
54
 
55
INT WINAPI
56
OffsetRgn( HRGN hrgn, INT x, INT y )
57
{
58
    MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
59
 
60
    if (obj)
61
    {
62
        GdOffsetRegion(obj->rgn, x, y);
63
        return obj->rgn->type;
64
    }
65
    return ERRORREGION;
66
}
67
 
68
 
69
INT WINAPI
70
GetRgnBox( HRGN hrgn, LPRECT rect )
71
{
72
    MWRGNOBJ * obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
73
    if (obj)
74
        return GdGetRegionBox(obj->rgn, rect);
75
    return ERRORREGION;
76
}
77
 
78
 
79
HRGN WINAPI
80
CreateRectRgn(INT left, INT top, INT right, INT bottom)
81
{
82
    HRGN hrgn;
83
 
84
    if (!(hrgn = REGION_CreateRegion()))
85
        return 0;
86
    /*TRACE(region, "\n");*/
87
    SetRectRgn(hrgn, left, top, right, bottom);
88
    return hrgn;
89
}
90
 
91
 
92
HRGN WINAPI
93
CreateRectRgnIndirect( const RECT* rect )
94
{
95
    return CreateRectRgn( rect->left, rect->top, rect->right, rect->bottom );
96
}
97
 
98
 
99
/*
100
 * Allows either or both left and top to be greater than right or bottom.
101
 */
102
VOID WINAPI
103
SetRectRgn( HRGN hrgn, INT left, INT top, INT right, INT bottom )
104
{
105
    MWRGNOBJ * obj;
106
    MWCLIPREGION *rgn;
107
 
108
    /*TRACE(region, " %04x %d,%d-%d,%d\n", hrgn, left, top, right, bottom );*/
109
 
110
    if (!(obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ))) return;
111
 
112
    if (left > right) { INT tmp = left; left = right; right = tmp; }
113
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
114
 
115
    rgn = obj->rgn;
116
    GdSetRectRegion(rgn, left, top, right, bottom);
117
}
118
 
119
 
120
HRGN WINAPI
121
CreateRoundRectRgn( INT left, INT top, INT right, INT bottom,
122
        INT ellipse_width, INT ellipse_height )
123
{
124
    MWRGNOBJ * obj;
125
    HRGN hrgn;
126
    int asq, bsq, d, xd, yd;
127
    RECT rect;
128
 
129
    /* Check if we can do a normal rectangle instead */
130
    if (ellipse_width == 0 || ellipse_height == 0)
131
        return CreateRectRgn( left, top, right, bottom );
132
 
133
    /* Make the dimensions sensible */
134
    if (left > right) { INT tmp = left; left = right; right = tmp; }
135
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }
136
 
137
    ellipse_width = abs(ellipse_width);
138
    ellipse_height = abs(ellipse_height);
139
 
140
    /* Create region */
141
 
142
    if (!(hrgn = REGION_CreateRegion()))
143
            return 0;
144
    obj = (MWRGNOBJ *)hrgn;
145
    /*TRACE(region,"(%d,%d-%d,%d %dx%d): ret=%04x\n",
146
               left, top, right, bottom, ellipse_width, ellipse_height, hrgn);*/
147
 
148
    /* Check parameters */
149
 
150
    if (ellipse_width > right-left) ellipse_width = right-left;
151
    if (ellipse_height > bottom-top) ellipse_height = bottom-top;
152
 
153
    /* Ellipse algorithm, based on an article by K. Porter */
154
    /* in DDJ Graphics Programming Column, 8/89 */
155
 
156
    asq = ellipse_width * ellipse_width / 4;        /* a^2 */
157
    bsq = ellipse_height * ellipse_height / 4;      /* b^2 */
158
    if (asq == 0) asq = 1;
159
    if (bsq == 0) bsq = 1;
160
    d = bsq - asq * ellipse_height / 2 + asq / 4;   /* b^2 - a^2b + a^2/4 */
161
    xd = 0;
162
    yd = asq * ellipse_height;                      /* 2a^2b */
163
 
164
    rect.left   = left + ellipse_width / 2;
165
    rect.right  = right - ellipse_width / 2;
166
 
167
    /* Loop to draw first half of quadrant */
168
 
169
    while (xd < yd)
170
    {
171
        if (d > 0)  /* if nearest pixel is toward the center */
172
        {
173
              /* move toward center */
174
            rect.top = top++;
175
            rect.bottom = rect.top + 1;
176
            GdUnionRectWithRegion( &rect, obj->rgn );
177
            rect.top = --bottom;
178
            rect.bottom = rect.top + 1;
179
            GdUnionRectWithRegion( &rect, obj->rgn );
180
            yd -= 2*asq;
181
            d  -= yd;
182
        }
183
        rect.left--;        /* next horiz point */
184
        rect.right++;
185
        xd += 2*bsq;
186
        d  += bsq + xd;
187
    }
188
 
189
    /* Loop to draw second half of quadrant */
190
 
191
    d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
192
    while (yd >= 0)
193
    {
194
          /* next vertical point */
195
        rect.top = top++;
196
        rect.bottom = rect.top + 1;
197
        GdUnionRectWithRegion( &rect, obj->rgn );
198
        rect.top = --bottom;
199
        rect.bottom = rect.top + 1;
200
        GdUnionRectWithRegion( &rect, obj->rgn );
201
        if (d < 0)   /* if nearest pixel is outside ellipse */
202
        {
203
            rect.left--;     /* move away from center */
204
            rect.right++;
205
            xd += 2*bsq;
206
            d  += xd;
207
        }
208
        yd -= 2*asq;
209
        d  += asq - yd;
210
    }
211
 
212
    /* Add the inside rectangle */
213
 
214
    if (top <= bottom)
215
    {
216
        rect.top = top;
217
        rect.bottom = bottom;
218
        GdUnionRectWithRegion( &rect, obj->rgn );
219
    }
220
    obj->rgn->type = SIMPLEREGION; /* FIXME? */
221
    return hrgn;
222
}
223
 
224
 
225
HRGN WINAPI
226
CreateEllipticRgn( INT left, INT top, INT right, INT bottom )
227
{
228
    return CreateRoundRectRgn(left, top, right, bottom, right-left, bottom-top);
229
}
230
 
231
 
232
HRGN WINAPI
233
CreateEllipticRgnIndirect( const RECT *rect )
234
{
235
    return CreateRoundRectRgn( rect->left, rect->top, rect->right,
236
                                 rect->bottom, rect->right - rect->left,
237
                                 rect->bottom - rect->top );
238
}
239
 
240
HRGN WINAPI
241
CreatePolygonRgn(const POINT *points, INT count, INT mode)
242
{
243
#if POLYREGIONS
244
        HRGN            hrgn;
245
        MWRGNOBJ *      obj;
246
        MWCLIPREGION *  rgn;
247
 
248
        if (!(hrgn = REGION_CreateRegion()))
249
                return NULL;
250
        obj = (MWRGNOBJ *)GDI_GetObjPtr(hrgn, OBJ_REGION);
251
        if (!obj)
252
                return NULL;
253
 
254
        rgn = GdAllocPolygonRegion((POINT *)points, count, mode);
255
        if (!rgn)
256
                return hrgn;
257
        GdDestroyRegion(obj->rgn);
258
        obj->rgn = rgn;
259
        return hrgn;
260
#endif
261
}
262
 
263
DWORD WINAPI
264
GetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
265
{
266
    DWORD size;
267
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
268
    MWCLIPREGION *rgn;
269
 
270
    /*TRACE(region," %04x count = %ld, rgndata = %p\n", hrgn, count, rgndata);*/
271
 
272
    if(!obj) return 0;
273
 
274
    rgn = obj->rgn;
275
    size = rgn->numRects * sizeof(RECT);
276
    if(count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL)
277
        return size + sizeof(RGNDATAHEADER);
278
 
279
    rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
280
    rgndata->rdh.iType = RDH_RECTANGLES;
281
    rgndata->rdh.nCount = rgn->numRects;
282
    rgndata->rdh.nRgnSize = size;
283
    rgndata->rdh.rcBound.left = rgn->extents.left;
284
    rgndata->rdh.rcBound.top = rgn->extents.top;
285
    rgndata->rdh.rcBound.right = rgn->extents.right;
286
    rgndata->rdh.rcBound.bottom = rgn->extents.bottom;
287
 
288
    memcpy( rgndata->Buffer, rgn->rects, size );
289
 
290
    return 1;
291
}
292
 
293
 
294
#if 0
295
HRGN WINAPI
296
ExtCreateRegion(const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata)
297
{
298
    HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
299
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
300
    RECT *pCurRect, *pEndRect;
301
 
302
    /*TRACE(region, " %p %ld %p. Returning %04x\n",
303
                lpXform, dwCount, rgndata, hrgn);*/
304
    if(!hrgn)
305
    {
306
        WARN(region, "Can't create a region!\n");
307
        return 0;
308
    }
309
    if(lpXform)
310
        WARN(region, "Xform not implemented - ignoring\n");
311
 
312
    if(rgndata->rdh.iType != RDH_RECTANGLES)
313
    {
314
        WARN(region, "Type not RDH_RECTANGLES\n");
315
        DeleteObject( hrgn );
316
        return 0;
317
    }
318
 
319
    pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
320
    for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
321
        GdUnionRectWithRegion( pCurRect, obj->rgn );
322
 
323
    return hrgn;
324
}
325
#endif
326
 
327
 
328
BOOL WINAPI
329
PtInRegion( HRGN hrgn, INT x, INT y )
330
{
331
    MWRGNOBJ * obj;
332
 
333
    obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
334
    if(!obj)
335
            return FALSE;
336
    return GdPtInRegion(obj->rgn, x, y);
337
}
338
 
339
/*
340
 * Returns TRUE if rect is at least partly inside hrgn
341
 */
342
BOOL WINAPI
343
RectInRegion( HRGN hrgn, const RECT *rect )
344
{
345
    MWRGNOBJ * obj;
346
 
347
    obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
348
    if(!obj)
349
            return FALSE;
350
    return (GdRectInRegion(obj->rgn, rect) == MWRECT_OUT? FALSE: TRUE);
351
}
352
 
353
BOOL WINAPI
354
EqualRgn( HRGN hrgn1, HRGN hrgn2 )
355
{
356
    MWRGNOBJ *obj1, *obj2;
357
 
358
    if ((obj1 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn1, OBJ_REGION )))
359
        if ((obj2 = (MWRGNOBJ *) GDI_GetObjPtr( hrgn2, OBJ_REGION )))
360
            return GdEqualRegion(obj1->rgn, obj2->rgn);
361
    return FALSE;
362
}
363
 
364
#if 0
365
/*
366
 *           REGION_UnionRectWithRgn
367
 *           Adds a rectangle to a HRGN
368
 *           A helper used by scroll.c
369
 */
370
BOOL
371
REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect )
372
{
373
    MWRGNOBJ *obj = (MWRGNOBJ *)hrgn;
374
 
375
    if(!obj) return FALSE;
376
    GdUnionRectWithRegion( lpRect, obj->rgn );
377
    return TRUE;
378
}
379
 
380
/*
381
 *           REGION_FrameRgn
382
 * Create a region that is a frame around another region.
383
 * Expand all rectangles by +/- x and y, then subtract original region.
384
 */
385
BOOL
386
REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
387
{
388
    BOOL bRet;
389
    MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION );
390
 
391
    if (srcObj->rgn->numRects != 0)
392
    {
393
        MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION );
394
        RECT *pRect, *pEndRect;
395
        RECT tempRect;
396
 
397
        EMPTY_REGION( destObj->rgn );
398
 
399
        pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
400
        for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++)
401
        {
402
            tempRect.left = pRect->left - x;
403
            tempRect.top = pRect->top - y;
404
            tempRect.right = pRect->right + x;
405
            tempRect.bottom = pRect->bottom + y;
406
            GdUnionRectWithRegion( &tempRect, destObj->rgn );
407
        }
408
        GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn );
409
        bRet = TRUE;
410
    }
411
    else
412
        bRet = FALSE;
413
    return bRet;
414
}
415
#endif
416
 
417
/*
418
 * Note: The behavior is correct even if src and dest regions are the same.
419
 */
420
INT WINAPI
421
CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
422
{
423
    MWRGNOBJ *destObj = (MWRGNOBJ *) GDI_GetObjPtr( hDest, OBJ_REGION);
424
    INT result = ERRORREGION;
425
 
426
    /*TRACE(region, " %04x,%04x -> %04x mode=%x\n", hSrc1, hSrc2, hDest,mode);*/
427
 
428
    if (destObj)
429
    {
430
        MWRGNOBJ *src1Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc1, OBJ_REGION);
431
 
432
        if (src1Obj)
433
        {
434
            /*TRACE(region, "dump:\n");
435
            if(TRACE_ON(region))
436
                REGION_DumpRegion(src1Obj->rgn);*/
437
            if (mode == RGN_COPY)
438
            {
439
                GdCopyRegion( destObj->rgn, src1Obj->rgn );
440
                result = destObj->rgn->type;
441
            }
442
            else
443
            {
444
                MWRGNOBJ *src2Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc2, OBJ_REGION);
445
 
446
                if (src2Obj)
447
                {
448
                    /*TRACE(region, "dump:\n");
449
                    if(TRACE_ON(region))
450
                        REGION_DumpRegion(src2Obj->rgn);*/
451
                    switch (mode)
452
                    {
453
                    case RGN_AND:
454
                        GdIntersectRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn);
455
                        break;
456
                    case RGN_OR:
457
                        GdUnionRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
458
                        break;
459
                    case RGN_XOR:
460
                        GdXorRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
461
                        break;
462
                    case RGN_DIFF:
463
                        GdSubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
464
                        break;
465
                    }
466
                    result = destObj->rgn->type;
467
                }
468
            }
469
        }
470
        /*TRACE(region, "dump:\n");
471
        if(TRACE_ON(region))
472
            REGION_DumpRegion(destObj->rgn);*/
473
    }
474
    return result;
475
}
476
 
477
/*
478
 * Rectangle-related functions
479
 *
480
 * Copyright 1993, 1996 Alexandre Julliard
481
 *
482
 */
483
BOOL WINAPI
484
IntersectRect( LPRECT dest, const RECT *src1, const RECT *src2 )
485
{
486
    if (IsRectEmpty(src1) || IsRectEmpty(src2) ||
487
        (src1->left >= src2->right) || (src2->left >= src1->right) ||
488
        (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
489
    {
490
        SetRectEmpty( dest );
491
        return FALSE;
492
    }
493
    dest->left   = MWMAX( src1->left, src2->left );
494
    dest->right  = MWMIN( src1->right, src2->right );
495
    dest->top    = MWMAX( src1->top, src2->top );
496
    dest->bottom = MWMIN( src1->bottom, src2->bottom );
497
    return TRUE;
498
}
499
 
500
 
501
BOOL WINAPI
502
UnionRect( LPRECT dest, const RECT *src1, const RECT *src2 )
503
{
504
    if (IsRectEmpty(src1))
505
    {
506
        if (IsRectEmpty(src2))
507
        {
508
            SetRectEmpty( dest );
509
            return FALSE;
510
        }
511
        else *dest = *src2;
512
    }
513
    else
514
    {
515
        if (IsRectEmpty(src2)) *dest = *src1;
516
        else
517
        {
518
            dest->left   = MWMIN( src1->left, src2->left );
519
            dest->right  = MWMAX( src1->right, src2->right );
520
            dest->top    = MWMIN( src1->top, src2->top );
521
            dest->bottom = MWMAX( src1->bottom, src2->bottom );
522
        }
523
    }
524
    return TRUE;
525
}
526
 
527
 
528
BOOL WINAPI
529
EqualRect( const RECT* rect1, const RECT* rect2 )
530
{
531
    return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
532
            (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
533
}
534
 
535
 
536
BOOL WINAPI
537
SubtractRect( LPRECT dest, const RECT *src1, const RECT *src2 )
538
{
539
    RECT tmp;
540
 
541
    if (IsRectEmpty( src1 ))
542
    {
543
        SetRectEmpty( dest );
544
        return FALSE;
545
    }
546
    *dest = *src1;
547
    if (IntersectRect( &tmp, src1, src2 ))
548
    {
549
        if (EqualRect( &tmp, dest ))
550
        {
551
            SetRectEmpty( dest );
552
            return FALSE;
553
        }
554
        if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
555
        {
556
            if (tmp.left == dest->left) dest->left = tmp.right;
557
            else if (tmp.right == dest->right) dest->right = tmp.left;
558
        }
559
        else if ((tmp.left == dest->left) && (tmp.right == dest->right))
560
        {
561
            if (tmp.top == dest->top) dest->top = tmp.bottom;
562
            else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
563
        }
564
    }
565
    return TRUE;
566
}

powered by: WebSVN 2.1.0

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