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 "servermd.h" 33706f2543Smrg#include "mi.h" 34706f2543Smrg#include "picturestr.h" 35706f2543Smrg#include "mipict.h" 36706f2543Smrg 37706f2543SmrgPicturePtr 38706f2543SmrgmiCreateAlphaPicture (ScreenPtr pScreen, 39706f2543Smrg PicturePtr pDst, 40706f2543Smrg PictFormatPtr pPictFormat, 41706f2543Smrg CARD16 width, 42706f2543Smrg CARD16 height) 43706f2543Smrg{ 44706f2543Smrg PixmapPtr pPixmap; 45706f2543Smrg PicturePtr pPicture; 46706f2543Smrg GCPtr pGC; 47706f2543Smrg int error; 48706f2543Smrg xRectangle rect; 49706f2543Smrg 50706f2543Smrg if (width > 32767 || height > 32767) 51706f2543Smrg return 0; 52706f2543Smrg 53706f2543Smrg if (!pPictFormat) 54706f2543Smrg { 55706f2543Smrg if (pDst->polyEdge == PolyEdgeSharp) 56706f2543Smrg pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1); 57706f2543Smrg else 58706f2543Smrg pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8); 59706f2543Smrg if (!pPictFormat) 60706f2543Smrg return 0; 61706f2543Smrg } 62706f2543Smrg 63706f2543Smrg pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 64706f2543Smrg pPictFormat->depth, 0); 65706f2543Smrg if (!pPixmap) 66706f2543Smrg return 0; 67706f2543Smrg pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); 68706f2543Smrg if (!pGC) 69706f2543Smrg { 70706f2543Smrg (*pScreen->DestroyPixmap) (pPixmap); 71706f2543Smrg return 0; 72706f2543Smrg } 73706f2543Smrg ValidateGC (&pPixmap->drawable, pGC); 74706f2543Smrg rect.x = 0; 75706f2543Smrg rect.y = 0; 76706f2543Smrg rect.width = width; 77706f2543Smrg rect.height = height; 78706f2543Smrg (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect); 79706f2543Smrg FreeScratchGC (pGC); 80706f2543Smrg pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat, 81706f2543Smrg 0, 0, serverClient, &error); 82706f2543Smrg (*pScreen->DestroyPixmap) (pPixmap); 83706f2543Smrg return pPicture; 84706f2543Smrg} 85706f2543Smrg 86706f2543Smrgstatic xFixed 87706f2543SmrgmiLineFixedX (xLineFixed *l, xFixed y, Bool ceil) 88706f2543Smrg{ 89706f2543Smrg xFixed dx = l->p2.x - l->p1.x; 90706f2543Smrg xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx; 91706f2543Smrg xFixed dy = l->p2.y - l->p1.y; 92706f2543Smrg if (ceil) 93706f2543Smrg ex += (dy - 1); 94706f2543Smrg return l->p1.x + (xFixed) (ex / dy); 95706f2543Smrg} 96706f2543Smrg 97706f2543Smrgvoid 98706f2543SmrgmiTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box) 99706f2543Smrg{ 100706f2543Smrg box->y1 = MAXSHORT; 101706f2543Smrg box->y2 = MINSHORT; 102706f2543Smrg box->x1 = MAXSHORT; 103706f2543Smrg box->x2 = MINSHORT; 104706f2543Smrg for (; ntrap; ntrap--, traps++) 105706f2543Smrg { 106706f2543Smrg INT16 x1, y1, x2, y2; 107706f2543Smrg 108706f2543Smrg if (!xTrapezoidValid(traps)) 109706f2543Smrg continue; 110706f2543Smrg y1 = xFixedToInt (traps->top); 111706f2543Smrg if (y1 < box->y1) 112706f2543Smrg box->y1 = y1; 113706f2543Smrg 114706f2543Smrg y2 = xFixedToInt (xFixedCeil (traps->bottom)); 115706f2543Smrg if (y2 > box->y2) 116706f2543Smrg box->y2 = y2; 117706f2543Smrg 118706f2543Smrg x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE), 119706f2543Smrg miLineFixedX (&traps->left, traps->bottom, FALSE))); 120706f2543Smrg if (x1 < box->x1) 121706f2543Smrg box->x1 = x1; 122706f2543Smrg 123706f2543Smrg x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE), 124706f2543Smrg miLineFixedX (&traps->right, traps->bottom, TRUE)))); 125706f2543Smrg if (x2 > box->x2) 126706f2543Smrg box->x2 = x2; 127706f2543Smrg } 128706f2543Smrg} 129706f2543Smrg 130706f2543Smrgvoid 131706f2543SmrgmiTrapezoids (CARD8 op, 132706f2543Smrg PicturePtr pSrc, 133706f2543Smrg PicturePtr pDst, 134706f2543Smrg PictFormatPtr maskFormat, 135706f2543Smrg INT16 xSrc, 136706f2543Smrg INT16 ySrc, 137706f2543Smrg int ntrap, 138706f2543Smrg xTrapezoid *traps) 139706f2543Smrg{ 140706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 141706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 142706f2543Smrg 143706f2543Smrg /* 144706f2543Smrg * Check for solid alpha add 145706f2543Smrg */ 146706f2543Smrg if (op == PictOpAdd && miIsSolidAlpha (pSrc)) 147706f2543Smrg { 148706f2543Smrg for (; ntrap; ntrap--, traps++) 149706f2543Smrg (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0); 150706f2543Smrg } 151706f2543Smrg else if (maskFormat) 152706f2543Smrg { 153706f2543Smrg PicturePtr pPicture; 154706f2543Smrg BoxRec bounds; 155706f2543Smrg INT16 xDst, yDst; 156706f2543Smrg INT16 xRel, yRel; 157706f2543Smrg 158706f2543Smrg xDst = traps[0].left.p1.x >> 16; 159706f2543Smrg yDst = traps[0].left.p1.y >> 16; 160706f2543Smrg 161706f2543Smrg miTrapezoidBounds (ntrap, traps, &bounds); 162706f2543Smrg if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) 163706f2543Smrg return; 164706f2543Smrg pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat, 165706f2543Smrg bounds.x2 - bounds.x1, 166706f2543Smrg bounds.y2 - bounds.y1); 167706f2543Smrg if (!pPicture) 168706f2543Smrg return; 169706f2543Smrg for (; ntrap; ntrap--, traps++) 170706f2543Smrg (*ps->RasterizeTrapezoid) (pPicture, traps, 171706f2543Smrg -bounds.x1, -bounds.y1); 172706f2543Smrg xRel = bounds.x1 + xSrc - xDst; 173706f2543Smrg yRel = bounds.y1 + ySrc - yDst; 174706f2543Smrg CompositePicture (op, pSrc, pPicture, pDst, 175706f2543Smrg xRel, yRel, 0, 0, bounds.x1, bounds.y1, 176706f2543Smrg bounds.x2 - bounds.x1, 177706f2543Smrg bounds.y2 - bounds.y1); 178706f2543Smrg FreePicture (pPicture, 0); 179706f2543Smrg } 180706f2543Smrg else 181706f2543Smrg { 182706f2543Smrg if (pDst->polyEdge == PolyEdgeSharp) 183706f2543Smrg maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1); 184706f2543Smrg else 185706f2543Smrg maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8); 186706f2543Smrg for (; ntrap; ntrap--, traps++) 187706f2543Smrg miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps); 188706f2543Smrg } 189706f2543Smrg} 190