diff options
Diffstat (limited to 'hw/xfree86/xaa/xaaSpans.c')
-rw-r--r-- | hw/xfree86/xaa/xaaSpans.c | 880 |
1 files changed, 880 insertions, 0 deletions
diff --git a/hw/xfree86/xaa/xaaSpans.c b/hw/xfree86/xaa/xaaSpans.c new file mode 100644 index 000000000..522225665 --- /dev/null +++ b/hw/xfree86/xaa/xaaSpans.c @@ -0,0 +1,880 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c,v 1.15 2001/10/28 03:34:04 tsi Exp $ */ + +#include "misc.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" + +#include "X.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "xf86str.h" +#include "mi.h" +#include "mispans.h" +#include "xaa.h" +#include "xaalocal.h" + + +static void XAARenderSolidSpans( + GCPtr, int, DDXPointPtr, int*, int, int, int); +static void XAARenderColor8x8Spans( + GCPtr, int, DDXPointPtr, int*, int, int, int); +static void XAARenderMono8x8Spans( + GCPtr, int, DDXPointPtr, int*, int, int, int); +static void XAARenderCacheBltSpans( + GCPtr, int, DDXPointPtr, int*, int, int, int); +static void XAARenderColorExpandSpans( + GCPtr, int, DDXPointPtr, int*, int, int, int); +static void XAARenderCacheExpandSpans( + GCPtr, int, DDXPointPtr, int*, int, int, int); +static void XAARenderPixmapCopySpans( + GCPtr, int, DDXPointPtr, int*, int, int, int); + +void +XAAFillSpans( + DrawablePtr pDraw, + GC *pGC, + int nInit, /* number of spans to fill */ + DDXPointPtr pptInit, /* pointer to list of start points */ + int *pwidthInit, /* pointer to list of n widths */ + int fSorted +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + int type = 0; + ClipAndRenderSpansFunc function; + Bool fastClip = FALSE; + + if((nInit <= 0) || !pGC->planemask) + return; + + if(!REGION_NUM_RECTS(pGC->pCompositeClip)) + return; + + switch(pGC->fillStyle) { + case FillSolid: + type = DO_SOLID; + break; + case FillStippled: + type = (*infoRec->StippledFillChooser)(pGC); + break; + case FillOpaqueStippled: + if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSpansSolid && + CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) && + CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) && + CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) && + CHECK_FG(pGC,infoRec->FillSpansSolidFlags)) + type = DO_SOLID; + else + type = (*infoRec->OpaqueStippledFillChooser)(pGC); + break; + case FillTiled: + type = (*infoRec->TiledFillChooser)(pGC); + break; + } + + switch(type) { + case DO_SOLID: + function = XAARenderSolidSpans; + if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL) + fastClip = TRUE; + break; + case DO_COLOR_8x8: + function = XAARenderColor8x8Spans; + if(infoRec->ClippingFlags & HARDWARE_CLIP_COLOR_8x8_FILL) + fastClip = TRUE; + break; + case DO_MONO_8x8: + function = XAARenderMono8x8Spans; + if(infoRec->ClippingFlags & HARDWARE_CLIP_MONO_8x8_FILL) + fastClip = TRUE; + break; + case DO_CACHE_BLT: + function = XAARenderCacheBltSpans; + if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY) + fastClip = TRUE; + break; + case DO_COLOR_EXPAND: + function = XAARenderColorExpandSpans; + break; + case DO_CACHE_EXPAND: + function = XAARenderCacheExpandSpans; + if(infoRec->ClippingFlags & + HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND) + fastClip = TRUE; + break; + case DO_PIXMAP_COPY: + function = XAARenderPixmapCopySpans; + if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY) + fastClip = TRUE; + break; + case DO_IMAGE_WRITE: + default: + (*XAAFallbackOps.FillSpans)(pDraw, pGC, nInit, pptInit, + pwidthInit, fSorted); + return; + } + + + if((nInit < 10) || (REGION_NUM_RECTS(pGC->pCompositeClip) != 1)) + fastClip = FALSE; + + if(fastClip) { + infoRec->ClipBox = &pGC->pCompositeClip->extents; + (*function)(pGC, nInit, pptInit, pwidthInit, fSorted, + pDraw->x, pDraw->y); + infoRec->ClipBox = NULL; + } else + XAAClipAndRenderSpans(pGC, pptInit, pwidthInit, nInit, fSorted, + function, pDraw->x, pDraw->y); +} + + + /*********************\ + | Solid Spans | + \*********************/ + + +static void +XAARenderSolidSpans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + + (*infoRec->FillSolidSpans) (infoRec->pScrn, pGC->fgPixel, + pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted); +} + + + /************************\ + | Mono 8x8 Spans | + \************************/ + + +static void +XAARenderMono8x8Spans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAAPixmapPtr pPriv; + int fg, bg; + + switch(pGC->fillStyle) { + case FillStippled: + pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple); + fg = pGC->fgPixel; bg = -1; + break; + case FillOpaqueStippled: + pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple); + fg = pGC->fgPixel; bg = pGC->bgPixel; + break; + case FillTiled: + pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap); + fg = pPriv->fg; bg = pPriv->bg; + break; + default: /* Muffle compiler */ + pPriv = NULL; /* Kaboom */ + fg = -1; bg = -1; + break; + } + + (*infoRec->FillMono8x8PatternSpans) (infoRec->pScrn, + fg, bg, pGC->alu, pGC->planemask, + n, ppt, pwidth, fSorted, pPriv->pattern0, pPriv->pattern1, + (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y)); +} + + + /*************************\ + | Color 8x8 Spans | + \*************************/ + + +static void +XAARenderColor8x8Spans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAACacheInfoPtr pCache; + PixmapPtr pPix; + int fg, bg; + + switch(pGC->fillStyle) { + case FillStippled: + pPix = pGC->stipple; + fg = pGC->fgPixel; bg = -1; + break; + case FillOpaqueStippled: + pPix = pGC->stipple; + fg = pGC->fgPixel; bg = pGC->bgPixel; + break; + case FillTiled: + pPix = pGC->tile.pixmap; + fg = -1; bg = -1; + break; + default: /* Muffle compiler */ + pPix = NULL; + fg = -1; bg = -1; + break; + } + + pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg); + + (*infoRec->FillColor8x8PatternSpans) (infoRec->pScrn, + pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache, + (yorg + pGC->patOrg.x), (xorg + pGC->patOrg.y)); +} + + + /****************************\ + | Color Expand Spans | + \****************************/ + + +static void +XAARenderColorExpandSpans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + int fg, bg; + + switch(pGC->fillStyle) { + case FillStippled: + fg = pGC->fgPixel; bg = -1; + break; + case FillOpaqueStippled: + fg = pGC->fgPixel; bg = pGC->bgPixel; + break; + default: /* Muffle compiler */ + fg = -1; bg = -1; + break; + } + + (*infoRec->FillColorExpandSpans) (infoRec->pScrn, fg, bg, + pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, + (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), + pGC->stipple); + +} + + + /*************************\ + | Cache Blt Spans | + \*************************/ + + +static void +XAARenderCacheBltSpans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAACacheInfoPtr pCache; + + switch(pGC->fillStyle) { + case FillStippled: + pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, + pGC->fgPixel, -1); + break; + case FillOpaqueStippled: + pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, + pGC->fgPixel, pGC->bgPixel); + break; + case FillTiled: + pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap); + break; + default: /* Muffle compiler */ + pCache = NULL; + break; + } + + (*infoRec->FillCacheBltSpans) (infoRec->pScrn, + pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache, + (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y)); + +} + + + /****************************\ + | Cache Expand Spans | + \****************************/ + + +static void +XAARenderCacheExpandSpans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + int fg, bg; + + switch(pGC->fillStyle) { + case FillStippled: + fg = pGC->fgPixel; bg = -1; + break; + case FillOpaqueStippled: + fg = pGC->fgPixel; bg = pGC->bgPixel; + break; + default: /* Muffle compiler */ + fg = -1; bg = -1; + break; + } + + (*infoRec->FillCacheExpandSpans) (infoRec->pScrn, fg, bg, + pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, + (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), + pGC->stipple); +} + + + /***************************\ + | Pixmap Copy Spans | + \***************************/ + + +static void +XAARenderPixmapCopySpans( + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec); + XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap); + + 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; + pCache->trans_color = -1; + + (*infoRec->FillCacheBltSpans) (infoRec->pScrn, + pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache, + (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y)); +} + + + + + + /****************\ + | Solid | + \****************/ + + +void +XAAFillSolidSpans( + ScrnInfoPtr pScrn, + int fg, int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, int fSorted +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + if (*pwidth > 0) + (*infoRec->SubsequentSolidFillRect)(pScrn, ppt->x, ppt->y, + *pwidth, 1); + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + /***************\ + | Mono 8x8 | + \***************/ + + +void +XAAFillMono8x8PatternSpansScreenOrigin( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, int fSorted, + int pattern0, int pattern1, + int xorigin, int yorigin +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int patx = pattern0, paty = pattern1; + int xorg = (-xorigin) & 0x07; + int yorg = (-yorigin) & 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)(pScrn, pattern0, pattern1); + 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; + } + } + + (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty, + fg, bg, rop, planemask); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn, + xorg, yorg, ppt->x, ppt->y, *pwidth, 1); + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + +void +XAAFillMono8x8PatternSpans( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, int fSorted, + int pattern0, int pattern1, + int xorigin, int yorigin +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int patx = pattern0, paty = pattern1; + int xorg, yorg, slot; + XAACacheInfoPtr pCache = NULL; + + + if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){ + pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1); + patx = pCache->x; paty = pCache->y; + } + + (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty, + fg, bg, rop, planemask); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + xorg = (ppt->x - xorigin) & 0x07; + yorg = (ppt->y - yorigin) & 0x07; + + if(!(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ + if(infoRec->Mono8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_BITS) { + patx = pattern0; paty = pattern1; + XAARotateMonoPattern(&patx, &paty, xorg, yorg, + (infoRec->Mono8x8PatternFillFlags & + BIT_ORDER_IN_BYTE_MSBFIRST)); + xorg = patx; yorg = paty; + } else { + slot = (yorg << 3) + xorg; + xorg = patx + pCache->offsets[slot].x; + yorg = paty + pCache->offsets[slot].y; + } + } + + (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn, + xorg, yorg, ppt->x, ppt->y, *pwidth, 1); + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + + + /****************\ + | Color 8x8 | + \****************/ + + +void +XAAFillColor8x8PatternSpansScreenOrigin( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, int fSorted, + XAACacheInfoPtr pCache, + int xorigin, int yorigin +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int patx = pCache->x, paty = pCache->y; + int xorg = (-xorigin) & 0x07; + int yorg = (-yorigin) & 0x07; + + + if(!(infoRec->Color8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ + int slot = (yorg << 3) + xorg; + paty += pCache->offsets[slot].y; + patx += pCache->offsets[slot].x; + xorg = patx; yorg = paty; + } + + (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty, + rop, planemask, pCache->trans_color); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn, + xorg, yorg, ppt->x, ppt->y, *pwidth, 1); + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + +void +XAAFillColor8x8PatternSpans( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, int fSorted, + XAACacheInfoPtr pCache, + int xorigin, int yorigin +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int xorg, yorg, slot; + + (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y, + rop, planemask, pCache->trans_color); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + xorg = (ppt->x - xorigin) & 0x07; + yorg = (ppt->y - yorigin) & 0x07; + + if(!(infoRec->Color8x8PatternFillFlags & + HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ + slot = (yorg << 3) + xorg; + yorg = pCache->y + pCache->offsets[slot].y; + xorg = pCache->x + pCache->offsets[slot].x; + } + + (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn, + xorg, yorg, ppt->x, ppt->y, *pwidth, 1); + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + /*****************\ + | Cache Blit | + \*****************/ + + +void +XAAFillCacheBltSpans( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + XAACacheInfoPtr pCache, + int xorg, int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int x, w, phaseX, phaseY, blit_w; + + (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask, + pCache->trans_color); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + x = ppt->x; + w = *pwidth; + phaseX = (x - xorg) % pCache->orig_w; + if(phaseX < 0) phaseX += pCache->orig_w; + phaseY = (ppt->y - yorg) % pCache->orig_h; + if(phaseY < 0) phaseY += pCache->orig_h; + + while(1) { + blit_w = pCache->w - phaseX; + if(blit_w > w) blit_w = w; + + (*infoRec->SubsequentScreenToScreenCopy)(pScrn, + pCache->x + phaseX, pCache->y + phaseY, + x, ppt->y, blit_w, 1); + + w -= blit_w; + if(!w) break; + x += blit_w; + phaseX = (phaseX + blit_w) % pCache->orig_w; + } + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + + /****************\ + | Cache Expand | + \****************/ + + +void +XAAFillCacheExpandSpans( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg, + PixmapPtr pPix +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int x, w, phaseX, phaseY, blit_w, cacheWidth; + XAACacheInfoPtr pCache; + + pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix); + + cacheWidth = (pCache->w * pScrn->bitsPerPixel) / + infoRec->CacheColorExpandDensity; + + (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, + planemask); + + if(infoRec->ClipBox) + (*infoRec->SetClippingRectangle)(infoRec->pScrn, + infoRec->ClipBox->x1, infoRec->ClipBox->y1, + infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1); + + while(n--) { + x = ppt->x; + w = *pwidth; + phaseX = (x - xorg) % pCache->orig_w; + if(phaseX < 0) phaseX += pCache->orig_w; + phaseY = (ppt->y - yorg) % pCache->orig_h; + if(phaseY < 0) phaseY += pCache->orig_h; + + while(1) { + blit_w = cacheWidth - phaseX; + if(blit_w > w) blit_w = w; + + (*infoRec->SubsequentScreenToScreenColorExpandFill)( + pScrn, x, ppt->y, blit_w, 1, + pCache->x, pCache->y + phaseY, phaseX); + + w -= blit_w; + if(!w) break; + x += blit_w; + phaseX = (phaseX + blit_w) % pCache->orig_w; + } + ppt++; pwidth++; + } + + if(infoRec->ClipBox) + (*infoRec->DisableClipping)(infoRec->pScrn); + + SET_SYNC_FLAG(infoRec); +} + + + +void +XAAClipAndRenderSpans( + GCPtr pGC, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted, + ClipAndRenderSpansFunc func, + int xorg, + int yorg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + DDXPointPtr pptNew, pptBase; + int *pwidthBase, *pwidthNew; + int Right, numRects, MaxBoxes; + + MaxBoxes = infoRec->PreAllocSize/(sizeof(DDXPointRec) + sizeof(int)); + pptBase = (DDXPointRec*)infoRec->PreAllocMem; + pwidthBase = (int*)(&pptBase[MaxBoxes]); + + pptNew = pptBase; + pwidthNew = pwidthBase; + + numRects = REGION_NUM_RECTS(pGC->pCompositeClip); + + if(numRects == 1) { + BoxPtr pextent = REGION_RECTS(pGC->pCompositeClip); + + while(nspans--) { + if ((pextent->y1 <= ppt->y) && (ppt->y < pextent->y2)) { + pptNew->x = max(pextent->x1, ppt->x); + Right = ppt->x + *pwidth; + *pwidthNew = min(pextent->x2, Right) - pptNew->x; + + if (*pwidthNew > 0) { + pptNew->y = ppt->y; + pptNew++; + pwidthNew++; + + if(pptNew >= (pptBase + MaxBoxes)) { + (*func)(pGC, MaxBoxes, pptBase, pwidthBase, fSorted, + xorg, yorg); + pptNew = pptBase; + pwidthNew = pwidthBase; + } + } + } + ppt++; + pwidth++; + } + } else if (numRects) { + BoxPtr pbox; + int nbox; + + while(nspans--) { + nbox = numRects; + pbox = REGION_RECTS(pGC->pCompositeClip); + + /* find the first band */ + while(nbox && (pbox->y2 <= ppt->y)) { + pbox++; + nbox--; + } + + if(nbox && (pbox->y1 <= ppt->y)) { + int orig_y = pbox->y1; + Right = ppt->x + *pwidth; + while(nbox && (orig_y == pbox->y1)) { + if(pbox->x2 <= ppt->x) { + nbox--; + pbox++; + continue; + } + + if(pbox->x1 >= Right) { + nbox = 0; + break; + } + + pptNew->x = max(pbox->x1, ppt->x); + *pwidthNew = min(pbox->x2, Right) - pptNew->x; + if(*pwidthNew > 0) { + pptNew->y = ppt->y; + pptNew++; + pwidthNew++; + + if(pptNew >= (pptBase + MaxBoxes)) { + (*func)(pGC, MaxBoxes, pptBase, pwidthBase, + fSorted, xorg, yorg); + pptNew = pptBase; + pwidthNew = pwidthBase; + } + } + pbox++; + nbox--; + } + } + ppt++; + pwidth++; + } + } + + if(pptNew != pptBase) + (*func)(pGC, pptNew - pptBase, pptBase, pwidthBase, fSorted, + xorg, yorg); +} |