summaryrefslogtreecommitdiff
path: root/hw/xfree86/xaa/xaaRect.c
blob: fe8d70de2eb211db7cd5801e06b79cdb704bd5df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c,v 1.3 1999/05/30 03:03:33 dawes Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include "X.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"

/*
   Much of this file based on code by 
	Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
*/


void
XAAPolyRectangleThinSolid(
    DrawablePtr  pDrawable,
    GCPtr        pGC,    
    int	         nRectsInit,
    xRectangle  *pRectsInit )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int         nClipRects;     /* number of clip rectangles */
    BoxPtr      pClipRects;     /* points to the list of clip rects */
    int         xOrigin;        /* Drawables x origin */
    int         yOrigin;        /* Drawables x origin */
    xRectangle *pRect;          /* list of rects */
    int         nRects;         /* running count of number of rects */
    int         origX1, origY1; /* original rectangle's U/L corner */
    int         origX2, origY2; /* original rectangle's L/R corner */
    int         clippedX1;      /* clipped rectangle's left x */
    int         clippedY1;      /* clipped rectangle's top y */
    int         clippedX2;      /* clipped rectangle's right x */
    int         clippedY2;      /* clipped rectangle's bottom y */
    int         clipXMin;       /* upper left corner of clip rect */
    int         clipYMin;       /* upper left corner of clip rect */
    int         clipXMax;       /* lower right corner of clip rect */
    int         clipYMax;       /* lower right corner of clip rect */
    int         width, height;  /* width and height of rect */

    nClipRects = REGION_NUM_RECTS(pGC->pCompositeClip);
    pClipRects = REGION_RECTS(pGC->pCompositeClip);

    if(!nClipRects) return;

    xOrigin = pDrawable->x;
    yOrigin = pDrawable->y;


    (*infoRec->SetupForSolidLine)(infoRec->pScrn, 
			pGC->fgPixel, pGC->alu, pGC->planemask);


    for ( ; nClipRects > 0; 
	  nClipRects--, pClipRects++ )
    {
        clipYMin = pClipRects->y1;
        clipYMax = pClipRects->y2 - 1;
        clipXMin = pClipRects->x1;
        clipXMax = pClipRects->x2 - 1;

	for (pRect = pRectsInit, nRects = nRectsInit; 
	     nRects > 0; 
	     nRects--, pRect++ )
        {
	    /* translate rectangle data over to the drawable */
            origX1 = pRect->x + xOrigin; 
	    origY1 = pRect->y + yOrigin;
            origX2 = origX1 + pRect->width; 
	    origY2 = origY1 + pRect->height; 

	    /* reject entire rectangle if completely outside clip rect */
	    if ((origX1 > clipXMax) || (origX2 < clipXMin) ||
		(origY1 > clipYMax) || (origY2 < clipYMin))
	        continue;

	    /* clip the rectangle */
	    clippedX1 = max (origX1, clipXMin);
	    clippedX2 = min (origX2, clipXMax);
	    clippedY1 = max (origY1, clipYMin);
	    clippedY2 = min (origY2, clipYMax);

	    width = clippedX2 - clippedX1 + 1;

	    if (origY1 >= clipYMin) {
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY1, width, DEGREES_0);

		/* don't overwrite corner */
		clippedY1++;
	    }

	    if ((origY2 <= clipYMax) && (origY1 != origY2)) {
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY2, width, DEGREES_0);

		/* don't overwrite corner */
		clippedY2--; 
	    }

	    if (clippedY2 < clippedY1) continue;

	    height = clippedY2 - clippedY1 + 1;

	    /* draw vertical edges using lines if not clipped out */
            if (origX1 >= clipXMin) 
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY1, height, DEGREES_270);

            if ((origX2 <= clipXMax) && (origX2 != origX1))
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX2, clippedY1, height, DEGREES_270);
	}
    }

    SET_SYNC_FLAG(infoRec);
}