mitri.c revision 706f2543
1/*
2 *
3 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  Keith Packard makes no
12 * representations about the suitability of this software for any purpose.  It
13 * is provided "as is" without express or implied warranty.
14 *
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24#ifdef HAVE_DIX_CONFIG_H
25#include <dix-config.h>
26#endif
27
28#include "scrnintstr.h"
29#include "gcstruct.h"
30#include "pixmapstr.h"
31#include "windowstr.h"
32#include "mi.h"
33#include "picturestr.h"
34#include "mipict.h"
35
36void
37miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds)
38{
39    bounds->x1 = xFixedToInt (points->x);
40    bounds->x2 = xFixedToInt (xFixedCeil (points->x));
41    bounds->y1 = xFixedToInt (points->y);
42    bounds->y2 = xFixedToInt (xFixedCeil (points->y));
43    points++;
44    npoint--;
45    while (npoint-- > 0)
46    {
47	INT16	x1 = xFixedToInt (points->x);
48	INT16	x2 = xFixedToInt (xFixedCeil (points->x));
49	INT16	y1 = xFixedToInt (points->y);
50	INT16	y2 = xFixedToInt (xFixedCeil (points->y));
51
52	if (x1 < bounds->x1)
53	    bounds->x1 = x1;
54	else if (x2 > bounds->x2)
55	    bounds->x2 = x2;
56	if (y1 < bounds->y1)
57	    bounds->y1 = y1;
58	else if (y2 > bounds->y2)
59	    bounds->y2 = y2;
60	points++;
61    }
62}
63
64void
65miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
66{
67    miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
68}
69
70void
71miTriangles (CARD8	    op,
72	     PicturePtr	    pSrc,
73	     PicturePtr	    pDst,
74	     PictFormatPtr  maskFormat,
75	     INT16	    xSrc,
76	     INT16	    ySrc,
77	     int	    ntri,
78	     xTriangle	    *tris)
79{
80    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
81    PictureScreenPtr    ps = GetPictureScreen(pScreen);
82
83    /*
84     * Check for solid alpha add
85     */
86    if (op == PictOpAdd && miIsSolidAlpha (pSrc))
87    {
88	(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
89    }
90    else if (maskFormat)
91    {
92	BoxRec		bounds;
93	PicturePtr	pPicture;
94	INT16		xDst, yDst;
95	INT16		xRel, yRel;
96
97	xDst = tris[0].p1.x >> 16;
98	yDst = tris[0].p1.y >> 16;
99
100	miTriangleBounds (ntri, tris, &bounds);
101	if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
102	    return;
103	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
104					 bounds.x2 - bounds.x1,
105					 bounds.y2 - bounds.y1);
106	if (!pPicture)
107	    return;
108	(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
109
110	xRel = bounds.x1 + xSrc - xDst;
111	yRel = bounds.y1 + ySrc - yDst;
112	CompositePicture (op, pSrc, pPicture, pDst,
113			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
114			  bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
115	FreePicture (pPicture, 0);
116    }
117    else
118    {
119	if (pDst->polyEdge == PolyEdgeSharp)
120	    maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
121	else
122	    maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
123
124	for (; ntri; ntri--, tris++)
125	    miTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
126    }
127}
128
129void
130miTriStrip (CARD8	    op,
131	    PicturePtr	    pSrc,
132	    PicturePtr	    pDst,
133	    PictFormatPtr   maskFormat,
134	    INT16	    xSrc,
135	    INT16	    ySrc,
136	    int		    npoint,
137	    xPointFixed	    *points)
138{
139    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
140    PictureScreenPtr    ps = GetPictureScreen(pScreen);
141    xTriangle		*tris, *tri;
142    int			ntri;
143
144    if (npoint < 3)
145	return;
146    ntri = npoint - 2;
147    tris = malloc(ntri * sizeof (xTriangle));
148    if (!tris)
149	return;
150    for (tri = tris; npoint >= 3; npoint--, points++, tri++)
151    {
152	tri->p1 = points[0];
153	tri->p2 = points[1];
154	tri->p3 = points[2];
155    }
156    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
157    free(tris);
158}
159
160void
161miTriFan (CARD8		op,
162	  PicturePtr	pSrc,
163	  PicturePtr	pDst,
164	  PictFormatPtr	maskFormat,
165	  INT16		xSrc,
166	  INT16		ySrc,
167	  int		npoint,
168	  xPointFixed	*points)
169{
170    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
171    PictureScreenPtr    ps = GetPictureScreen(pScreen);
172    xTriangle		*tris, *tri;
173    xPointFixed		*first;
174    int			ntri;
175
176    if (npoint < 3)
177	return;
178    ntri = npoint - 2;
179    tris = malloc(ntri * sizeof (xTriangle));
180    if (!tris)
181	return;
182    first = points++;
183    for (tri = tris; npoint >= 3; npoint--, points++, tri++)
184    {
185	tri->p1 = *first;
186	tri->p2 = points[0];
187	tri->p3 = points[1];
188    }
189    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
190    free(tris);
191}
192