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