123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*
- *
- * Copyright © 2004 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include "fb.h"
- #include "picturestr.h"
- #include "mipict.h"
- #include "renderedge.h"
- #include "fbpict.h"
- void
- fbAddTraps(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
- {
- FbBits *buf;
- int bpp;
- int width;
- int stride;
- int height;
- int pxoff, pyoff;
- xFixed x_off_fixed;
- xFixed y_off_fixed;
- RenderEdge l, r;
- xFixed t, b;
- fbGetDrawable(pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
- width = pPicture->pDrawable->width;
- height = pPicture->pDrawable->height;
- x_off += pxoff;
- y_off += pyoff;
- x_off_fixed = IntToxFixed(x_off);
- y_off_fixed = IntToxFixed(y_off);
- while (ntrap--) {
- t = traps->top.y + y_off_fixed;
- if (t < 0)
- t = 0;
- t = RenderSampleCeilY(t, bpp);
- b = traps->bot.y + y_off_fixed;
- if (xFixedToInt(b) >= height)
- b = IntToxFixed(height) - 1;
- b = RenderSampleFloorY(b, bpp);
- if (b >= t) {
- /* initialize edge walkers */
- RenderEdgeInit(&l, bpp, t,
- traps->top.l + x_off_fixed,
- traps->top.y + y_off_fixed,
- traps->bot.l + x_off_fixed,
- traps->bot.y + y_off_fixed);
- RenderEdgeInit(&r, bpp, t,
- traps->top.r + x_off_fixed,
- traps->top.y + y_off_fixed,
- traps->bot.r + x_off_fixed,
- traps->bot.y + y_off_fixed);
- fbRasterizeEdges(buf, bpp, width, stride, &l, &r, t, b);
- }
- traps++;
- }
- }
- void
- fbRasterizeTrapezoid(PicturePtr pPicture,
- xTrapezoid * trap, int x_off, int y_off)
- {
- FbBits *buf;
- int bpp;
- int width;
- int stride;
- int height;
- int pxoff, pyoff;
- xFixed x_off_fixed _X_UNUSED;
- xFixed y_off_fixed;
- RenderEdge l, r;
- xFixed t, b;
- fbGetDrawable(pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
- width = pPicture->pDrawable->width;
- height = pPicture->pDrawable->height;
- x_off += pxoff;
- y_off += pyoff;
- x_off_fixed = IntToxFixed(x_off);
- y_off_fixed = IntToxFixed(y_off);
- t = trap->top + y_off_fixed;
- if (t < 0)
- t = 0;
- t = RenderSampleCeilY(t, bpp);
- b = trap->bottom + y_off_fixed;
- if (xFixedToInt(b) >= height)
- b = IntToxFixed(height) - 1;
- b = RenderSampleFloorY(b, bpp);
- if (b >= t) {
- /* initialize edge walkers */
- RenderLineFixedEdgeInit(&l, bpp, t, &trap->left, x_off, y_off);
- RenderLineFixedEdgeInit(&r, bpp, t, &trap->right, x_off, y_off);
- fbRasterizeEdges(buf, bpp, width, stride, &l, &r, t, b);
- }
- }
- static int
- _GreaterY(xPointFixed * a, xPointFixed * b)
- {
- if (a->y == b->y)
- return a->x > b->x;
- return a->y > b->y;
- }
- /*
- * Note that the definition of this function is a bit odd because
- * of the X coordinate space (y increasing downwards).
- */
- static int
- _Clockwise(xPointFixed * ref, xPointFixed * a, xPointFixed * b)
- {
- xPointFixed ad, bd;
- ad.x = a->x - ref->x;
- ad.y = a->y - ref->y;
- bd.x = b->x - ref->x;
- bd.y = b->y - ref->y;
- return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
- }
- /* FIXME -- this could be made more efficient */
- void
- fbAddTriangles(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntri, xTriangle * tris)
- {
- xPointFixed *top, *left, *right, *tmp;
- xTrapezoid trap;
- for (; ntri; ntri--, tris++) {
- top = &tris->p1;
- left = &tris->p2;
- right = &tris->p3;
- if (_GreaterY(top, left)) {
- tmp = left;
- left = top;
- top = tmp;
- }
- if (_GreaterY(top, right)) {
- tmp = right;
- right = top;
- top = tmp;
- }
- if (_Clockwise(top, right, left)) {
- tmp = right;
- right = left;
- left = tmp;
- }
- /*
- * Two cases:
- *
- * + +
- * / \ / \
- * / \ / \
- * / + + \
- * / -- -- \
- * / -- -- \
- * / --- --- \
- * +-- --+
- */
- trap.top = top->y;
- trap.left.p1 = *top;
- trap.left.p2 = *left;
- trap.right.p1 = *top;
- trap.right.p2 = *right;
- if (right->y < left->y)
- trap.bottom = right->y;
- else
- trap.bottom = left->y;
- fbRasterizeTrapezoid(pPicture, &trap, x_off, y_off);
- if (right->y < left->y) {
- trap.top = right->y;
- trap.bottom = left->y;
- trap.right.p1 = *right;
- trap.right.p2 = *left;
- }
- else {
- trap.top = left->y;
- trap.bottom = right->y;
- trap.left.p1 = *left;
- trap.left.p2 = *right;
- }
- fbRasterizeTrapezoid(pPicture, &trap, x_off, y_off);
- }
- }
|