1706f2543Smrg/*
2706f2543Smrg * Copyright © 1998 Keith Packard
3706f2543Smrg *
4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
6706f2543Smrg * the above copyright notice appear in all copies and that both that
7706f2543Smrg * copyright notice and this permission notice appear in supporting
8706f2543Smrg * documentation, and that the name of Keith Packard not be used in
9706f2543Smrg * advertising or publicity pertaining to distribution of the software without
10706f2543Smrg * specific, written prior permission.  Keith Packard makes no
11706f2543Smrg * representations about the suitability of this software for any purpose.  It
12706f2543Smrg * is provided "as is" without express or implied warranty.
13706f2543Smrg *
14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg */
22706f2543Smrg
23706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
24706f2543Smrg#include <dix-config.h>
25706f2543Smrg#endif
26706f2543Smrg
27706f2543Smrg#include "fb.h"
28706f2543Smrg
29706f2543Smrgtypedef void	(*FbDots)  (FbBits	*dst,
30706f2543Smrg			    FbStride    dstStride,
31706f2543Smrg			    int		dstBpp,
32706f2543Smrg			    BoxPtr	pBox,
33706f2543Smrg			    xPoint	*pts,
34706f2543Smrg			    int		npt,
35706f2543Smrg			    int		xorg,
36706f2543Smrg			    int		yorg,
37706f2543Smrg			    int		xoff,
38706f2543Smrg			    int		yoff,
39706f2543Smrg			    FbBits	and,
40706f2543Smrg			    FbBits	xor);
41706f2543Smrg
42706f2543Smrgvoid
43706f2543SmrgfbDots (FbBits	    *dstOrig,
44706f2543Smrg	FbStride    dstStride,
45706f2543Smrg	int	    dstBpp,
46706f2543Smrg	BoxPtr	    pBox,
47706f2543Smrg	xPoint	    *pts,
48706f2543Smrg	int	    npt,
49706f2543Smrg	int	    xorg,
50706f2543Smrg	int	    yorg,
51706f2543Smrg	int	    xoff,
52706f2543Smrg	int	    yoff,
53706f2543Smrg	FbBits	    andOrig,
54706f2543Smrg	FbBits	    xorOrig)
55706f2543Smrg{
56706f2543Smrg    FbStip	*dst = (FbStip *) dstOrig;
57706f2543Smrg    int		x1, y1, x2, y2;
58706f2543Smrg    int		x, y;
59706f2543Smrg    FbStip	*d;
60706f2543Smrg    FbStip	and = andOrig;
61706f2543Smrg    FbStip	xor = xorOrig;
62706f2543Smrg
63706f2543Smrg    dstStride = FbBitsStrideToStipStride (dstStride);
64706f2543Smrg    x1 = pBox->x1;
65706f2543Smrg    y1 = pBox->y1;
66706f2543Smrg    x2 = pBox->x2;
67706f2543Smrg    y2 = pBox->y2;
68706f2543Smrg    while (npt--)
69706f2543Smrg    {
70706f2543Smrg	x = pts->x + xorg;
71706f2543Smrg	y = pts->y + yorg;
72706f2543Smrg	pts++;
73706f2543Smrg	if (x1 <= x && x < x2 && y1 <= y && y < y2)
74706f2543Smrg	{
75706f2543Smrg	    x = (x + xoff) * dstBpp;
76706f2543Smrg	    d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT);
77706f2543Smrg	    x &= FB_STIP_MASK;
78706f2543Smrg#ifdef FB_24BIT
79706f2543Smrg	    if (dstBpp == 24)
80706f2543Smrg	    {
81706f2543Smrg		FbStip	leftMask, rightMask;
82706f2543Smrg		int	n, rot;
83706f2543Smrg		FbStip	andT, xorT;
84706f2543Smrg
85706f2543Smrg		rot = FbFirst24Rot (x);
86706f2543Smrg		andT = FbRot24Stip(and,rot);
87706f2543Smrg		xorT = FbRot24Stip(xor,rot);
88706f2543Smrg		FbMaskStip (x, 24, leftMask, n, rightMask);
89706f2543Smrg		if (leftMask)
90706f2543Smrg		{
91706f2543Smrg		    WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask));
92706f2543Smrg		    andT = FbNext24Stip(andT);
93706f2543Smrg		    xorT = FbNext24Stip(xorT);
94706f2543Smrg		    d++;
95706f2543Smrg		}
96706f2543Smrg		if (rightMask)
97706f2543Smrg		    WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, rightMask));
98706f2543Smrg	    }
99706f2543Smrg	    else
100706f2543Smrg#endif
101706f2543Smrg	    {
102706f2543Smrg		FbStip	mask;
103706f2543Smrg		mask = FbStipMask(x, dstBpp);
104706f2543Smrg		WRITE(d, FbDoMaskRRop (READ(d), and, xor, mask));
105706f2543Smrg	    }
106706f2543Smrg	}
107706f2543Smrg    }
108706f2543Smrg}
109706f2543Smrg
110706f2543Smrgvoid
111706f2543SmrgfbPolyPoint (DrawablePtr    pDrawable,
112706f2543Smrg	     GCPtr	    pGC,
113706f2543Smrg	     int	    mode,
114706f2543Smrg	     int	    nptInit,
115706f2543Smrg	     xPoint	    *pptInit)
116706f2543Smrg{
117706f2543Smrg    FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
118706f2543Smrg    RegionPtr	pClip = fbGetCompositeClip(pGC);
119706f2543Smrg    FbBits	*dst;
120706f2543Smrg    FbStride	dstStride;
121706f2543Smrg    int		dstBpp;
122706f2543Smrg    int		dstXoff, dstYoff;
123706f2543Smrg    FbDots	dots;
124706f2543Smrg    FbBits	and, xor;
125706f2543Smrg    xPoint	*ppt;
126706f2543Smrg    int		npt;
127706f2543Smrg    BoxPtr	pBox;
128706f2543Smrg    int		nBox;
129706f2543Smrg
130706f2543Smrg    /* make pointlist origin relative */
131706f2543Smrg    ppt = pptInit;
132706f2543Smrg    npt = nptInit;
133706f2543Smrg    if (mode == CoordModePrevious)
134706f2543Smrg    {
135706f2543Smrg	npt--;
136706f2543Smrg	while(npt--)
137706f2543Smrg	{
138706f2543Smrg	    ppt++;
139706f2543Smrg	    ppt->x += (ppt-1)->x;
140706f2543Smrg	    ppt->y += (ppt-1)->y;
141706f2543Smrg	}
142706f2543Smrg    }
143706f2543Smrg    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
144706f2543Smrg    and = pPriv->and;
145706f2543Smrg    xor = pPriv->xor;
146706f2543Smrg    dots = fbDots;
147706f2543Smrg#ifndef FBNOPIXADDR
148706f2543Smrg    switch (dstBpp) {
149706f2543Smrg    case 8:	dots = fbDots8; break;
150706f2543Smrg    case 16:    dots = fbDots16; break;
151706f2543Smrg#ifdef FB_24BIT
152706f2543Smrg    case 24:    dots = fbDots24; break;
153706f2543Smrg#endif
154706f2543Smrg    case 32:    dots = fbDots32; break;
155706f2543Smrg    }
156706f2543Smrg#endif
157706f2543Smrg    for (nBox = RegionNumRects (pClip), pBox = RegionRects (pClip);
158706f2543Smrg	 nBox--; pBox++)
159706f2543Smrg	(*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit,
160706f2543Smrg		 pDrawable->x, pDrawable->y, dstXoff, dstYoff, and, xor);
161706f2543Smrg    fbFinishAccess (pDrawable);
162706f2543Smrg}
163