diff options
Diffstat (limited to 'xorg-server/hw/xfree86/xaa/xaaFillPoly.c')
-rw-r--r-- | xorg-server/hw/xfree86/xaa/xaaFillPoly.c | 1953 |
1 files changed, 991 insertions, 962 deletions
diff --git a/xorg-server/hw/xfree86/xaa/xaaFillPoly.c b/xorg-server/hw/xfree86/xaa/xaaFillPoly.c index b8347b336..0cdedf57e 100644 --- a/xorg-server/hw/xfree86/xaa/xaaFillPoly.c +++ b/xorg-server/hw/xfree86/xaa/xaaFillPoly.c @@ -1,962 +1,991 @@ -
-/*
- * Copyright 1996 The XFree86 Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-/*
- * Written by Mark Vojkovich. Loosly based on an original version
- * written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net) which
- * only did solid rectangles and didn't have trapezoid support.
- *
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "xf86str.h"
-#include "mi.h"
-#include "micoord.h"
-
-#include "xaa.h"
-#include "xaalocal.h"
-
-#define POLY_USE_MI 0
-#define POLY_FULLY_CLIPPED 1
-#define POLY_IS_EASY 2
-
-
-#define Setup(c,x,vertex,dx,dy,e,sign,step,DX) {\
- x = intToX(vertex); \
- if ((dy = intToY(c) - y)) { \
- DX = dx = intToX(c) - x; \
- step = 0; \
- if (dx >= 0) \
- { \
- e = 0; \
- sign = 1; \
- if (dx >= dy) {\
- step = dx / dy; \
- dx %= dy; \
- } \
- } \
- else \
- { \
- e = 1 - dy; \
- sign = -1; \
- dx = -dx; \
- if (dx >= dy) { \
- step = - (dx / dy); \
- dx %= dy; \
- } \
- } \
- } \
- x += origin; \
- vertex = c; \
-}
-
-#define Step(x,dx,dy,e,sign,step) {\
- x += step; \
- if ((e += dx) > 0) \
- { \
- x += sign; \
- e -= dy; \
- } \
-}
-
-#define FixError(x, dx, dy, e, sign, step, h) { \
- e += (h) * dx; \
- x += (h) * step; \
- if(e > 0) { \
- x += e * sign/dy; \
- e %= dy; \
- if(e) { \
- x += sign; \
- e -= dy; \
- } \
- } \
-}
-
-
-/*
- XAAIsEasyPoly -
-
- Checks CoordModeOrigin one rect polygons to see if we need
- to use Mi.
- Returns: POLY_USE_MI, POLY_FULLY_CLIPPED or POLY_IS_EASY
- as well as the pointer to the "top" point and the y
- extents.
-*/
-
-int
-XAAIsEasyPolygon(
- DDXPointPtr ptsIn,
- int count,
- BoxPtr extents,
- int origin,
- DDXPointPtr *topPoint, /* return */
- int *topY, int *bottomY, /* return */
- int shape
-){
- int c = 0, vertex1, vertex2;
-
- *topY = 32767;
- *bottomY = 0;
-
- origin -= (origin & 0x8000) << 1;
- vertex1 = extents->x1 - origin;
- vertex2 = extents->x2 - origin /* - 0x00010001 */;
- /* I think this was an error in cfb ^ */
-
- if (shape == Convex) {
- while (count--) {
- c = *((int*)ptsIn);
- if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
- return POLY_USE_MI;
-
- c = intToY(c);
- if (c < *topY) {
- *topY = c;
- *topPoint = ptsIn;
- }
- ptsIn++;
- if (c > *bottomY) *bottomY = c;
- }
- } else {
- int yFlip = 0;
- int dx2, dx1, x1, x2;
-
- x2 = x1 = -1;
- dx2 = dx1 = 1;
-
- while (count--) {
- c = *((int*)ptsIn);
- if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
- return POLY_USE_MI;
- c = intToY(c);
- if (c < *topY) {
- *topY = c;
- *topPoint = ptsIn;
- }
- ptsIn++;
- if (c > *bottomY) *bottomY = c;
- if (c == x1)
- continue;
- if (dx1 > 0) {
- if (x2 < 0) x2 = c;
- else dx2 = dx1 = (c - x1) >> 31;
- } else if ((c - x1) >> 31 != dx1) {
- dx1 = ~dx1;
- yFlip++;
- }
- x1 = c;
- }
- x1 = (x2 - c) >> 31;
- if (x1 != dx1) yFlip++;
- if (x1 != dx2) yFlip++;
- if (yFlip != 2) {
- if(*topY == *bottomY)
- return POLY_FULLY_CLIPPED;
- else
- return POLY_USE_MI;
- }
- }
- if (*topY == *bottomY)
- return POLY_FULLY_CLIPPED;
-
- return POLY_IS_EASY;
-}
-
-void
-XAAFillPolygonSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- int origin, vertex1, vertex2;
- int *vertex1p, *vertex2p, *endp;
- int x1 = 0, x2 = 0;
- int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
- int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
- int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
- int c, y, maxy, h, yoffset;
- DDXPointPtr topPoint;
-
- if(!RegionNumRects(pGC->pCompositeClip))
- return;
-
- if (mode == CoordModePrevious) {
- register DDXPointPtr ppt = ptsIn + 1;
-
- for (origin = 1; origin < count; origin++, ppt++) {
- ppt->x += (ppt-1)->x;
- ppt->y += (ppt-1)->y;
- }
- mode = CoordModeOrigin;
- }
-
- if (RegionNumRects(pGC->pCompositeClip) != 1) {
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
- origin = coordToInt(pDraw->x, pDraw->y);
-
- switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
- origin, &topPoint, &y, &maxy, shape) ) {
- case POLY_USE_MI:
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- case POLY_FULLY_CLIPPED:
- return;
- }
-
- endp = (int*)ptsIn + count;
- vertex2p = vertex1p = (int *)topPoint;
- origin = pDraw->x;
- yoffset = pDraw->y;
- vertex2 = vertex1 = *vertex2p++;
- if (vertex2p == endp)
- vertex2p = (int *) ptsIn;
-
- (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
- pGC->planemask);
-
- while(1) {
- if (y == intToY(vertex1)) {
- do {
- if (vertex1p == (int *) ptsIn)
- vertex1p = endp;
- c = *--vertex1p;
- Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
- } while (y >= intToY(vertex1));
- h = dy1;
- } else {
- Step(x1,dx1,dy1,e1,sign1,step1)
- h = intToY(vertex1) - y;
- }
- if (y == intToY(vertex2)) {
- do {
- c = *vertex2p++;
- if (vertex2p == endp)
- vertex2p = (int *) ptsIn;
- Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
- } while (y >= intToY(vertex2));
- if (dy2 < h)
- h = dy2;
- } else {
- Step(x2,dx2,dy2,e2,sign2,step2)
- if ((c = (intToY(vertex2) - y)) < h)
- h = c;
- }
-
- /* fill spans for this segment */
- if(DX1 | DX2) {
- if(infoRec->SubsequentSolidFillTrap && (h > 6)) {
- if(x1 == x2) {
- while(x1 == x2) {
- y++;
- if (!--h) break;
- Step(x1,dx1,dy1,e1,sign1,step1)
- Step(x2,dx2,dy2,e2,sign2,step2)
- }
- if(y == maxy) break;
- if(!h) continue;
- }
-
- if(x1 < x2)
- (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
- y + yoffset, h,
- x1, DX1, dy1, e1,
- x2 - 1, DX2, dy2, e2);
- else
- (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
- y + yoffset, h,
- x2, DX2, dy2, e2,
- x1 - 1, DX1, dy1, e1);
- y += h;
- if(--h) {
- FixError(x1,dx1,dy1,e1,sign1,step1,h);
- FixError(x2,dx2,dy2,e2,sign2,step2,h);
- h = 0;
- }
- } else {
- while(1) {
- if (x2 > x1)
- (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
- x1, y + yoffset, x2 - x1, 1);
- else if (x1 > x2)
- (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
- x2, y + yoffset, x1 - x2, 1);
- y++;
- if (!--h) break;
- Step(x1,dx1,dy1,e1,sign1,step1)
- Step(x2,dx2,dy2,e2,sign2,step2)
- }
- }
- } else {
- if (x2 > x1)
- (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
- x1, y + yoffset, x2 - x1, h);
- else if (x1 > x2)
- (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
- x2, y + yoffset, x1 - x2, h);
-
- y += h;
- h = 0;
- }
- if (y == maxy) break;
- }
- SET_SYNC_FLAG(infoRec);
-}
-
-
-
-
-void
-XAAFillPolygonHelper(
- ScrnInfoPtr pScrn,
- DDXPointPtr ptsIn,
- int count,
- DDXPointPtr topPoint,
- int y,
- int maxy,
- int origin,
- RectFuncPtr RectFunc,
- TrapFuncPtr TrapFunc,
- int xorg,
- int yorg,
- XAACacheInfoPtr pCache
-){
- int *vertex1p, *vertex2p, *endp;
- int vertex1, vertex2;
- int x1 = 0, x2 = 0;
- int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
- int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
- int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
- int c, h, yoffset;
-
-
- endp = (int*)ptsIn + count;
- vertex2p = vertex1p = (int *)topPoint;
- yoffset = intToY(origin);
- origin = intToX(origin);
- vertex2 = vertex1 = *vertex2p++;
- if (vertex2p == endp)
- vertex2p = (int *)ptsIn;
-
- while(1) {
- if (y == intToY(vertex1)) {
- do {
- if (vertex1p == (int *) ptsIn)
- vertex1p = endp;
- c = *--vertex1p;
- Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
- } while (y >= intToY(vertex1));
- h = dy1;
- } else {
- Step(x1,dx1,dy1,e1,sign1,step1)
- h = intToY(vertex1) - y;
- }
- if (y == intToY(vertex2)) {
- do {
- c = *vertex2p++;
- if (vertex2p == endp)
- vertex2p = (int *) ptsIn;
- Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
- } while (y >= intToY(vertex2));
- if (dy2 < h)
- h = dy2;
- } else {
- Step(x2,dx2,dy2,e2,sign2,step2)
- if ((c = (intToY(vertex2) - y)) < h)
- h = c;
- }
-
- /* fill spans for this segment */
- if(DX1 | DX2) {
- if(TrapFunc && (h > 6)) {
- if(x1 == x2) {
- while(x1 == x2) {
- y++;
- if (!--h) break;
- Step(x1,dx1,dy1,e1,sign1,step1)
- Step(x2,dx2,dy2,e2,sign2,step2)
- }
- if(y == maxy) break;
- if(!h) continue;
- }
-
- if(x1 < x2)
- (*TrapFunc)(pScrn, y + yoffset, h,
- x1, DX1, dy1, e1,
- x2 - 1, DX2, dy2, e2, xorg, yorg, pCache);
- else
- (*TrapFunc)(pScrn, y + yoffset, h,
- x2, DX2, dy2, e2,
- x1 - 1, DX1, dy1, e1, xorg, yorg, pCache);
- y += h;
- if(--h) {
- FixError(x1,dx1,dy1,e1,sign1,step1,h);
- FixError(x2,dx2,dy2,e2,sign2,step2,h);
- h = 0;
- }
- } else {
- while(1) {
- if (x2 > x1)
- (*RectFunc)(pScrn,
- x1, y + yoffset, x2 - x1, 1, xorg, yorg, pCache);
- else if (x1 > x2)
- (*RectFunc)(pScrn,
- x2, y + yoffset, x1 - x2, 1, xorg, yorg, pCache);
- y++;
- if (!--h) break;
- Step(x1,dx1,dy1,e1,sign1,step1)
- Step(x2,dx2,dy2,e2,sign2,step2)
- }
- }
- } else {
- if (x2 > x1)
- (*RectFunc)(pScrn,
- x1, y + yoffset, x2 - x1, h, xorg, yorg, pCache);
- else if (x1 > x2)
- (*RectFunc)(pScrn,
- x2, y + yoffset, x1 - x2, h, xorg, yorg, pCache);
-
- y += h;
- h = 0;
- }
- if (y == maxy) break;
- }
-}
-
- /*****************\
- | Solid Helpers |
- \*****************/
-
-static void
-SolidTrapHelper(
- ScrnInfoPtr pScrn,
- int y, int h,
- int x1, int dx1, int dy1, int e1,
- int x2, int dx2, int dy2, int e2,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->SubsequentSolidFillTrap) (pScrn,
- y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
-}
-
-static void
-SolidRectHelper (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
-}
-
-
- /*********************\
- | Mono 8x8 Patterns |
- \*********************/
-
-static void
-Mono8x8PatternTrapHelper_ScreenOrigin(
- ScrnInfoPtr pScrn,
- int y, int h,
- int x1, int dx1, int dy1, int e1,
- int x2, int dx2, int dy2, int e2,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg,
- y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
-}
-
-static void
-Mono8x8PatternRectHelper_ScreenOrigin (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
- x, y, w, h);
-}
-
-static void
-Mono8x8PatternRectHelper (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- xorg = (x - xorg) & 0x07;
- yorg = (y - yorg) & 0x07;
-
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_BITS) {
- int patx = pCache->pat0;
- int paty = pCache->pat1;
- XAARotateMonoPattern(&patx, &paty, xorg, yorg,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- xorg = patx; yorg = paty;
- } else {
- int slot = (yorg << 3) + xorg;
- xorg = pCache->x + pCache->offsets[slot].x;
- yorg = pCache->y + pCache->offsets[slot].y;
- }
- }
-
-
- (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
- x, y, w, h);
-}
-
-
-
- /****************\
- | Cache Expand |
- \****************/
-
-
-static void
-CacheExpandRectHelper (
- ScrnInfoPtr pScrn,
- int X, int Y, int Width, int Height,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
- int cacheWidth;
-
- cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
- infoRec->CacheColorExpandDensity;
-
- phaseY = (Y - yorg) % pCache->orig_h;
- if(phaseY < 0) phaseY += pCache->orig_h;
- phaseX = (X - xorg) % pCache->orig_w;
- if(phaseX < 0) phaseX += pCache->orig_w;
-
- while(1) {
- w = Width; skipleft = phaseX; x = X;
- blit_h = pCache->h - phaseY;
- if(blit_h > Height) blit_h = Height;
-
- while(1) {
- blit_w = cacheWidth - skipleft;
- if(blit_w > w) blit_w = w;
- (*infoRec->SubsequentScreenToScreenColorExpandFill)(
- pScrn, x, Y, blit_w, blit_h,
- pCache->x, pCache->y + phaseY, skipleft);
- w -= blit_w;
- if(!w) break;
- x += blit_w;
- skipleft = (skipleft + blit_w) % pCache->orig_w;
- }
- Height -= blit_h;
- if(!Height) break;
- Y += blit_h;
- phaseY = (phaseY + blit_h) % pCache->orig_h;
- }
-}
-
-
-
- /**************\
- | Cache Blit |
- \**************/
-
-
-static void
-CacheBltRectHelper (
- ScrnInfoPtr pScrn,
- int X, int Y, int Width, int Height,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
-
- phaseY = (Y - yorg) % pCache->orig_h;
- if(phaseY < 0) phaseY += pCache->orig_h;
- phaseX = (X - xorg) % pCache->orig_w;
- if(phaseX < 0) phaseX += pCache->orig_w;
-
- while(1) {
- w = Width; skipleft = phaseX; x = X;
- blit_h = pCache->h - phaseY;
- if(blit_h > Height) blit_h = Height;
-
- while(1) {
- blit_w = pCache->w - skipleft;
- if(blit_w > w) blit_w = w;
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
- pCache->x + skipleft, pCache->y + phaseY,
- x, Y, blit_w, blit_h);
- w -= blit_w;
- if(!w) break;
- x += blit_w;
- skipleft = (skipleft + blit_w) % pCache->orig_w;
- }
- Height -= blit_h;
- if(!Height) break;
- Y += blit_h;
- phaseY = (phaseY + blit_h) % pCache->orig_h;
- }
-}
-
-
- /**********************\
- | Stippled Polygons |
- \**********************/
-
-
-void
-XAAFillPolygonStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
- int origin, type, patx, paty, fg, bg;
- int y, maxy, xorg, yorg;
- DDXPointPtr topPoint;
- XAACacheInfoPtr pCache = NULL;
- RectFuncPtr RectFunc = NULL;
- TrapFuncPtr TrapFunc = NULL;
-
- if(!RegionNumRects(pGC->pCompositeClip))
- return;
-
- if (mode == CoordModePrevious) {
- register DDXPointPtr ppt = ptsIn + 1;
-
- for (origin = 1; origin < count; origin++, ppt++) {
- ppt->x += (ppt-1)->x;
- ppt->y += (ppt-1)->y;
- }
- mode = CoordModeOrigin;
- }
-
- if (RegionNumRects(pGC->pCompositeClip) != 1) {
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
-
- if(pGC->fillStyle == FillStippled) {
- type = (*infoRec->StippledFillChooser)(pGC);
- fg = pGC->fgPixel; bg = -1;
- } else {
- type = (*infoRec->OpaqueStippledFillChooser)(pGC);
- fg = pGC->fgPixel; bg = pGC->bgPixel;
- }
-
-
- if(!type) {
- (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
- if((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) {
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
- origin = pDraw->x;
-
- switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
- origin, &topPoint, &y, &maxy, shape) ) {
- case POLY_USE_MI:
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- case POLY_FULLY_CLIPPED:
- return;
- }
-
- xorg = (pDraw->x + pGC->patOrg.x);
- yorg = (pDraw->y + pGC->patOrg.y);
-
-
- if((fg == bg) && (bg != -1) && infoRec->SetupForSolidFill) {
-
- (*infoRec->SetupForSolidFill)(infoRec->pScrn, fg,
- pGC->alu, pGC->planemask);
-
- RectFunc = SolidRectHelper;
- TrapFunc = infoRec->SubsequentSolidFillTrap ? SolidTrapHelper : NULL;
- } else
- switch(type) {
- case DO_MONO_8x8:
- patx = pPriv->pattern0; paty = pPriv->pattern1;
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_SCREEN_ORIGIN) {
- xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_BITS) {
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
- XAARotateMonoPattern(&patx, &paty, xorg, yorg,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- xorg = patx; yorg = paty;
- }
- } else {
- XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
- infoRec->pScrn, patx, paty);
- patx = pCache->x; paty = pCache->y;
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
- int slot = (yorg << 3) + xorg;
- patx += pCache->offsets[slot].x;
- paty += pCache->offsets[slot].y;
- xorg = patx; yorg = paty;
- }
- }
- RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
- if(infoRec->SubsequentMono8x8PatternFillTrap)
- TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
- } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_BITS)){
- pCache = (*infoRec->CacheMono8x8Pattern)(
- infoRec->pScrn, patx, paty);
- patx = pCache->x; paty = pCache->y;
- } else {
- pCache = &(infoRec->ScratchCacheInfoRec);
- pCache->pat0 = patx;
- pCache->pat1 = paty;
- }
- RectFunc = Mono8x8PatternRectHelper;
- }
-
- (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
- patx, paty, fg, bg, pGC->alu, pGC->planemask);
- break;
- case DO_CACHE_EXPAND:
- pCache = (*infoRec->CacheMonoStipple)(infoRec->pScrn, pGC->stipple);
-
- (*infoRec->SetupForScreenToScreenColorExpandFill)(
- infoRec->pScrn, fg, bg, pGC->alu, pGC->planemask);
-
- RectFunc = CacheExpandRectHelper;
- break;
- case DO_CACHE_BLT:
- pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
- fg, bg);
- (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
- pGC->alu, pGC->planemask, pCache->trans_color);
-
- RectFunc = CacheBltRectHelper;
- break;
- default:
- return;
- }
-
-
- XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
- y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
-
- SET_SYNC_FLAG(infoRec);
-}
-
-
-
-
- /*******************\
- | Tiled Polygons |
- \*******************/
-
-
-void
-XAAFillPolygonTiled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
- int origin, type, patx, paty;
- int y, maxy, xorg, yorg;
- DDXPointPtr topPoint;
- XAACacheInfoPtr pCache = NULL;
- RectFuncPtr RectFunc = NULL;
- TrapFuncPtr TrapFunc = NULL;
-
- if(!RegionNumRects(pGC->pCompositeClip))
- return;
-
- if (mode == CoordModePrevious) {
- register DDXPointPtr ppt = ptsIn + 1;
-
- for (origin = 1; origin < count; origin++, ppt++) {
- ppt->x += (ppt-1)->x;
- ppt->y += (ppt-1)->y;
- }
- mode = CoordModeOrigin;
- }
-
- if (RegionNumRects(pGC->pCompositeClip) != 1) {
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
-
- type = (*infoRec->TiledFillChooser)(pGC);
-
- if(!type || (type == DO_IMAGE_WRITE)) {
- (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
- if(type == DO_COLOR_8x8) {
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- return;
- }
-
- origin = pDraw->x;
-
- switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
- origin, &topPoint, &y, &maxy, shape) ) {
- case POLY_USE_MI:
- miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
- case POLY_FULLY_CLIPPED:
- return;
- }
-
- xorg = (pDraw->x + pGC->patOrg.x);
- yorg = (pDraw->y + pGC->patOrg.y);
-
- switch(type) {
- case DO_MONO_8x8:
- patx = pPriv->pattern0; paty = pPriv->pattern1;
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_SCREEN_ORIGIN) {
- xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_BITS) {
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
- XAARotateMonoPattern(&patx, &paty, xorg, yorg,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- xorg = patx; yorg = paty;
- }
- } else {
- XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
- infoRec->pScrn, patx, paty);
- patx = pCache->x; paty = pCache->y;
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
- int slot = (yorg << 3) + xorg;
- patx += pCache->offsets[slot].x;
- paty += pCache->offsets[slot].y;
- xorg = patx; yorg = paty;
- }
- }
- RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
- if(infoRec->SubsequentMono8x8PatternFillTrap)
- TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
- } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
- if(!(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_BITS)){
- pCache = (*infoRec->CacheMono8x8Pattern)(
- infoRec->pScrn, patx, paty);
- patx = pCache->x; paty = pCache->y;
- }
- else {
- pCache = &(infoRec->ScratchCacheInfoRec);
- pCache->pat0 = patx;
- pCache->pat1 = paty;
- }
- RectFunc = Mono8x8PatternRectHelper;
- }
-
- (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
- patx, paty, pPriv->fg, pPriv->bg, pGC->alu, pGC->planemask);
- break;
- case DO_CACHE_BLT:
- pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
- (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
- pGC->alu, pGC->planemask, -1);
-
- RectFunc = CacheBltRectHelper;
- break;
- case DO_PIXMAP_COPY:
- pCache = &(infoRec->ScratchCacheInfoRec);
- pCache->x = pPriv->offscreenArea->box.x1;
- pCache->y = pPriv->offscreenArea->box.y1;
- pCache->w = pCache->orig_w =
- pPriv->offscreenArea->box.x2 - pCache->x;
- pCache->h = pCache->orig_h =
- pPriv->offscreenArea->box.y2 - pCache->y;
-
- (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
- pGC->alu, pGC->planemask, -1);
-
- RectFunc = CacheBltRectHelper;
- break;
- default:
- return;
- }
-
- XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
- y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
-
- SET_SYNC_FLAG(infoRec);
-}
-
-
+ +/* + * Copyright 1996 The XFree86 Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +/* + * Written by Mark Vojkovich. Loosly based on an original version + * written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net) which + * only did solid rectangles and didn't have trapezoid support. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" + +#include <X11/X.h> +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "xf86str.h" +#include "mi.h" +#include "micoord.h" + +#include "xaa.h" +#include "xaalocal.h" + +#define POLY_USE_MI 0 +#define POLY_FULLY_CLIPPED 1 +#define POLY_IS_EASY 2 + +#define Setup(c,x,vertex,dx,dy,e,sign,step,DX) {\ + x = intToX(vertex); \ + if ((dy = intToY(c) - y)) { \ + DX = dx = intToX(c) - x; \ + step = 0; \ + if (dx >= 0) \ + { \ + e = 0; \ + sign = 1; \ + if (dx >= dy) {\ + step = dx / dy; \ + dx %= dy; \ + } \ + } \ + else \ + { \ + e = 1 - dy; \ + sign = -1; \ + dx = -dx; \ + if (dx >= dy) { \ + step = - (dx / dy); \ + dx %= dy; \ + } \ + } \ + } \ + x += origin; \ + vertex = c; \ +} + +#define Step(x,dx,dy,e,sign,step) {\ + x += step; \ + if ((e += dx) > 0) \ + { \ + x += sign; \ + e -= dy; \ + } \ +} + +#define FixError(x, dx, dy, e, sign, step, h) { \ + e += (h) * dx; \ + x += (h) * step; \ + if(e > 0) { \ + x += e * sign/dy; \ + e %= dy; \ + if(e) { \ + x += sign; \ + e -= dy; \ + } \ + } \ +} + +/* + XAAIsEasyPoly - + + Checks CoordModeOrigin one rect polygons to see if we need + to use Mi. + Returns: POLY_USE_MI, POLY_FULLY_CLIPPED or POLY_IS_EASY + as well as the pointer to the "top" point and the y + extents. +*/ + +int +XAAIsEasyPolygon(DDXPointPtr ptsIn, int count, BoxPtr extents, int origin, DDXPointPtr * topPoint, /* return */ + int *topY, int *bottomY, /* return */ + int shape) +{ + int c = 0, vertex1, vertex2; + + *topY = 32767; + *bottomY = 0; + + origin -= (origin & 0x8000) << 1; + vertex1 = extents->x1 - origin; + vertex2 = extents->x2 - origin /* - 0x00010001 */ ; + /* I think this was an error in cfb ^ */ + + if (shape == Convex) { + while (count--) { + c = *((int *) ptsIn); + if (((c - vertex1) | (vertex2 - c)) & 0x80008000) + return POLY_USE_MI; + + c = intToY(c); + if (c < *topY) { + *topY = c; + *topPoint = ptsIn; + } + ptsIn++; + if (c > *bottomY) + *bottomY = c; + } + } + else { + int yFlip = 0; + int dx2, dx1, x1, x2; + + x2 = x1 = -1; + dx2 = dx1 = 1; + + while (count--) { + c = *((int *) ptsIn); + if (((c - vertex1) | (vertex2 - c)) & 0x80008000) + return POLY_USE_MI; + c = intToY(c); + if (c < *topY) { + *topY = c; + *topPoint = ptsIn; + } + ptsIn++; + if (c > *bottomY) + *bottomY = c; + if (c == x1) + continue; + if (dx1 > 0) { + if (x2 < 0) + x2 = c; + else + dx2 = dx1 = (c - x1) >> 31; + } + else if ((c - x1) >> 31 != dx1) { + dx1 = ~dx1; + yFlip++; + } + x1 = c; + } + x1 = (x2 - c) >> 31; + if (x1 != dx1) + yFlip++; + if (x1 != dx2) + yFlip++; + if (yFlip != 2) { + if (*topY == *bottomY) + return POLY_FULLY_CLIPPED; + else + return POLY_USE_MI; + } + } + if (*topY == *bottomY) + return POLY_FULLY_CLIPPED; + + return POLY_IS_EASY; +} + +void +XAAFillPolygonSolid(DrawablePtr pDraw, + GCPtr pGC, + int shape, int mode, int count, DDXPointPtr ptsIn) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + int origin, vertex1, vertex2; + int *vertex1p, *vertex2p, *endp; + int x1 = 0, x2 = 0; + int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; + int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0; + int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0; + int c, y, maxy, h, yoffset; + DDXPointPtr topPoint; + + if (!RegionNumRects(pGC->pCompositeClip)) + return; + + if (mode == CoordModePrevious) { + register DDXPointPtr ppt = ptsIn + 1; + + for (origin = 1; origin < count; origin++, ppt++) { + ppt->x += (ppt - 1)->x; + ppt->y += (ppt - 1)->y; + } + mode = CoordModeOrigin; + } + + if (RegionNumRects(pGC->pCompositeClip) != 1) { + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + origin = coordToInt(pDraw->x, pDraw->y); + + switch (XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents, + origin, &topPoint, &y, &maxy, shape)) { + case POLY_USE_MI: + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + case POLY_FULLY_CLIPPED: + return; + } + + endp = (int *) ptsIn + count; + vertex2p = vertex1p = (int *) topPoint; + origin = pDraw->x; + yoffset = pDraw->y; + vertex2 = vertex1 = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; + + (*infoRec->SetupForSolidFill) (infoRec->pScrn, pGC->fgPixel, pGC->alu, + pGC->planemask); + + while (1) { + if (y == intToY(vertex1)) { + do { + if (vertex1p == (int *) ptsIn) + vertex1p = endp; + c = *--vertex1p; + Setup(c, x1, vertex1, dx1, dy1, e1, sign1, step1, DX1) + } while (y >= intToY(vertex1)); + h = dy1; + } + else { + Step(x1, dx1, dy1, e1, sign1, step1) + h = intToY(vertex1) - y; + } + if (y == intToY(vertex2)) { + do { + c = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; + Setup(c, x2, vertex2, dx2, dy2, e2, sign2, step2, DX2) + } while (y >= intToY(vertex2)); + if (dy2 < h) + h = dy2; + } + else { + Step(x2, dx2, dy2, e2, sign2, step2) + if ((c = (intToY(vertex2) - y)) < h) + h = c; + } + + /* fill spans for this segment */ + if (DX1 | DX2) { + if (infoRec->SubsequentSolidFillTrap && (h > 6)) { + if (x1 == x2) { + while (x1 == x2) { + y++; + if (!--h) + break; + Step(x1, dx1, dy1, e1, sign1, step1) + Step(x2, dx2, dy2, e2, sign2, step2) + } + if (y == maxy) + break; + if (!h) + continue; + } + + if (x1 < x2) + (*infoRec->SubsequentSolidFillTrap) (infoRec->pScrn, + y + yoffset, h, + x1, DX1, dy1, e1, + x2 - 1, DX2, dy2, e2); + else + (*infoRec->SubsequentSolidFillTrap) (infoRec->pScrn, + y + yoffset, h, + x2, DX2, dy2, e2, + x1 - 1, DX1, dy1, e1); + y += h; + if (--h) { + FixError(x1, dx1, dy1, e1, sign1, step1, h); + FixError(x2, dx2, dy2, e2, sign2, step2, h); + h = 0; + } + } + else { + while (1) { + if (x2 > x1) + (*infoRec->SubsequentSolidFillRect) (infoRec->pScrn, + x1, y + yoffset, + x2 - x1, 1); + else if (x1 > x2) + (*infoRec->SubsequentSolidFillRect) (infoRec->pScrn, + x2, y + yoffset, + x1 - x2, 1); + y++; + if (!--h) + break; + Step(x1, dx1, dy1, e1, sign1, step1) + Step(x2, dx2, dy2, e2, sign2, step2) + } + } + } + else { + if (x2 > x1) + (*infoRec->SubsequentSolidFillRect) (infoRec->pScrn, + x1, y + yoffset, x2 - x1, + h); + else if (x1 > x2) + (*infoRec->SubsequentSolidFillRect) (infoRec->pScrn, + x2, y + yoffset, x1 - x2, + h); + + y += h; + h = 0; + } + if (y == maxy) + break; + } + SET_SYNC_FLAG(infoRec); +} + +void +XAAFillPolygonHelper(ScrnInfoPtr pScrn, + DDXPointPtr ptsIn, + int count, + DDXPointPtr topPoint, + int y, + int maxy, + int origin, + RectFuncPtr RectFunc, + TrapFuncPtr TrapFunc, + int xorg, int yorg, XAACacheInfoPtr pCache) +{ + int *vertex1p, *vertex2p, *endp; + int vertex1, vertex2; + int x1 = 0, x2 = 0; + int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; + int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0; + int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0; + int c, h, yoffset; + + endp = (int *) ptsIn + count; + vertex2p = vertex1p = (int *) topPoint; + yoffset = intToY(origin); + origin = intToX(origin); + vertex2 = vertex1 = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; + + while (1) { + if (y == intToY(vertex1)) { + do { + if (vertex1p == (int *) ptsIn) + vertex1p = endp; + c = *--vertex1p; + Setup(c, x1, vertex1, dx1, dy1, e1, sign1, step1, DX1) + } while (y >= intToY(vertex1)); + h = dy1; + } + else { + Step(x1, dx1, dy1, e1, sign1, step1) + h = intToY(vertex1) - y; + } + if (y == intToY(vertex2)) { + do { + c = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; + Setup(c, x2, vertex2, dx2, dy2, e2, sign2, step2, DX2) + } while (y >= intToY(vertex2)); + if (dy2 < h) + h = dy2; + } + else { + Step(x2, dx2, dy2, e2, sign2, step2) + if ((c = (intToY(vertex2) - y)) < h) + h = c; + } + + /* fill spans for this segment */ + if (DX1 | DX2) { + if (TrapFunc && (h > 6)) { + if (x1 == x2) { + while (x1 == x2) { + y++; + if (!--h) + break; + Step(x1, dx1, dy1, e1, sign1, step1) + Step(x2, dx2, dy2, e2, sign2, step2) + } + if (y == maxy) + break; + if (!h) + continue; + } + + if (x1 < x2) + (*TrapFunc) (pScrn, y + yoffset, h, + x1, DX1, dy1, e1, + x2 - 1, DX2, dy2, e2, xorg, yorg, pCache); + else + (*TrapFunc) (pScrn, y + yoffset, h, + x2, DX2, dy2, e2, + x1 - 1, DX1, dy1, e1, xorg, yorg, pCache); + y += h; + if (--h) { + FixError(x1, dx1, dy1, e1, sign1, step1, h); + FixError(x2, dx2, dy2, e2, sign2, step2, h); + h = 0; + } + } + else { + while (1) { + if (x2 > x1) + (*RectFunc) (pScrn, + x1, y + yoffset, x2 - x1, 1, xorg, yorg, + pCache); + else if (x1 > x2) + (*RectFunc) (pScrn, + x2, y + yoffset, x1 - x2, 1, xorg, yorg, + pCache); + y++; + if (!--h) + break; + Step(x1, dx1, dy1, e1, sign1, step1) + Step(x2, dx2, dy2, e2, sign2, step2) + } + } + } + else { + if (x2 > x1) + (*RectFunc) (pScrn, + x1, y + yoffset, x2 - x1, h, xorg, yorg, pCache); + else if (x1 > x2) + (*RectFunc) (pScrn, + x2, y + yoffset, x1 - x2, h, xorg, yorg, pCache); + + y += h; + h = 0; + } + if (y == maxy) + break; + } +} + + /*****************\ + | Solid Helpers | + \*****************/ + +static void +SolidTrapHelper(ScrnInfoPtr pScrn, + int y, int h, + int x1, int dx1, int dy1, int e1, + int x2, int dx2, int dy2, int e2, + int xorg, int yorg, XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + (*infoRec->SubsequentSolidFillTrap) (pScrn, + y, h, x1, dx1, dy1, e1, x2, dx2, dy2, + e2); +} + +static void +SolidRectHelper(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int xorg, int yorg, XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); +} + + /*********************\ + | Mono 8x8 Patterns | + \*********************/ + +static void +Mono8x8PatternTrapHelper_ScreenOrigin(ScrnInfoPtr pScrn, + int y, int h, + int x1, int dx1, int dy1, int e1, + int x2, int dx2, int dy2, int e2, + int xorg, int yorg, + XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg, + y, h, x1, dx1, dy1, e1, x2, + dx2, dy2, e2); +} + +static void +Mono8x8PatternRectHelper_ScreenOrigin(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int xorg, int yorg, + XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg, + x, y, w, h); +} + +static void +Mono8x8PatternRectHelper(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int xorg, int yorg, XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + xorg = (x - xorg) & 0x07; + yorg = (y - yorg) & 0x07; + + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) { + if (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) { + int patx = pCache->pat0; + int paty = pCache->pat1; + + XAARotateMonoPattern(&patx, &paty, xorg, yorg, + (infoRec->Mono8x8PatternFillFlags & + BIT_ORDER_IN_BYTE_MSBFIRST)); + xorg = patx; + yorg = paty; + } + else { + int slot = (yorg << 3) + xorg; + + xorg = pCache->x + pCache->offsets[slot].x; + yorg = pCache->y + pCache->offsets[slot].y; + } + } + + (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg, + x, y, w, h); +} + + /****************\ + | Cache Expand | + \****************/ + +static void +CacheExpandRectHelper(ScrnInfoPtr pScrn, + int X, int Y, int Width, int Height, + int xorg, int yorg, XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int x, phaseY, phaseX, skipleft, w, blit_w, blit_h; + int cacheWidth; + + cacheWidth = (pCache->w * pScrn->bitsPerPixel) / + infoRec->CacheColorExpandDensity; + + phaseY = (Y - yorg) % pCache->orig_h; + if (phaseY < 0) + phaseY += pCache->orig_h; + phaseX = (X - xorg) % pCache->orig_w; + if (phaseX < 0) + phaseX += pCache->orig_w; + + while (1) { + w = Width; + skipleft = phaseX; + x = X; + blit_h = pCache->h - phaseY; + if (blit_h > Height) + blit_h = Height; + + while (1) { + blit_w = cacheWidth - skipleft; + if (blit_w > w) + blit_w = w; + (*infoRec->SubsequentScreenToScreenColorExpandFill) (pScrn, x, Y, + blit_w, blit_h, + pCache->x, + pCache->y + + phaseY, + skipleft); + w -= blit_w; + if (!w) + break; + x += blit_w; + skipleft = (skipleft + blit_w) % pCache->orig_w; + } + Height -= blit_h; + if (!Height) + break; + Y += blit_h; + phaseY = (phaseY + blit_h) % pCache->orig_h; + } +} + + /**************\ + | Cache Blit | + \**************/ + +static void +CacheBltRectHelper(ScrnInfoPtr pScrn, + int X, int Y, int Width, int Height, + int xorg, int yorg, XAACacheInfoPtr pCache) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int x, phaseY, phaseX, skipleft, w, blit_w, blit_h; + + phaseY = (Y - yorg) % pCache->orig_h; + if (phaseY < 0) + phaseY += pCache->orig_h; + phaseX = (X - xorg) % pCache->orig_w; + if (phaseX < 0) + phaseX += pCache->orig_w; + + while (1) { + w = Width; + skipleft = phaseX; + x = X; + blit_h = pCache->h - phaseY; + if (blit_h > Height) + blit_h = Height; + + while (1) { + blit_w = pCache->w - skipleft; + if (blit_w > w) + blit_w = w; + (*infoRec->SubsequentScreenToScreenCopy) (pScrn, + pCache->x + skipleft, + pCache->y + phaseY, x, Y, + blit_w, blit_h); + w -= blit_w; + if (!w) + break; + x += blit_w; + skipleft = (skipleft + blit_w) % pCache->orig_w; + } + Height -= blit_h; + if (!Height) + break; + Y += blit_h; + phaseY = (phaseY + blit_h) % pCache->orig_h; + } +} + + /**********************\ + | Stippled Polygons | + \**********************/ + +void +XAAFillPolygonStippled(DrawablePtr pDraw, + GCPtr pGC, + int shape, int mode, int count, DDXPointPtr ptsIn) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple); + int origin, type, patx, paty, fg, bg; + int y, maxy, xorg, yorg; + DDXPointPtr topPoint; + XAACacheInfoPtr pCache = NULL; + RectFuncPtr RectFunc = NULL; + TrapFuncPtr TrapFunc = NULL; + + if (!RegionNumRects(pGC->pCompositeClip)) + return; + + if (mode == CoordModePrevious) { + register DDXPointPtr ppt = ptsIn + 1; + + for (origin = 1; origin < count; origin++, ppt++) { + ppt->x += (ppt - 1)->x; + ppt->y += (ppt - 1)->y; + } + mode = CoordModeOrigin; + } + + if (RegionNumRects(pGC->pCompositeClip) != 1) { + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + if (pGC->fillStyle == FillStippled) { + type = (*infoRec->StippledFillChooser) (pGC); + fg = pGC->fgPixel; + bg = -1; + } + else { + type = (*infoRec->OpaqueStippledFillChooser) (pGC); + fg = pGC->fgPixel; + bg = pGC->bgPixel; + } + + if (!type) { + (*XAAFallbackOps.FillPolygon) (pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + if ((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) { + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + origin = pDraw->x; + + switch (XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents, + origin, &topPoint, &y, &maxy, shape)) { + case POLY_USE_MI: + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + case POLY_FULLY_CLIPPED: + return; + } + + xorg = (pDraw->x + pGC->patOrg.x); + yorg = (pDraw->y + pGC->patOrg.y); + + if ((fg == bg) && (bg != -1) && infoRec->SetupForSolidFill) { + + (*infoRec->SetupForSolidFill) (infoRec->pScrn, fg, + pGC->alu, pGC->planemask); + + RectFunc = SolidRectHelper; + TrapFunc = infoRec->SubsequentSolidFillTrap ? SolidTrapHelper : NULL; + } + else + switch (type) { + case DO_MONO_8x8: + patx = pPriv->pattern0; + paty = pPriv->pattern1; + if (infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_SCREEN_ORIGIN) { + xorg = (-xorg) & 0x07; + yorg = (-yorg) & 0x07; + if (infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_BITS) { + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) { + XAARotateMonoPattern(&patx, &paty, xorg, yorg, + (infoRec->Mono8x8PatternFillFlags & + BIT_ORDER_IN_BYTE_MSBFIRST)); + xorg = patx; + yorg = paty; + } + } + else { + XAACacheInfoPtr pCache = + (*infoRec->CacheMono8x8Pattern) (infoRec->pScrn, patx, + paty); + patx = pCache->x; + paty = pCache->y; + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) { + int slot = (yorg << 3) + xorg; + + patx += pCache->offsets[slot].x; + paty += pCache->offsets[slot].y; + xorg = patx; + yorg = paty; + } + } + RectFunc = Mono8x8PatternRectHelper_ScreenOrigin; + if (infoRec->SubsequentMono8x8PatternFillTrap) + TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin; + } + else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */ + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_BITS)) { + pCache = + (*infoRec->CacheMono8x8Pattern) (infoRec->pScrn, patx, + paty); + patx = pCache->x; + paty = pCache->y; + } + else { + pCache = &(infoRec->ScratchCacheInfoRec); + pCache->pat0 = patx; + pCache->pat1 = paty; + } + RectFunc = Mono8x8PatternRectHelper; + } + + (*infoRec->SetupForMono8x8PatternFill) (infoRec->pScrn, + patx, paty, fg, bg, + pGC->alu, pGC->planemask); + break; + case DO_CACHE_EXPAND: + pCache = + (*infoRec->CacheMonoStipple) (infoRec->pScrn, pGC->stipple); + + (*infoRec->SetupForScreenToScreenColorExpandFill) (infoRec->pScrn, + fg, bg, pGC->alu, + pGC->planemask); + + RectFunc = CacheExpandRectHelper; + break; + case DO_CACHE_BLT: + pCache = (*infoRec->CacheStipple) (infoRec->pScrn, pGC->stipple, + fg, bg); + (*infoRec->SetupForScreenToScreenCopy) (infoRec->pScrn, 1, 1, + pGC->alu, pGC->planemask, + pCache->trans_color); + + RectFunc = CacheBltRectHelper; + break; + default: + return; + } + + XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint, + y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, + pCache); + + SET_SYNC_FLAG(infoRec); +} + + /*******************\ + | Tiled Polygons | + \*******************/ + +void +XAAFillPolygonTiled(DrawablePtr pDraw, + GCPtr pGC, + int shape, int mode, int count, DDXPointPtr ptsIn) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap); + int origin, type, patx, paty; + int y, maxy, xorg, yorg; + DDXPointPtr topPoint; + XAACacheInfoPtr pCache = NULL; + RectFuncPtr RectFunc = NULL; + TrapFuncPtr TrapFunc = NULL; + + if (!RegionNumRects(pGC->pCompositeClip)) + return; + + if (mode == CoordModePrevious) { + register DDXPointPtr ppt = ptsIn + 1; + + for (origin = 1; origin < count; origin++, ppt++) { + ppt->x += (ppt - 1)->x; + ppt->y += (ppt - 1)->y; + } + mode = CoordModeOrigin; + } + + if (RegionNumRects(pGC->pCompositeClip) != 1) { + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + type = (*infoRec->TiledFillChooser) (pGC); + + if (!type || (type == DO_IMAGE_WRITE)) { + (*XAAFallbackOps.FillPolygon) (pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + if (type == DO_COLOR_8x8) { + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + return; + } + + origin = pDraw->x; + + switch (XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents, + origin, &topPoint, &y, &maxy, shape)) { + case POLY_USE_MI: + miFillPolygon(pDraw, pGC, shape, mode, count, ptsIn); + case POLY_FULLY_CLIPPED: + return; + } + + xorg = (pDraw->x + pGC->patOrg.x); + yorg = (pDraw->y + pGC->patOrg.y); + + switch (type) { + case DO_MONO_8x8: + patx = pPriv->pattern0; + paty = pPriv->pattern1; + if (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) { + xorg = (-xorg) & 0x07; + yorg = (-yorg) & 0x07; + if (infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_BITS) { + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) { + XAARotateMonoPattern(&patx, &paty, xorg, yorg, + (infoRec->Mono8x8PatternFillFlags & + BIT_ORDER_IN_BYTE_MSBFIRST)); + xorg = patx; + yorg = paty; + } + } + else { + XAACacheInfoPtr pCache = + (*infoRec->CacheMono8x8Pattern) (infoRec->pScrn, patx, + paty); + patx = pCache->x; + paty = pCache->y; + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) { + int slot = (yorg << 3) + xorg; + + patx += pCache->offsets[slot].x; + paty += pCache->offsets[slot].y; + xorg = patx; + yorg = paty; + } + } + RectFunc = Mono8x8PatternRectHelper_ScreenOrigin; + if (infoRec->SubsequentMono8x8PatternFillTrap) + TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin; + } + else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */ + if (!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_BITS)) { + pCache = + (*infoRec->CacheMono8x8Pattern) (infoRec->pScrn, patx, + paty); + patx = pCache->x; + paty = pCache->y; + } + else { + pCache = &(infoRec->ScratchCacheInfoRec); + pCache->pat0 = patx; + pCache->pat1 = paty; + } + RectFunc = Mono8x8PatternRectHelper; + } + + (*infoRec->SetupForMono8x8PatternFill) (infoRec->pScrn, + patx, paty, pPriv->fg, + pPriv->bg, pGC->alu, + pGC->planemask); + break; + case DO_CACHE_BLT: + pCache = (*infoRec->CacheTile) (infoRec->pScrn, pGC->tile.pixmap); + (*infoRec->SetupForScreenToScreenCopy) (infoRec->pScrn, 1, 1, + pGC->alu, pGC->planemask, -1); + + RectFunc = CacheBltRectHelper; + break; + case DO_PIXMAP_COPY: + pCache = &(infoRec->ScratchCacheInfoRec); + pCache->x = pPriv->offscreenArea->box.x1; + pCache->y = pPriv->offscreenArea->box.y1; + pCache->w = pCache->orig_w = pPriv->offscreenArea->box.x2 - pCache->x; + pCache->h = pCache->orig_h = pPriv->offscreenArea->box.y2 - pCache->y; + + (*infoRec->SetupForScreenToScreenCopy) (infoRec->pScrn, 1, 1, + pGC->alu, pGC->planemask, -1); + + RectFunc = CacheBltRectHelper; + break; + default: + return; + } + + XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint, + y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, + pCache); + + SET_SYNC_FLAG(infoRec); +} |