1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4706f2543Smrg *
5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
7706f2543Smrg * the above copyright notice appear in all copies and that both that
8706f2543Smrg * copyright notice and this permission notice appear in supporting
9706f2543Smrg * documentation, and that the name of Keith Packard not be used in
10706f2543Smrg * advertising or publicity pertaining to distribution of the software without
11706f2543Smrg * specific, written prior permission.  Keith Packard makes no
12706f2543Smrg * representations about the suitability of this software for any purpose.  It
13706f2543Smrg * is provided "as is" without express or implied warranty.
14706f2543Smrg *
15706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
22706f2543Smrg */
23706f2543Smrg
24706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
25706f2543Smrg#include <dix-config.h>
26706f2543Smrg#endif
27706f2543Smrg
28706f2543Smrg#include "scrnintstr.h"
29706f2543Smrg#include "gcstruct.h"
30706f2543Smrg#include "pixmapstr.h"
31706f2543Smrg#include "windowstr.h"
32706f2543Smrg#include "mi.h"
33706f2543Smrg#include "picturestr.h"
34706f2543Smrg#include "mipict.h"
35706f2543Smrg
36706f2543Smrgvoid
37706f2543SmrgmiPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds)
38706f2543Smrg{
39706f2543Smrg    bounds->x1 = xFixedToInt (points->x);
40706f2543Smrg    bounds->x2 = xFixedToInt (xFixedCeil (points->x));
41706f2543Smrg    bounds->y1 = xFixedToInt (points->y);
42706f2543Smrg    bounds->y2 = xFixedToInt (xFixedCeil (points->y));
43706f2543Smrg    points++;
44706f2543Smrg    npoint--;
45706f2543Smrg    while (npoint-- > 0)
46706f2543Smrg    {
47706f2543Smrg	INT16	x1 = xFixedToInt (points->x);
48706f2543Smrg	INT16	x2 = xFixedToInt (xFixedCeil (points->x));
49706f2543Smrg	INT16	y1 = xFixedToInt (points->y);
50706f2543Smrg	INT16	y2 = xFixedToInt (xFixedCeil (points->y));
51706f2543Smrg
52706f2543Smrg	if (x1 < bounds->x1)
53706f2543Smrg	    bounds->x1 = x1;
54706f2543Smrg	else if (x2 > bounds->x2)
55706f2543Smrg	    bounds->x2 = x2;
56706f2543Smrg	if (y1 < bounds->y1)
57706f2543Smrg	    bounds->y1 = y1;
58706f2543Smrg	else if (y2 > bounds->y2)
59706f2543Smrg	    bounds->y2 = y2;
60706f2543Smrg	points++;
61706f2543Smrg    }
62706f2543Smrg}
63706f2543Smrg
64706f2543Smrgvoid
65706f2543SmrgmiTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
66706f2543Smrg{
67706f2543Smrg    miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
68706f2543Smrg}
69706f2543Smrg
70706f2543Smrgvoid
71706f2543SmrgmiTriangles (CARD8	    op,
72706f2543Smrg	     PicturePtr	    pSrc,
73706f2543Smrg	     PicturePtr	    pDst,
74706f2543Smrg	     PictFormatPtr  maskFormat,
75706f2543Smrg	     INT16	    xSrc,
76706f2543Smrg	     INT16	    ySrc,
77706f2543Smrg	     int	    ntri,
78706f2543Smrg	     xTriangle	    *tris)
79706f2543Smrg{
80706f2543Smrg    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
81706f2543Smrg    PictureScreenPtr    ps = GetPictureScreen(pScreen);
82706f2543Smrg
83706f2543Smrg    /*
84706f2543Smrg     * Check for solid alpha add
85706f2543Smrg     */
86706f2543Smrg    if (op == PictOpAdd && miIsSolidAlpha (pSrc))
87706f2543Smrg    {
88706f2543Smrg	(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
89706f2543Smrg    }
90706f2543Smrg    else if (maskFormat)
91706f2543Smrg    {
92706f2543Smrg	BoxRec		bounds;
93706f2543Smrg	PicturePtr	pPicture;
94706f2543Smrg	INT16		xDst, yDst;
95706f2543Smrg	INT16		xRel, yRel;
96706f2543Smrg
97706f2543Smrg	xDst = tris[0].p1.x >> 16;
98706f2543Smrg	yDst = tris[0].p1.y >> 16;
99706f2543Smrg
100706f2543Smrg	miTriangleBounds (ntri, tris, &bounds);
101706f2543Smrg	if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
102706f2543Smrg	    return;
103706f2543Smrg	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
104706f2543Smrg					 bounds.x2 - bounds.x1,
105706f2543Smrg					 bounds.y2 - bounds.y1);
106706f2543Smrg	if (!pPicture)
107706f2543Smrg	    return;
108706f2543Smrg	(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
109706f2543Smrg
110706f2543Smrg	xRel = bounds.x1 + xSrc - xDst;
111706f2543Smrg	yRel = bounds.y1 + ySrc - yDst;
112706f2543Smrg	CompositePicture (op, pSrc, pPicture, pDst,
113706f2543Smrg			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
114706f2543Smrg			  bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
115706f2543Smrg	FreePicture (pPicture, 0);
116706f2543Smrg    }
117706f2543Smrg    else
118706f2543Smrg    {
119706f2543Smrg	if (pDst->polyEdge == PolyEdgeSharp)
120706f2543Smrg	    maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
121706f2543Smrg	else
122706f2543Smrg	    maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
123706f2543Smrg
124706f2543Smrg	for (; ntri; ntri--, tris++)
125706f2543Smrg	    miTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
126706f2543Smrg    }
127706f2543Smrg}
128706f2543Smrg
129706f2543Smrgvoid
130706f2543SmrgmiTriStrip (CARD8	    op,
131706f2543Smrg	    PicturePtr	    pSrc,
132706f2543Smrg	    PicturePtr	    pDst,
133706f2543Smrg	    PictFormatPtr   maskFormat,
134706f2543Smrg	    INT16	    xSrc,
135706f2543Smrg	    INT16	    ySrc,
136706f2543Smrg	    int		    npoint,
137706f2543Smrg	    xPointFixed	    *points)
138706f2543Smrg{
139706f2543Smrg    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
140706f2543Smrg    PictureScreenPtr    ps = GetPictureScreen(pScreen);
141706f2543Smrg    xTriangle		*tris, *tri;
142706f2543Smrg    int			ntri;
143706f2543Smrg
144706f2543Smrg    if (npoint < 3)
145706f2543Smrg	return;
146706f2543Smrg    ntri = npoint - 2;
147706f2543Smrg    tris = malloc(ntri * sizeof (xTriangle));
148706f2543Smrg    if (!tris)
149706f2543Smrg	return;
150706f2543Smrg    for (tri = tris; npoint >= 3; npoint--, points++, tri++)
151706f2543Smrg    {
152706f2543Smrg	tri->p1 = points[0];
153706f2543Smrg	tri->p2 = points[1];
154706f2543Smrg	tri->p3 = points[2];
155706f2543Smrg    }
156706f2543Smrg    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
157706f2543Smrg    free(tris);
158706f2543Smrg}
159706f2543Smrg
160706f2543Smrgvoid
161706f2543SmrgmiTriFan (CARD8		op,
162706f2543Smrg	  PicturePtr	pSrc,
163706f2543Smrg	  PicturePtr	pDst,
164706f2543Smrg	  PictFormatPtr	maskFormat,
165706f2543Smrg	  INT16		xSrc,
166706f2543Smrg	  INT16		ySrc,
167706f2543Smrg	  int		npoint,
168706f2543Smrg	  xPointFixed	*points)
169706f2543Smrg{
170706f2543Smrg    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
171706f2543Smrg    PictureScreenPtr    ps = GetPictureScreen(pScreen);
172706f2543Smrg    xTriangle		*tris, *tri;
173706f2543Smrg    xPointFixed		*first;
174706f2543Smrg    int			ntri;
175706f2543Smrg
176706f2543Smrg    if (npoint < 3)
177706f2543Smrg	return;
178706f2543Smrg    ntri = npoint - 2;
179706f2543Smrg    tris = malloc(ntri * sizeof (xTriangle));
180706f2543Smrg    if (!tris)
181706f2543Smrg	return;
182706f2543Smrg    first = points++;
183706f2543Smrg    for (tri = tris; npoint >= 3; npoint--, points++, tri++)
184706f2543Smrg    {
185706f2543Smrg	tri->p1 = *first;
186706f2543Smrg	tri->p2 = points[0];
187706f2543Smrg	tri->p3 = points[1];
188706f2543Smrg    }
189706f2543Smrg    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
190706f2543Smrg    free(tris);
191706f2543Smrg}
192