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