1706f2543Smrg/* 2706f2543Smrg * Copyright © 2004 Keith Packard 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Keith Packard not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Keith Packard makes no 11706f2543Smrg * representations about the suitability of this software for any purpose. It 12706f2543Smrg * is provided "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg */ 22706f2543Smrg 23706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 24706f2543Smrg#include <dix-config.h> 25706f2543Smrg#endif 26706f2543Smrg 27706f2543Smrg#include "fb.h" 28706f2543Smrg 29706f2543Smrg#include "picturestr.h" 30706f2543Smrg#include "mipict.h" 31706f2543Smrg#include "fbpict.h" 32706f2543Smrg 33706f2543Smrgvoid 34706f2543SmrgfbAddTraps (PicturePtr pPicture, 35706f2543Smrg INT16 x_off, 36706f2543Smrg INT16 y_off, 37706f2543Smrg int ntrap, 38706f2543Smrg xTrap *traps) 39706f2543Smrg{ 40706f2543Smrg int image_xoff, image_yoff; 41706f2543Smrg pixman_image_t *image = image_from_pict (pPicture, FALSE, &image_xoff, &image_yoff); 42706f2543Smrg 43706f2543Smrg if (!image) 44706f2543Smrg return; 45706f2543Smrg 46706f2543Smrg pixman_add_traps (image, x_off, y_off, ntrap, (pixman_trap_t *)traps); 47706f2543Smrg 48706f2543Smrg free_pixman_pict (pPicture, image); 49706f2543Smrg} 50706f2543Smrg 51706f2543Smrgvoid 52706f2543SmrgfbRasterizeTrapezoid (PicturePtr pPicture, 53706f2543Smrg xTrapezoid *trap, 54706f2543Smrg int x_off, 55706f2543Smrg int y_off) 56706f2543Smrg{ 57706f2543Smrg int mask_xoff, mask_yoff; 58706f2543Smrg pixman_image_t *image = image_from_pict (pPicture, FALSE, &mask_xoff, &mask_yoff); 59706f2543Smrg 60706f2543Smrg if (!image) 61706f2543Smrg return; 62706f2543Smrg 63706f2543Smrg pixman_rasterize_trapezoid (image, (pixman_trapezoid_t *)trap, x_off, y_off); 64706f2543Smrg 65706f2543Smrg free_pixman_pict (pPicture, image); 66706f2543Smrg} 67706f2543Smrg 68706f2543Smrgstatic int 69706f2543Smrg_GreaterY (xPointFixed *a, xPointFixed *b) 70706f2543Smrg{ 71706f2543Smrg if (a->y == b->y) 72706f2543Smrg return a->x > b->x; 73706f2543Smrg return a->y > b->y; 74706f2543Smrg} 75706f2543Smrg 76706f2543Smrg/* 77706f2543Smrg * Note that the definition of this function is a bit odd because 78706f2543Smrg * of the X coordinate space (y increasing downwards). 79706f2543Smrg */ 80706f2543Smrgstatic int 81706f2543Smrg_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b) 82706f2543Smrg{ 83706f2543Smrg xPointFixed ad, bd; 84706f2543Smrg 85706f2543Smrg ad.x = a->x - ref->x; 86706f2543Smrg ad.y = a->y - ref->y; 87706f2543Smrg bd.x = b->x - ref->x; 88706f2543Smrg bd.y = b->y - ref->y; 89706f2543Smrg 90706f2543Smrg return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0; 91706f2543Smrg} 92706f2543Smrg 93706f2543Smrg/* FIXME -- this could be made more efficient */ 94706f2543Smrgvoid 95706f2543SmrgfbAddTriangles (PicturePtr pPicture, 96706f2543Smrg INT16 x_off, 97706f2543Smrg INT16 y_off, 98706f2543Smrg int ntri, 99706f2543Smrg xTriangle *tris) 100706f2543Smrg{ 101706f2543Smrg xPointFixed *top, *left, *right, *tmp; 102706f2543Smrg xTrapezoid trap; 103706f2543Smrg 104706f2543Smrg for (; ntri; ntri--, tris++) 105706f2543Smrg { 106706f2543Smrg top = &tris->p1; 107706f2543Smrg left = &tris->p2; 108706f2543Smrg right = &tris->p3; 109706f2543Smrg if (_GreaterY (top, left)) { 110706f2543Smrg tmp = left; left = top; top = tmp; 111706f2543Smrg } 112706f2543Smrg if (_GreaterY (top, right)) { 113706f2543Smrg tmp = right; right = top; top = tmp; 114706f2543Smrg } 115706f2543Smrg if (_Clockwise (top, right, left)) { 116706f2543Smrg tmp = right; right = left; left = tmp; 117706f2543Smrg } 118706f2543Smrg 119706f2543Smrg /* 120706f2543Smrg * Two cases: 121706f2543Smrg * 122706f2543Smrg * + + 123706f2543Smrg * / \ / \ 124706f2543Smrg * / \ / \ 125706f2543Smrg * / + + \ 126706f2543Smrg * / -- -- \ 127706f2543Smrg * / -- -- \ 128706f2543Smrg * / --- --- \ 129706f2543Smrg * +-- --+ 130706f2543Smrg */ 131706f2543Smrg 132706f2543Smrg trap.top = top->y; 133706f2543Smrg trap.left.p1 = *top; 134706f2543Smrg trap.left.p2 = *left; 135706f2543Smrg trap.right.p1 = *top; 136706f2543Smrg trap.right.p2 = *right; 137706f2543Smrg if (right->y < left->y) 138706f2543Smrg trap.bottom = right->y; 139706f2543Smrg else 140706f2543Smrg trap.bottom = left->y; 141706f2543Smrg fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); 142706f2543Smrg if (right->y < left->y) 143706f2543Smrg { 144706f2543Smrg trap.top = right->y; 145706f2543Smrg trap.bottom = left->y; 146706f2543Smrg trap.right.p1 = *right; 147706f2543Smrg trap.right.p2 = *left; 148706f2543Smrg } 149706f2543Smrg else 150706f2543Smrg { 151706f2543Smrg trap.top = left->y; 152706f2543Smrg trap.bottom = right->y; 153706f2543Smrg trap.left.p1 = *left; 154706f2543Smrg trap.left.p2 = *right; 155706f2543Smrg } 156706f2543Smrg fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); 157706f2543Smrg } 158706f2543Smrg} 159706f2543Smrg 160