First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbbitblt.c
blobfaf49b92d5bc3041f829c3c71090a53ee8b8a9fb
1 /*
2 * cfb copy area
3 */
6 /*
8 Copyright 1989, 1998 The Open Group
10 Permission to use, copy, modify, distribute, and sell this software and its
11 documentation for any purpose is hereby granted without fee, provided that
12 the above copyright notice appear in all copies and that both that
13 copyright notice and this permission notice appear in supporting
14 documentation.
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of The Open Group shall not be
27 used in advertising or otherwise to promote the sale, use or other dealings
28 in this Software without prior written authorization from The Open Group.
30 Author: Keith Packard
34 #ifdef HAVE_DIX_CONFIG_H
35 #include <dix-config.h>
36 #endif
38 #include <stdlib.h>
40 #include <X11/X.h>
41 #include <X11/Xmd.h>
42 #include <X11/Xproto.h>
43 #include "gcstruct.h"
44 #include "windowstr.h"
45 #include "scrnintstr.h"
46 #include "pixmapstr.h"
47 #include "regionstr.h"
48 #include "mi.h"
49 #include "cfb.h"
50 #include "cfbmskbits.h"
51 #include "cfb8bit.h"
52 #include "fastblt.h"
53 #define MFB_CONSTS_ONLY
54 #include "maskbits.h"
56 #if PSZ == 8
57 #define cfbCopyPlane1toN cfbCopyPlane1to8
58 #define cfbCopyPlaneNto1 cfbCopyPlane8to1
59 #else
60 static unsigned int FgPixel, BgPixel;
61 # if PSZ == 16
62 #define cfbCopyPlane1toN cfbCopyPlane1to16
63 #define cfbCopyPlaneNto1 cfbCopyPlane16to1
64 # endif
65 # if PSZ == 24
66 #define cfbCopyPlane1toN cfbCopyPlane1to24
67 #define cfbCopyPlaneNto1 cfbCopyPlane24to1
68 # endif
69 # if PSZ == 32
70 #define cfbCopyPlane1toN cfbCopyPlane1to32
71 #define cfbCopyPlaneNto1 cfbCopyPlane32to1
72 # endif
73 #endif
75 /* cfbBitBltcfb == cfbCopyPlaneExpand */
76 RegionPtr
77 cfbBitBlt (
78 register DrawablePtr pSrcDrawable,
79 register DrawablePtr pDstDrawable,
80 GC *pGC,
81 int srcx, int srcy,
82 int width, int height,
83 int dstx, int dsty,
84 void (*doBitBlt)(
85 DrawablePtr /*pSrc*/,
86 DrawablePtr /*pDst*/,
87 int /*alu*/,
88 RegionPtr /*prgnDst*/,
89 DDXPointPtr /*pptSrc*/,
90 unsigned long /*planemask*/),
91 unsigned long bitPlane)
93 RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
94 Bool freeSrcClip = FALSE;
96 RegionPtr prgnExposed;
97 RegionRec rgnDst;
98 DDXPointPtr pptSrc;
99 register DDXPointPtr ppt;
100 register BoxPtr pbox;
101 int i;
102 register int dx;
103 register int dy;
104 xRectangle origSource;
105 DDXPointRec origDest;
106 int numRects;
107 BoxRec fastBox;
108 int fastClip = 0; /* for fast clipping with pixmap source */
109 int fastExpose = 0; /* for fast exposures with pixmap source */
111 origSource.x = srcx;
112 origSource.y = srcy;
113 origSource.width = width;
114 origSource.height = height;
115 origDest.x = dstx;
116 origDest.y = dsty;
118 if ((pSrcDrawable != pDstDrawable) &&
119 pSrcDrawable->pScreen->SourceValidate)
121 (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
124 srcx += pSrcDrawable->x;
125 srcy += pSrcDrawable->y;
127 /* clip the source */
129 if (pSrcDrawable->type == DRAWABLE_PIXMAP)
131 if ((pSrcDrawable == pDstDrawable) &&
132 (pGC->clientClipType == CT_NONE))
134 prgnSrcClip = cfbGetCompositeClip(pGC);
136 else
138 fastClip = 1;
141 else
143 if (pGC->subWindowMode == IncludeInferiors)
146 * XFree86 DDX empties the border clip when the
147 * VT is inactive
149 if (!((WindowPtr) pSrcDrawable)->parent &&
150 REGION_NOTEMPTY (pSrcDrawable->pScreen,
151 &((WindowPtr) pSrcDrawable)->borderClip))
154 * special case bitblt from root window in
155 * IncludeInferiors mode; just like from a pixmap
157 fastClip = 1;
159 else if ((pSrcDrawable == pDstDrawable) &&
160 (pGC->clientClipType == CT_NONE))
162 prgnSrcClip = cfbGetCompositeClip(pGC);
164 else
166 prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
167 freeSrcClip = TRUE;
170 else
172 prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
176 fastBox.x1 = srcx;
177 fastBox.y1 = srcy;
178 fastBox.x2 = srcx + width;
179 fastBox.y2 = srcy + height;
181 /* Don't create a source region if we are doing a fast clip */
182 if (fastClip)
184 fastExpose = 1;
186 * clip the source; if regions extend beyond the source size,
187 * make sure exposure events get sent
189 if (fastBox.x1 < pSrcDrawable->x)
191 fastBox.x1 = pSrcDrawable->x;
192 fastExpose = 0;
194 if (fastBox.y1 < pSrcDrawable->y)
196 fastBox.y1 = pSrcDrawable->y;
197 fastExpose = 0;
199 if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
201 fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
202 fastExpose = 0;
204 if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
206 fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
207 fastExpose = 0;
210 else
212 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
213 REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
216 dstx += pDstDrawable->x;
217 dsty += pDstDrawable->y;
219 if (pDstDrawable->type == DRAWABLE_WINDOW)
221 if (!((WindowPtr)pDstDrawable)->realized)
223 if (!fastClip)
224 REGION_UNINIT(pGC->pScreen, &rgnDst);
225 if (freeSrcClip)
226 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
227 return NULL;
231 dx = srcx - dstx;
232 dy = srcy - dsty;
234 /* Translate and clip the dst to the destination composite clip */
235 if (fastClip)
237 RegionPtr cclip;
239 /* Translate the region directly */
240 fastBox.x1 -= dx;
241 fastBox.x2 -= dx;
242 fastBox.y1 -= dy;
243 fastBox.y2 -= dy;
245 /* If the destination composite clip is one rectangle we can
246 do the clip directly. Otherwise we have to create a full
247 blown region and call intersect */
249 /* XXX because CopyPlane uses this routine for 8-to-1 bit
250 * copies, this next line *must* also correctly fetch the
251 * composite clip from an mfb gc
254 cclip = cfbGetCompositeClip(pGC);
255 if (REGION_NUM_RECTS(cclip) == 1)
257 BoxPtr pBox = REGION_RECTS(cclip);
259 if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
260 if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
261 if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
262 if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
264 /* Check to see if the region is empty */
265 if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
267 REGION_NULL(pGC->pScreen, &rgnDst);
269 else
271 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
274 else
276 /* We must turn off fastClip now, since we must create
277 a full blown region. It is intersected with the
278 composite clip below. */
279 fastClip = 0;
280 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
283 else
285 REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
288 if (!fastClip)
290 REGION_INTERSECT(pGC->pScreen, &rgnDst,
291 &rgnDst,
292 cfbGetCompositeClip(pGC));
295 /* Do bit blitting */
296 numRects = REGION_NUM_RECTS(&rgnDst);
297 if (numRects && width && height)
299 if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
300 sizeof(DDXPointRec))))
302 REGION_UNINIT(pGC->pScreen, &rgnDst);
303 if (freeSrcClip)
304 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
305 return NULL;
307 pbox = REGION_RECTS(&rgnDst);
308 ppt = pptSrc;
309 for (i = numRects; --i >= 0; pbox++, ppt++)
311 ppt->x = pbox->x1 + dx;
312 ppt->y = pbox->y1 + dy;
315 (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask);
316 DEALLOCATE_LOCAL(pptSrc);
319 prgnExposed = NULL;
320 if (pGC->fExpose)
322 /* Pixmap sources generate a NoExposed (we return NULL to do this) */
323 if (!fastExpose)
324 prgnExposed =
325 miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
326 origSource.x, origSource.y,
327 (int)origSource.width,
328 (int)origSource.height,
329 origDest.x, origDest.y, bitPlane);
331 REGION_UNINIT(pGC->pScreen, &rgnDst);
332 if (freeSrcClip)
333 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
334 return prgnExposed;
338 RegionPtr
339 cfbCopyPlaneReduce (
340 register DrawablePtr pSrcDrawable,
341 register DrawablePtr pDstDrawable,
342 GC *pGC,
343 int srcx, int srcy,
344 int width, int height,
345 int dstx, int dsty,
346 void (*doCopyPlane)(
347 DrawablePtr /*pSrc*/,
348 DrawablePtr /*pDst*/,
349 int /*alu*/,
350 RegionPtr /*prgnDst*/,
351 DDXPointPtr /*pptSrc*/,
352 unsigned long /*planemask*/,
353 unsigned long /*bitPlane*/),
354 unsigned long bitPlane)
356 RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
357 Bool freeSrcClip = FALSE;
359 RegionPtr prgnExposed;
360 RegionRec rgnDst;
361 DDXPointPtr pptSrc;
362 register DDXPointPtr ppt;
363 register BoxPtr pbox;
364 int i;
365 register int dx;
366 register int dy;
367 xRectangle origSource;
368 DDXPointRec origDest;
369 int numRects;
370 BoxRec fastBox;
371 int fastClip = 0; /* for fast clipping with pixmap source */
372 int fastExpose = 0; /* for fast exposures with pixmap source */
374 origSource.x = srcx;
375 origSource.y = srcy;
376 origSource.width = width;
377 origSource.height = height;
378 origDest.x = dstx;
379 origDest.y = dsty;
381 if ((pSrcDrawable != pDstDrawable) &&
382 pSrcDrawable->pScreen->SourceValidate)
384 (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
387 srcx += pSrcDrawable->x;
388 srcy += pSrcDrawable->y;
390 /* clip the source */
392 if (pSrcDrawable->type == DRAWABLE_PIXMAP)
394 if ((pSrcDrawable == pDstDrawable) &&
395 (pGC->clientClipType == CT_NONE))
397 prgnSrcClip = cfbGetCompositeClip(pGC);
399 else
401 fastClip = 1;
404 else
406 if (pGC->subWindowMode == IncludeInferiors)
409 * XFree86 DDX empties the border clip when the
410 * VT is inactive
412 if (!((WindowPtr) pSrcDrawable)->parent &&
413 REGION_NOTEMPTY (pSrcDrawable->pScreen,
414 &((WindowPtr) pSrcDrawable)->borderClip))
417 * special case bitblt from root window in
418 * IncludeInferiors mode; just like from a pixmap
420 fastClip = 1;
422 else if ((pSrcDrawable == pDstDrawable) &&
423 (pGC->clientClipType == CT_NONE))
425 prgnSrcClip = cfbGetCompositeClip(pGC);
427 else
429 prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
430 freeSrcClip = TRUE;
433 else
435 prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
439 fastBox.x1 = srcx;
440 fastBox.y1 = srcy;
441 fastBox.x2 = srcx + width;
442 fastBox.y2 = srcy + height;
444 /* Don't create a source region if we are doing a fast clip */
445 if (fastClip)
447 fastExpose = 1;
449 * clip the source; if regions extend beyond the source size,
450 * make sure exposure events get sent
452 if (fastBox.x1 < pSrcDrawable->x)
454 fastBox.x1 = pSrcDrawable->x;
455 fastExpose = 0;
457 if (fastBox.y1 < pSrcDrawable->y)
459 fastBox.y1 = pSrcDrawable->y;
460 fastExpose = 0;
462 if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
464 fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
465 fastExpose = 0;
467 if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
469 fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
470 fastExpose = 0;
473 else
475 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
476 REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
479 dstx += pDstDrawable->x;
480 dsty += pDstDrawable->y;
482 if (pDstDrawable->type == DRAWABLE_WINDOW)
484 if (!((WindowPtr)pDstDrawable)->realized)
486 if (!fastClip)
487 REGION_UNINIT(pGC->pScreen, &rgnDst);
488 if (freeSrcClip)
489 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
490 return NULL;
494 dx = srcx - dstx;
495 dy = srcy - dsty;
497 /* Translate and clip the dst to the destination composite clip */
498 if (fastClip)
500 RegionPtr cclip;
502 /* Translate the region directly */
503 fastBox.x1 -= dx;
504 fastBox.x2 -= dx;
505 fastBox.y1 -= dy;
506 fastBox.y2 -= dy;
508 /* If the destination composite clip is one rectangle we can
509 do the clip directly. Otherwise we have to create a full
510 blown region and call intersect */
512 /* XXX because CopyPlane uses this routine for 8-to-1 bit
513 * copies, this next line *must* also correctly fetch the
514 * composite clip from an mfb gc
517 cclip = cfbGetCompositeClip(pGC);
518 if (REGION_NUM_RECTS(cclip) == 1)
520 BoxPtr pBox = REGION_RECTS(cclip);
522 if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
523 if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
524 if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
525 if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
527 /* Check to see if the region is empty */
528 if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
530 REGION_NULL(pGC->pScreen, &rgnDst);
532 else
534 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
537 else
539 /* We must turn off fastClip now, since we must create
540 a full blown region. It is intersected with the
541 composite clip below. */
542 fastClip = 0;
543 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
546 else
548 REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
551 if (!fastClip)
553 REGION_INTERSECT(pGC->pScreen, &rgnDst,
554 &rgnDst,
555 cfbGetCompositeClip(pGC));
558 /* Do bit blitting */
559 numRects = REGION_NUM_RECTS(&rgnDst);
560 if (numRects && width && height)
562 if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
563 sizeof(DDXPointRec))))
565 REGION_UNINIT(pGC->pScreen, &rgnDst);
566 if (freeSrcClip)
567 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
568 return NULL;
570 pbox = REGION_RECTS(&rgnDst);
571 ppt = pptSrc;
572 for (i = numRects; --i >= 0; pbox++, ppt++)
574 ppt->x = pbox->x1 + dx;
575 ppt->y = pbox->y1 + dy;
578 (*doCopyPlane) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask, bitPlane);
579 DEALLOCATE_LOCAL(pptSrc);
582 prgnExposed = NULL;
583 if (pGC->fExpose)
585 /* Pixmap sources generate a NoExposed (we return NULL to do this) */
586 if (!fastExpose)
587 prgnExposed =
588 miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
589 origSource.x, origSource.y,
590 (int)origSource.width,
591 (int)origSource.height,
592 origDest.x, origDest.y, bitPlane);
594 REGION_UNINIT(pGC->pScreen, &rgnDst);
595 if (freeSrcClip)
596 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
597 return prgnExposed;
601 void
602 cfbDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc, planemask)
603 DrawablePtr pSrc, pDst;
604 int alu;
605 RegionPtr prgnDst;
606 DDXPointPtr pptSrc;
607 unsigned long planemask;
609 void (*doBitBlt)(
610 DrawablePtr /*pSrc*/,
611 DrawablePtr /*pDst*/,
612 int /*alu*/,
613 RegionPtr /*prgnDst*/,
614 DDXPointPtr /*pptSrc*/,
615 unsigned long /*planemask*/)
616 = cfbDoBitbltGeneral;
618 if ((planemask & PMSK) == PMSK) {
619 switch (alu) {
620 case GXcopy:
621 doBitBlt = cfbDoBitbltCopy;
622 break;
623 case GXxor:
624 doBitBlt = cfbDoBitbltXor;
625 break;
626 case GXor:
627 doBitBlt = cfbDoBitbltOr;
628 break;
631 (*doBitBlt) (pSrc, pDst, alu, prgnDst, pptSrc, planemask);
634 RegionPtr
635 cfbCopyArea(pSrcDrawable, pDstDrawable,
636 pGC, srcx, srcy, width, height, dstx, dsty)
637 register DrawablePtr pSrcDrawable;
638 register DrawablePtr pDstDrawable;
639 GC *pGC;
640 int srcx, srcy;
641 int width, height;
642 int dstx, dsty;
644 void (*doBitBlt) (
645 DrawablePtr /*pSrc*/,
646 DrawablePtr /*pDst*/,
647 int /*alu*/,
648 RegionPtr /*prgnDst*/,
649 DDXPointPtr /*pptSrc*/,
650 unsigned long /*planemask*/);
652 doBitBlt = cfbDoBitbltCopy;
653 if (pGC->alu != GXcopy || (pGC->planemask & PMSK) != PMSK)
655 doBitBlt = cfbDoBitbltGeneral;
656 if ((pGC->planemask & PMSK) == PMSK)
658 switch (pGC->alu) {
659 case GXxor:
660 doBitBlt = cfbDoBitbltXor;
661 break;
662 case GXor:
663 doBitBlt = cfbDoBitbltOr;
664 break;
668 return cfbBitBlt (pSrcDrawable, pDstDrawable,
669 pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0L);
672 #if PSZ == 8
673 void
674 cfbCopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask)
675 DrawablePtr pSrcDrawable; /* must be a bitmap */
676 DrawablePtr pDstDrawable; /* must be depth 8 drawable */
677 int rop; /* not used; caller must call cfb8CheckOpaqueStipple
678 * beforehand to get cfb8StippleRRop set correctly */
679 RegionPtr prgnDst; /* region in destination to draw to;
680 * screen relative coords. if dest is a window;
681 * drawable relative if dest is a pixmap */
682 DDXPointPtr pptSrc; /* drawable relative src coords to copy from;
683 * must be one point for each box in prgnDst */
684 unsigned long planemask; /* to apply to destination writes */
686 int srcx, srcy; /* upper left corner of box being copied in source */
687 int dstx, dsty; /* upper left corner of box being copied in dest */
688 int width, height; /* in pixels, unpadded, of box being copied */
689 int xoffSrc; /* bit # in leftmost word of row from which copying starts */
690 int xoffDst; /* byte # in leftmost word of row from which copying starts */
691 CfbBits *psrcBase, *pdstBase; /* start of drawable's pixel data */
692 int widthSrc; /* # of groups of 32 pixels (1 bit/pixel) in src bitmap*/
693 int widthDst; /* # of groups of 4 pixels (8 bits/pixel) in dst */
694 CfbBits *psrcLine, *pdstLine; /* steps a row at a time thru src/dst;
695 * may point into middle of row */
696 register CfbBits *psrc, *pdst; /* steps within the row */
697 register CfbBits bits, tmp; /* bits from source */
698 register int leftShift;
699 register int rightShift;
700 CfbBits startmask; /* left edge pixel mask */
701 CfbBits endmask; /* right edge pixel mask */
702 register int nlMiddle; /* number of words in middle of the row to draw */
703 register int nl;
704 int firstoff = 0;
705 int secondoff = 0;
706 CfbBits src;
707 int nbox; /* number of boxes in region to copy */
708 BoxPtr pbox; /* steps thru boxes in region */
709 int pixelsRemainingOnRightEdge; /* # pixels to be drawn on a row after
710 * the main "middle" loop */
712 cfbGetLongWidthAndPointer (pSrcDrawable, widthSrc, psrcBase)
713 cfbGetLongWidthAndPointer (pDstDrawable, widthDst, pdstBase)
715 nbox = REGION_NUM_RECTS(prgnDst);
716 pbox = REGION_RECTS(prgnDst);
717 while (nbox--)
719 dstx = pbox->x1;
720 dsty = pbox->y1;
721 srcx = pptSrc->x;
722 srcy = pptSrc->y;
723 width = pbox->x2 - pbox->x1;
724 height = pbox->y2 - pbox->y1;
725 pbox++;
726 pptSrc++;
728 psrcLine = psrcBase + srcy * widthSrc + (srcx >> MFB_PWSH);
729 pdstLine = pdstBase + dsty * widthDst + (dstx >> PWSH);
730 xoffSrc = srcx & MFB_PIM; /* finds starting bit in src */
731 xoffDst = dstx & PIM; /* finds starting byte in dst */
733 /* compute startmask, endmask, nlMiddle */
735 if (xoffDst + width < PPW) /* XXX should this be '<= PPW' ? */
736 { /* the copy only affects one word per row in destination */
737 maskpartialbits(dstx, width, startmask);
738 endmask = 0; /* nothing on right edge */
739 nlMiddle = 0; /* nothing in middle */
741 else
742 { /* the copy will affect multiple words per row in destination */
743 maskbits(dstx, width, startmask, endmask, nlMiddle);
747 * compute constants for the first four bits to be
748 * copied. This avoids troubles with partial first
749 * writes, and difficult shift computation
751 if (startmask)
753 firstoff = xoffSrc - xoffDst;
754 if (firstoff > (MFB_PPW-PPW))
755 secondoff = MFB_PPW - firstoff;
756 if (xoffDst)
758 srcx += (PPW-xoffDst);
759 xoffSrc = srcx & MFB_PIM;
762 leftShift = xoffSrc;
763 rightShift = MFB_PPW - leftShift;
765 pixelsRemainingOnRightEdge = (nlMiddle & 7) * PPW +
766 ((dstx + width) & PIM);
768 /* setup is done; now let's move some bits */
770 /* caller must call cfb8CheckOpaqueStipple before this function
771 * to set cfb8StippleRRop!
774 if (cfb8StippleRRop == GXcopy)
776 while (height--)
777 { /* one iteration of this loop copies one row */
778 psrc = psrcLine;
779 pdst = pdstLine;
780 psrcLine += widthSrc;
781 pdstLine += widthDst;
782 bits = *psrc++;
783 if (startmask)
785 if (firstoff < 0)
786 tmp = BitRight (bits, -firstoff);
787 else
789 tmp = BitLeft (bits, firstoff);
791 * need a more cautious test for partialmask
792 * case...
794 if (firstoff >= (MFB_PPW-PPW))
796 bits = *psrc++;
797 if (firstoff != (MFB_PPW-PPW))
798 tmp |= BitRight (bits, secondoff);
801 *pdst = (*pdst & ~startmask) | (GetPixelGroup(tmp) & startmask);
802 pdst++;
804 nl = nlMiddle;
805 while (nl >= 8)
807 nl -= 8;
808 tmp = BitLeft(bits, leftShift);
809 bits = *psrc++;
810 if (rightShift != MFB_PPW)
811 tmp |= BitRight(bits, rightShift);
813 #ifdef FAST_CONSTANT_OFFSET_MODE
814 # define StorePixels(pdst,o,pixels) (pdst)[o] = (pixels)
815 # define EndStep(pdst,o) (pdst) += (o)
816 # define StoreRopPixels(pdst,o,and,xor) (pdst)[o] = DoRRop((pdst)[o],and,xor);
817 #else
818 # define StorePixels(pdst,o,pixels) *(pdst)++ = (pixels)
819 # define EndStep(pdst,o)
820 # define StoreRopPixels(pdst,o,and,xor) *(pdst) = DoRRop(*(pdst),and,xor); (pdst)++;
821 #endif
823 #define Step(c) NextBitGroup(c);
824 #define StoreBitsPlain(o,c) StorePixels(pdst,o,GetPixelGroup(c))
825 #define StoreRopBitsPlain(o,c) StoreRopPixels(pdst,o,\
826 cfb8StippleAnd[GetBitGroup(c)], \
827 cfb8StippleXor[GetBitGroup(c)])
828 #define StoreBits0(c) StoreBitsPlain(0,c)
829 #define StoreRopBits0(c) StoreRopBitsPlain(0,c)
831 #if (BITMAP_BIT_ORDER == MSBFirst)
832 # define StoreBits(o,c) StoreBitsPlain(o,c)
833 # define StoreRopBits(o,c) StoreRopBitsPlain(o,c)
834 # define FirstStep(c) Step(c)
835 #else /* BITMAP_BIT_ORDER == LSBFirst */
836 #if PGSZ == 64
837 # define StoreBits(o,c) StorePixels(pdst,o, (cfb8Pixels[c & 0xff]))
838 # define StoreRopBits(o,c) StoreRopPixels(pdst,o, \
839 (cfb8StippleAnd[c & 0xff]), \
840 (cfb8StippleXor[c & 0xff]))
841 # define FirstStep(c) c = BitLeft (c, 8);
842 #else
843 /* 0x3c is 0xf << 2 (4 bits, long word) */
844 # define StoreBits(o,c) StorePixels(pdst,o,*((CfbBits *)\
845 (((char *) cfb8Pixels) + (c & 0x3c))))
846 # define StoreRopBits(o,c) StoreRopPixels(pdst,o, \
847 *((CfbBits *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \
848 *((CfbBits *) (((char *) cfb8StippleXor) + (c & 0x3c))))
849 # define FirstStep(c) c = BitLeft (c, 2);
850 #endif /* PGSZ */
851 #endif /* BITMAP_BIT_ORDER */
853 StoreBits0(tmp); FirstStep(tmp);
854 StoreBits(1,tmp); Step(tmp);
855 StoreBits(2,tmp); Step(tmp);
856 StoreBits(3,tmp); Step(tmp);
857 StoreBits(4,tmp); Step(tmp);
858 StoreBits(5,tmp); Step(tmp);
859 StoreBits(6,tmp); Step(tmp);
860 StoreBits(7,tmp); EndStep (pdst,8);
863 /* do rest of middle and partial word on right edge */
865 if (pixelsRemainingOnRightEdge)
867 tmp = BitLeft(bits, leftShift);
869 if (pixelsRemainingOnRightEdge > rightShift)
871 bits = *psrc++;
872 tmp |= BitRight (bits, rightShift);
874 EndStep (pdst, nl);
875 switch (nl)
877 case 7:
878 StoreBitsPlain(-7,tmp); Step(tmp);
879 case 6:
880 StoreBitsPlain(-6,tmp); Step(tmp);
881 case 5:
882 StoreBitsPlain(-5,tmp); Step(tmp);
883 case 4:
884 StoreBitsPlain(-4,tmp); Step(tmp);
885 case 3:
886 StoreBitsPlain(-3,tmp); Step(tmp);
887 case 2:
888 StoreBitsPlain(-2,tmp); Step(tmp);
889 case 1:
890 StoreBitsPlain(-1,tmp); Step(tmp);
892 if (endmask)
893 *pdst = (*pdst & ~endmask) | (GetPixelGroup(tmp) & endmask);
897 else /* cfb8StippleRRop != GXcopy */
899 while (height--)
900 { /* one iteration of this loop copies one row */
901 psrc = psrcLine;
902 pdst = pdstLine;
903 psrcLine += widthSrc;
904 pdstLine += widthDst;
905 bits = *psrc++;
907 /* do partial word on left edge */
909 if (startmask)
911 if (firstoff < 0)
912 tmp = BitRight (bits, -firstoff);
913 else
915 tmp = BitLeft (bits, firstoff);
916 if (firstoff >= (MFB_PPW-PPW))
918 bits = *psrc++;
919 if (firstoff != (MFB_PPW-PPW))
920 tmp |= BitRight (bits, secondoff);
923 src = GetBitGroup(tmp);
924 *pdst = MaskRRopPixels (*pdst, src, startmask);
925 pdst++;
928 /* do middle of row */
930 nl = nlMiddle;
931 while (nl >= 8)
933 nl -= 8;
934 tmp = BitLeft(bits, leftShift);
935 bits = *psrc++;
936 if (rightShift != MFB_PPW)
937 tmp |= BitRight(bits, rightShift);
938 StoreRopBits0(tmp); FirstStep(tmp);
939 StoreRopBits(1,tmp); Step(tmp);
940 StoreRopBits(2,tmp); Step(tmp);
941 StoreRopBits(3,tmp); Step(tmp);
942 StoreRopBits(4,tmp); Step(tmp);
943 StoreRopBits(5,tmp); Step(tmp);
944 StoreRopBits(6,tmp); Step(tmp);
945 StoreRopBits(7,tmp); EndStep(pdst,8);
948 /* do rest of middle and partial word on right edge */
950 if (pixelsRemainingOnRightEdge)
952 tmp = BitLeft(bits, leftShift);
954 if (pixelsRemainingOnRightEdge > rightShift)
956 bits = *psrc++; /* XXX purify abr here */
957 tmp |= BitRight (bits, rightShift);
959 while (nl--)
961 src = GetBitGroup (tmp);
962 *pdst = RRopPixels (*pdst, src);
963 pdst++;
964 NextBitGroup(tmp);
966 if (endmask)
968 src = GetBitGroup (tmp);
969 *pdst = MaskRRopPixels (*pdst, src, endmask);
972 } /* end copy one row */
973 } /* end alu is non-copy-mode case */
974 } /* end iteration over region boxes */
977 #else /* PSZ == 8 */
979 #define mfbmaskbits(x, w, startmask, endmask, nlw) \
980 startmask = mfbGetstarttab((x)&0x1f); \
981 endmask = mfbGetendtab(((x)+(w)) & 0x1f); \
982 if (startmask) \
983 nlw = (((w) - (32 - ((x)&0x1f))) >> 5); \
984 else \
985 nlw = (w) >> 5;
987 #define mfbmaskpartialbits(x, w, mask) \
988 mask = mfbGetpartmasks((x)&0x1f,(w)&0x1f);
990 #define LeftMost 0
991 #define StepBit(bit, inc) ((bit) += (inc))
994 #define GetBits(psrc, nBits, curBit, bitPos, bits) {\
995 bits = 0; \
996 while (nBits--) \
998 bits |= ((*psrc++ >> bitPos) & 1) << curBit; \
999 StepBit (curBit, 1); \
1003 /******************************************************************/
1005 static void
1006 #if PSZ == 16
1007 cfbCopyPlane1to16
1008 #endif
1009 #if PSZ == 24
1010 cfbCopyPlane1to24
1011 #endif
1012 #if PSZ == 32
1013 cfbCopyPlane1to32
1014 #endif
1016 DrawablePtr pSrcDrawable,
1017 DrawablePtr pDstDrawable,
1018 int rop,
1019 RegionPtr prgnDst,
1020 DDXPointPtr pptSrc,
1021 unsigned long planemask)
1023 int srcx, srcy, dstx, dsty;
1024 int width, height;
1025 int xoffSrc;
1026 CfbBits *psrcBase, *pdstBase;
1027 int widthSrc, widthDst;
1028 unsigned int *psrcLine;
1029 register unsigned int *psrc;
1030 #if PSZ == 16
1031 unsigned short *pdstLine;
1032 register unsigned short *pdst;
1033 #endif
1034 #if PSZ == 32
1035 unsigned int *pdstLine;
1036 register unsigned int *pdst;
1037 #endif
1038 #if PSZ == 24
1039 unsigned char *pdstLine;
1040 register unsigned char *pdst;
1041 #endif
1042 register unsigned int bits, tmp;
1043 register unsigned int fgpixel, bgpixel;
1044 register unsigned int src;
1045 #if PSZ == 24
1046 register unsigned int dst;
1047 #endif
1048 register int leftShift, rightShift;
1049 register int i, nl;
1050 int nbox;
1051 BoxPtr pbox;
1052 int result;
1054 #if PSZ == 16
1055 unsigned int doublet[4]; /* Pixel values for 16bpp expansion. */
1056 #endif
1057 #if PSZ == 32
1058 unsigned int doublet[8]; /* Pixel values for 32bpp expansion */
1059 #endif
1061 fgpixel = FgPixel & planemask;
1062 bgpixel = BgPixel & planemask;
1064 #if PSZ == 16
1065 if (rop == GXcopy && (planemask & PMSK) == PMSK) {
1066 doublet[0] = bgpixel | (bgpixel << 16);
1067 doublet[1] = fgpixel | (bgpixel << 16);
1068 doublet[2] = bgpixel | (fgpixel << 16);
1069 doublet[3] = fgpixel | (fgpixel << 16);
1071 #endif
1072 #if PSZ == 32
1073 if (rop == GXcopy && (planemask & PMSK) == PMSK) {
1074 doublet[0] = bgpixel; doublet[1] = bgpixel;
1075 doublet[2] = fgpixel; doublet[3] = bgpixel;
1076 doublet[4] = bgpixel; doublet[5] = fgpixel;
1077 doublet[6] = fgpixel; doublet[7] = fgpixel;
1079 #endif
1081 /* must explicitly ask for "int" widths, as code below expects it */
1082 /* on some machines (Alpha), "long" and "int" are not the same size */
1083 cfbGetTypedWidthAndPointer (pSrcDrawable, widthSrc, psrcBase, int, CfbBits)
1084 cfbGetTypedWidthAndPointer (pDstDrawable, widthDst, pdstBase, int, CfbBits)
1086 #if PSZ == 16
1087 widthDst <<= 1;
1088 #endif
1089 #if PSZ == 24
1090 widthDst <<= 2;
1091 #endif
1093 nbox = REGION_NUM_RECTS(prgnDst);
1094 pbox = REGION_RECTS(prgnDst);
1096 while (nbox--)
1098 dstx = pbox->x1;
1099 dsty = pbox->y1;
1100 srcx = pptSrc->x;
1101 srcy = pptSrc->y;
1102 width = pbox->x2 - pbox->x1;
1103 height = pbox->y2 - pbox->y1;
1104 pbox++;
1105 pptSrc++;
1106 psrcLine = (unsigned int *)psrcBase + srcy * widthSrc + (srcx >> 5);
1107 #if PSZ == 16
1108 pdstLine = (unsigned short *)pdstBase + dsty * widthDst + dstx;
1109 #endif
1110 #if PSZ == 24
1111 pdstLine = (unsigned char *)pdstBase + dsty * widthDst + dstx * 3;
1112 #endif
1113 #if PSZ == 32
1114 pdstLine = (unsigned int *)pdstBase + dsty * widthDst + dstx;
1115 #endif
1116 xoffSrc = srcx & 0x1f;
1119 * compute constants for the first four bits to be
1120 * copied. This avoids troubles with partial first
1121 * writes, and difficult shift computation
1123 leftShift = xoffSrc;
1124 rightShift = 32 - leftShift;
1126 if (rop == GXcopy && (planemask & PMSK) == PMSK)
1128 while (height--)
1130 psrc = psrcLine;
1131 pdst = pdstLine;
1132 psrcLine += widthSrc;
1133 pdstLine += widthDst;
1134 bits = *psrc++;
1135 nl = width;
1136 while (nl >= 32)
1138 tmp = BitLeft(bits, leftShift);
1139 bits = *psrc++;
1140 if (rightShift != 32)
1141 tmp |= BitRight(bits, rightShift);
1142 i = 0;
1143 #if PSZ == 16
1145 * I've thrown in some optimization to at least write
1146 * some aligned 32-bit words instead of 16-bit shorts.
1148 if ((unsigned long)psrc & 2) {
1149 /* Write unaligned 16-bit word at left edge. */
1150 if (tmp & 0x01)
1151 *pdst = fgpixel;
1152 else
1153 *pdst = bgpixel;
1154 pdst++;
1155 i++;
1157 while (i <= 24)
1159 unsigned tmpbits = tmp >> i;
1160 *(unsigned int *)pdst = doublet[tmpbits & 0x03];
1161 *(unsigned int *)(pdst + 2) =
1162 doublet[(tmpbits >> 2) & 0x03];
1163 *(unsigned int *)(pdst + 4) =
1164 doublet[(tmpbits >> 4) & 0x03];
1165 *(unsigned int *)(pdst + 6) =
1166 doublet[(tmpbits >> 6) & 0x03];
1167 pdst += 8; /* Advance four 32-bit words. */
1168 i += 8;
1170 while (i <= 30)
1172 *(unsigned int *)pdst =
1173 doublet[(tmp >> i) & 0x03];
1174 pdst += 2; /* Advance one 32-bit word. */
1175 i += 2;
1177 if (i == 31) {
1178 if ((tmp >> 31) & 0x01)
1179 *pdst = fgpixel;
1180 else
1181 *pdst = bgpixel;
1182 pdst++;
1184 #endif
1185 #if PSZ == 24
1186 while (i < 32) {
1187 if ((tmp >> i) & 0x01) {
1188 *pdst = fgpixel;
1189 *(pdst + 1) = fgpixel >> 8;
1190 *(pdst + 2) = fgpixel >> 16;
1192 else {
1193 *pdst = bgpixel;
1194 *(pdst + 1) = bgpixel >> 8;
1195 *(pdst + 2) = bgpixel >> 16;
1197 pdst += 3;
1198 i++;
1200 #endif
1201 #if PSZ == 32
1202 while (i <= 28) {
1203 int pair;
1204 pair = (tmp >> i) & 0x03;
1205 *pdst = doublet[pair * 2];
1206 *(pdst + 1) = doublet[pair * 2 + 1];
1207 pair = (tmp >> (i + 2)) & 0x03;
1208 *(pdst + 2) = doublet[pair * 2];
1209 *(pdst + 3) = doublet[pair * 2 + 1];
1210 pdst += 4;
1211 i += 4;
1213 while (i < 32) {
1214 *pdst = ((tmp >> i) & 0x01) ? fgpixel : bgpixel;
1215 pdst++;
1216 i++;
1218 #endif
1219 nl -= 32;
1222 if (nl)
1224 tmp = BitLeft(bits, leftShift);
1226 * better condition needed -- mustn't run
1227 * off the end of the source...
1229 if (rightShift != 32)
1231 bits = *psrc++;
1232 tmp |= BitRight (bits, rightShift);
1234 i = 32;
1235 while (nl--)
1237 --i;
1238 #if PSZ == 24
1239 if ((tmp >> (31 - i)) & 0x01) {
1240 *pdst = fgpixel;
1241 *(pdst + 1) = fgpixel >> 8;
1242 *(pdst + 2) = fgpixel >> 16;
1244 else {
1245 *pdst = bgpixel;
1246 *(pdst + 1) = bgpixel >> 8;
1247 *(pdst + 2) = bgpixel >> 16;
1249 pdst += 3;
1250 #else
1251 *pdst = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel;
1252 pdst++;
1253 #endif
1258 else
1260 while (height--)
1262 psrc = psrcLine;
1263 pdst = pdstLine;
1264 psrcLine += widthSrc;
1265 pdstLine += widthDst;
1266 bits = *psrc++;
1267 nl = width;
1268 while (nl >= 32)
1270 tmp = BitLeft(bits, leftShift);
1271 bits = *psrc++;
1272 if (rightShift != 32)
1273 tmp |= BitRight(bits, rightShift);
1274 i = 32;
1275 while (i--)
1277 src = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel;
1278 #if PSZ == 24
1279 dst = *pdst;
1280 dst |= (*(pdst + 1)) << 8;
1281 dst |= (*(pdst + 2)) << 16;
1282 DoRop (result, rop, src, dst);
1283 *pdst = (dst & ~planemask) |
1284 (result & planemask);
1285 *(pdst+1) = ((dst & ~planemask) >> 8) |
1286 ((result & planemask) >> 8);
1287 *(pdst+2) = ((dst & ~planemask) >> 16) |
1288 ((result & planemask) >> 16);
1289 pdst += 3;
1290 #else
1291 DoRop (result, rop, src, *pdst);
1293 *pdst = (*pdst & ~planemask) |
1294 (result & planemask);
1295 pdst++;
1296 #endif
1298 nl -= 32;
1301 if (nl)
1303 tmp = BitLeft(bits, leftShift);
1305 * better condition needed -- mustn't run
1306 * off the end of the source...
1308 if (rightShift != 32)
1310 bits = *psrc++;
1311 tmp |= BitRight (bits, rightShift);
1313 i = 32;
1314 while (nl--)
1316 --i;
1317 src = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel;
1318 #if PSZ == 24
1319 dst = *pdst;
1320 dst |= (*(pdst + 1)) << 8;
1321 dst |= (*(pdst + 2)) << 16;
1322 DoRop (result, rop, src, dst);
1323 *pdst = (dst & ~planemask) |
1324 (result & planemask);
1325 *(pdst+1) = ((dst & ~planemask) >> 8) |
1326 ((result & planemask) >> 8);
1327 *(pdst+2) = ((dst & ~planemask) >> 16) |
1328 ((result & planemask) >> 16);
1329 pdst += 3;
1330 #else
1331 DoRop (result, rop, src, *pdst);
1333 *pdst = (*pdst & ~planemask) |
1334 (result & planemask);
1335 pdst++;
1336 #endif
1344 #endif /* PSZ == 8 */
1346 /* shared among all different cfb depths through linker magic */
1348 RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable,
1349 pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
1350 DrawablePtr pSrcDrawable;
1351 DrawablePtr pDstDrawable;
1352 GCPtr pGC;
1353 int srcx, srcy;
1354 int width, height;
1355 int dstx, dsty;
1356 unsigned long bitPlane;
1358 RegionPtr ret;
1360 #if IMAGE_BYTE_ORDER == LSBFirst
1362 void (*doCopyPlaneExpand)(
1363 DrawablePtr /*pSrc*/,
1364 DrawablePtr /*pDst*/,
1365 int /*alu*/,
1366 RegionPtr /*prgnDst*/,
1367 DDXPointPtr /*pptSrc*/,
1368 unsigned long /*planemask*/);
1370 if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == PSZ)
1372 if (bitPlane == 1)
1374 doCopyPlaneExpand = cfbCopyPlane1toN;
1375 #if PSZ == 8
1376 cfb8CheckOpaqueStipple (pGC->alu,
1377 pGC->fgPixel, pGC->bgPixel,
1378 pGC->planemask);
1379 #else
1380 FgPixel = pGC->fgPixel;
1381 BgPixel = pGC->bgPixel;
1382 #endif
1383 ret = cfbCopyPlaneExpand (pSrcDrawable, pDstDrawable,
1384 pGC, srcx, srcy, width, height, dstx, dsty, doCopyPlaneExpand, bitPlane);
1386 else
1387 ret = miHandleExposures (pSrcDrawable, pDstDrawable,
1388 pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
1390 else if (pSrcDrawable->bitsPerPixel == PSZ && pDstDrawable->bitsPerPixel == 1)
1392 int oldalu;
1394 oldalu = pGC->alu;
1395 if ((pGC->fgPixel & 1) == 0 && (pGC->bgPixel&1) == 1)
1396 pGC->alu = mfbGetInverseAlu(pGC->alu);
1397 else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))
1398 pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel);
1399 ret = cfbCopyPlaneReduce(pSrcDrawable, pDstDrawable,
1400 pGC, srcx, srcy, width, height, dstx, dsty,
1401 cfbCopyPlaneNto1, bitPlane);
1402 pGC->alu = oldalu;
1404 else if (pSrcDrawable->bitsPerPixel == PSZ && pDstDrawable->bitsPerPixel == PSZ)
1406 PixmapPtr pBitmap;
1407 ScreenPtr pScreen = pSrcDrawable->pScreen;
1408 GCPtr pGC1;
1410 pBitmap = (*pScreen->CreatePixmap) (pScreen, width, height, 1);
1411 if (!pBitmap)
1412 return NULL;
1413 pGC1 = GetScratchGC (1, pScreen);
1414 if (!pGC1)
1416 (*pScreen->DestroyPixmap) (pBitmap);
1417 return NULL;
1420 * don't need to set pGC->fgPixel,bgPixel as copyPlaneNto1
1421 * ignores pixel values, expecting the rop to "do the
1422 * right thing", which GXcopy will.
1424 ValidateGC ((DrawablePtr) pBitmap, pGC1);
1425 /* no exposures here, scratch GC's don't get graphics expose */
1426 cfbCopyPlaneReduce(pSrcDrawable, (DrawablePtr) pBitmap,
1427 pGC1, srcx, srcy, width, height, 0, 0,
1428 cfbCopyPlaneNto1, bitPlane);
1429 #if PSZ == 8
1430 cfb8CheckOpaqueStipple (pGC->alu,
1431 pGC->fgPixel, pGC->bgPixel,
1432 pGC->planemask);
1433 #else
1434 FgPixel = pGC->fgPixel;
1435 BgPixel = pGC->bgPixel;
1436 #endif
1437 /* no exposures here, copy bits from inside a pixmap */
1438 cfbCopyPlaneExpand((DrawablePtr) pBitmap, pDstDrawable, pGC,
1439 0, 0, width, height, dstx, dsty, cfbCopyPlane1toN, 1);
1440 FreeScratchGC (pGC1);
1441 (*pScreen->DestroyPixmap) (pBitmap);
1442 /* compute resultant exposures */
1443 ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC,
1444 srcx, srcy, width, height,
1445 dstx, dsty, bitPlane);
1447 else
1448 #endif
1449 ret = miCopyPlane (pSrcDrawable, pDstDrawable,
1450 pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
1451 return ret;