e:/XFree86 for RH 8.0/XFree86-4.2.0/xc/programs/Xserver/fb/fbbltone.c

Go to the documentation of this file.
00001 /* 00002 * Id: fbbltone.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ 00003 * 00004 * Copyright © 1998 Keith Packard 00005 * 00006 * Permission to use, copy, modify, distribute, and sell this software and its 00007 * documentation for any purpose is hereby granted without fee, provided that 00008 * the above copyright notice appear in all copies and that both that 00009 * copyright notice and this permission notice appear in supporting 00010 * documentation, and that the name of Keith Packard not be used in 00011 * advertising or publicity pertaining to distribution of the software without 00012 * specific, written prior permission. Keith Packard makes no 00013 * representations about the suitability of this software for any purpose. It 00014 * is provided "as is" without express or implied warranty. 00015 * 00016 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 00017 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 00018 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 00019 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 00020 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 00021 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00022 * PERFORMANCE OF THIS SOFTWARE. 00023 */ 00024 /* $XFree86: xc/programs/Xserver/fb/fbbltone.c,v 1.11 2001/09/07 15:15:31 keithp Exp $ */ 00025 00026 #include "fb.h" 00027 00028 /* 00029 * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8) 00030 * 00031 * **** **** **** **** **** **** **** **** 00032 * ^ 00033 * ******** ******** ******** ******** 00034 * ^ 00035 * leftShift = 12 00036 * rightShift = 20 00037 * 00038 * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8) 00039 * 00040 * **** **** **** **** **** **** **** **** 00041 * ^ 00042 * ******** ******** ******** ******** 00043 * ^ 00044 * 00045 * leftShift = 24 00046 * rightShift = 8 00047 */ 00048 00049 #define LoadBits {\ 00050 if (leftShift) { \ 00051 bitsRight = *src++; \ 00052 bits = (FbStipLeft (bitsLeft, leftShift) | \ 00053 FbStipRight(bitsRight, rightShift)); \ 00054 bitsLeft = bitsRight; \ 00055 } else \ 00056 bits = *src++; \ 00057 } 00058 00059 #ifndef FBNOPIXADDR 00060 00061 #define LaneCases1(n,a) case n: (void)FbLaneCase(n,a); break 00062 #define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a) 00063 #define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a) 00064 #define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a) 00065 #define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a) 00066 #define LaneCases32(n,a) LaneCases16(n,a); LaneCases16(n+16,a) 00067 #define LaneCases64(n,a) LaneCases32(n,a); LaneCases32(n+32,a) 00068 #define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a) 00069 #define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a) 00070 00071 #if FB_SHIFT == 6 00072 #define LaneCases(a) LaneCases256(0,a) 00073 #endif 00074 00075 #if FB_SHIFT == 5 00076 #define LaneCases(a) LaneCases16(0,a) 00077 #endif 00078 00079 #if FB_SHIFT == 6 00080 CARD8 fb8Lane[256] = { 00081 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 00082 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 00083 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 00084 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 00085 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 00086 98, 99, 100, 101, 102,103,104,105,106,107,108,109,110,111,112,113,114,115, 00087 116, 117, 118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133, 00088 134, 135, 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151, 00089 152, 153, 154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, 00090 170, 171, 172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187, 00091 188, 189, 190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205, 00092 206, 207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 00093 224, 225, 226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241, 00094 242, 243, 244,245,246,247,248,249,250,251,252,253,254,255, 00095 }; 00096 00097 CARD8 fb16Lane[256] = { 00098 0x00, 0x03, 0x0c, 0x0f, 00099 0x30, 0x33, 0x3c, 0x3f, 00100 0xc0, 0xc3, 0xcc, 0xcf, 00101 0xf0, 0xf3, 0xfc, 0xff, 00102 }; 00103 00104 CARD8 fb32Lane[16] = { 00105 0x00, 0x0f, 0xf0, 0xff, 00106 }; 00107 #endif 00108 00109 #if FB_SHIFT == 5 00110 CARD8 fb8Lane[16] = { 00111 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 00112 }; 00113 00114 CARD8 fb16Lane[16] = { 00115 0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00116 }; 00117 00118 CARD8 fb32Lane[16] = { 00119 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00120 }; 00121 #endif 00122 00123 CARD8 *fbLaneTable[33] = { 00124 0, 0, 0, 0, 0, 0, 0, 0, 00125 fb8Lane, 0, 0, 0, 0, 0, 0, 0, 00126 fb16Lane, 0, 0, 0, 0, 0, 0, 0, 00127 0, 0, 0, 0, 0, 0, 0, 0, 00128 fb32Lane 00129 }; 00130 #endif 00131 00132 void 00133 fbBltOne (FbStip *src, 00134 FbStride srcStride, /* FbStip units per scanline */ 00135 int srcX, /* bit position of source */ 00136 FbBits *dst, 00137 FbStride dstStride, /* FbBits units per scanline */ 00138 int dstX, /* bit position of dest */ 00139 int dstBpp, /* bits per destination unit */ 00140 00141 int width, /* width in bits of destination */ 00142 int height, /* height in scanlines */ 00143 00144 FbBits fgand, /* rrop values */ 00145 FbBits fgxor, 00146 FbBits bgand, 00147 FbBits bgxor) 00148 { 00149 const FbBits *fbBits; 00150 int pixelsPerDst; /* dst pixels per FbBits */ 00151 int unitsPerSrc; /* src patterns per FbStip */ 00152 int leftShift, rightShift; /* align source with dest */ 00153 FbBits startmask, endmask; /* dest scanline masks */ 00154 FbStip bits=0, bitsLeft, bitsRight;/* source bits */ 00155 FbStip left; 00156 FbBits mask; 00157 int nDst; /* dest longwords (w.o. end) */ 00158 int w; 00159 int n, nmiddle; 00160 int dstS; /* stipple-relative dst X coordinate */ 00161 Bool copy; /* accelerate dest-invariant */ 00162 Bool transparent; /* accelerate 0 nop */ 00163 int srcinc; /* source units consumed */ 00164 Bool endNeedsLoad = FALSE; /* need load for endmask */ 00165 #ifndef FBNOPIXADDR 00166 CARD8 *fbLane; 00167 #endif 00168 int startbyte, endbyte; 00169 00170 #ifdef FB_24BIT 00171 if (dstBpp == 24) 00172 { 00173 fbBltOne24 (src, srcStride, srcX, 00174 dst, dstStride, dstX, dstBpp, 00175 width, height, 00176 fgand, fgxor, bgand, bgxor); 00177 return; 00178 } 00179 #endif 00180 00181 /* 00182 * Number of destination units in FbBits == number of stipple pixels 00183 * used each time 00184 */ 00185 pixelsPerDst = FB_UNIT / dstBpp; 00186 00187 /* 00188 * Number of source stipple patterns in FbStip 00189 */ 00190 unitsPerSrc = FB_STIP_UNIT / pixelsPerDst; 00191 00192 copy = FALSE; 00193 transparent = FALSE; 00194 if (bgand == 0 && fgand == 0) 00195 copy = TRUE; 00196 else if (bgand == FB_ALLONES && bgxor == 0) 00197 transparent = TRUE; 00198 00199 /* 00200 * Adjust source and dest to nearest FbBits boundary 00201 */ 00202 src += srcX >> FB_STIP_SHIFT; 00203 dst += dstX >> FB_SHIFT; 00204 srcX &= FB_STIP_MASK; 00205 dstX &= FB_MASK; 00206 00207 FbMaskBitsBytes(dstX, width, copy, 00208 startmask, startbyte, nmiddle, endmask, endbyte); 00209 00210 /* 00211 * Compute effective dest alignment requirement for 00212 * source -- must align source to dest unit boundary 00213 */ 00214 dstS = dstX / dstBpp; 00215 /* 00216 * Compute shift constants for effective alignement 00217 */ 00218 if (srcX >= dstS) 00219 { 00220 leftShift = srcX - dstS; 00221 rightShift = FB_STIP_UNIT - leftShift; 00222 } 00223 else 00224 { 00225 rightShift = dstS - srcX; 00226 leftShift = FB_STIP_UNIT - rightShift; 00227 } 00228 /* 00229 * Get pointer to stipple mask array for this depth 00230 */ 00231 fbBits = 0; /* unused */ 00232 if (pixelsPerDst <= 8) 00233 fbBits = fbStippleTable[pixelsPerDst]; 00234 #ifndef FBNOPIXADDR 00235 fbLane = 0; 00236 if (transparent && fgand == 0 && dstBpp >= 8) 00237 fbLane = fbLaneTable[dstBpp]; 00238 #endif 00239 00240 /* 00241 * Compute total number of destination words written, but 00242 * don't count endmask 00243 */ 00244 nDst = nmiddle; 00245 if (startmask) 00246 nDst++; 00247 00248 dstStride -= nDst; 00249 00250 /* 00251 * Compute total number of source words consumed 00252 */ 00253 00254 srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc; 00255 00256 if (srcX > dstS) 00257 srcinc++; 00258 if (endmask) 00259 { 00260 endNeedsLoad = nDst % unitsPerSrc == 0; 00261 if (endNeedsLoad) 00262 srcinc++; 00263 } 00264 00265 srcStride -= srcinc; 00266 00267 /* 00268 * Copy rectangle 00269 */ 00270 while (height--) 00271 { 00272 w = nDst; /* total units across scanline */ 00273 n = unitsPerSrc; /* units avail in single stipple */ 00274 if (n > w) 00275 n = w; 00276 00277 bitsLeft = 0; 00278 if (srcX > dstS) 00279 bitsLeft = *src++; 00280 if (n) 00281 { 00282 /* 00283 * Load first set of stipple bits 00284 */ 00285 LoadBits; 00286 00287 /* 00288 * Consume stipple bits for startmask 00289 */ 00290 if (startmask) 00291 { 00292 #if FB_UNIT > 32 00293 if (pixelsPerDst == 16) 00294 mask = FbStipple16Bits(FbLeftStipBits(bits,16)); 00295 else 00296 #endif 00297 mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; 00298 #ifndef FBNOPIXADDR 00299 if (fbLane) 00300 { 00301 fbTransparentSpan (dst, mask & startmask, fgxor, 1); 00302 } 00303 else 00304 #endif 00305 { 00306 if (mask || !transparent) 00307 FbDoLeftMaskByteStippleRRop (dst, mask, 00308 fgand, fgxor, bgand, bgxor, 00309 startbyte, startmask); 00310 } 00311 bits = FbStipLeft (bits, pixelsPerDst); 00312 dst++; 00313 n--; 00314 w--; 00315 } 00316 /* 00317 * Consume stipple bits across scanline 00318 */ 00319 for (;;) 00320 { 00321 w -= n; 00322 if (copy) 00323 { 00324 while (n--) 00325 { 00326 #if FB_UNIT > 32 00327 if (pixelsPerDst == 16) 00328 mask = FbStipple16Bits(FbLeftStipBits(bits,16)); 00329 else 00330 #endif 00331 mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; 00332 *dst = FbOpaqueStipple (mask, fgxor, bgxor); 00333 dst++; 00334 bits = FbStipLeft(bits, pixelsPerDst); 00335 } 00336 } 00337 else 00338 { 00339 #ifndef FBNOPIXADDR 00340 if (fbLane) 00341 { 00342 while (bits && n) 00343 { 00344 switch (fbLane[FbLeftStipBits(bits,pixelsPerDst)]) { 00345 LaneCases((CARD8 *) dst); 00346 } 00347 bits = FbStipLeft(bits,pixelsPerDst); 00348 dst++; 00349 n--; 00350 } 00351 dst += n; 00352 } 00353 else 00354 #endif 00355 { 00356 while (n--) 00357 { 00358 left = FbLeftStipBits(bits,pixelsPerDst); 00359 if (left || !transparent) 00360 { 00361 mask = fbBits[left]; 00362 *dst = FbStippleRRop (*dst, mask, 00363 fgand, fgxor, bgand, bgxor); 00364 } 00365 dst++; 00366 bits = FbStipLeft(bits, pixelsPerDst); 00367 } 00368 } 00369 } 00370 if (!w) 00371 break; 00372 /* 00373 * Load another set and reset number of available units 00374 */ 00375 LoadBits; 00376 n = unitsPerSrc; 00377 if (n > w) 00378 n = w; 00379 } 00380 } 00381 /* 00382 * Consume stipple bits for endmask 00383 */ 00384 if (endmask) 00385 { 00386 if (endNeedsLoad) 00387 { 00388 LoadBits; 00389 } 00390 #if FB_UNIT > 32 00391 if (pixelsPerDst == 16) 00392 mask = FbStipple16Bits(FbLeftStipBits(bits,16)); 00393 else 00394 #endif 00395 mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; 00396 #ifndef FBNOPIXADDR 00397 if (fbLane) 00398 { 00399 fbTransparentSpan (dst, mask & endmask, fgxor, 1); 00400 } 00401 else 00402 #endif 00403 { 00404 if (mask || !transparent) 00405 FbDoRightMaskByteStippleRRop (dst, mask, 00406 fgand, fgxor, bgand, bgxor, 00407 endbyte, endmask); 00408 } 00409 } 00410 dst += dstStride; 00411 src += srcStride; 00412 } 00413 } 00414 00415 #ifdef FB_24BIT 00416 00417 /* 00418 * Crufty macros to initialize the mask array, most of this 00419 * is to avoid compile-time warnings about shift overflow 00420 */ 00421 00422 #if BITMAP_BIT_ORDER == MSBFirst 00423 #define Mask24Pos(x,r) ((x)*24-(r)) 00424 #else 00425 #define Mask24Pos(x,r) ((x)*24-((r) ? 24 - (r) : 0)) 00426 #endif 00427 00428 #define Mask24Neg(x,r) (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0) 00429 #define Mask24Check(x,r) (Mask24Pos(x,r) < 0 ? 0 : \ 00430 Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r)) 00431 00432 #define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \ 00433 (Mask24Pos(x,r) < 0 ? \ 00434 0xffffff >> Mask24Neg (x,r) : \ 00435 0xffffff << Mask24Check(x,r)) : 0) 00436 00437 #define SelMask24(b,n,r) ((((b) >> n) & 1) * Mask24(n,r)) 00438 00439 /* 00440 * Untested for MSBFirst or FB_UNIT == 32 00441 */ 00442 00443 #if FB_UNIT == 64 00444 #define C4_24(b,r) \ 00445 (SelMask24(b,0,r) | \ 00446 SelMask24(b,1,r) | \ 00447 SelMask24(b,2,r) | \ 00448 SelMask24(b,3,r)) 00449 00450 #define FbStip24New(rot) (2 + (rot != 0)) 00451 #define FbStip24Len 4 00452 00453 const FbBits fbStipple24Bits[3][1 << FbStip24Len] = { 00454 /* rotate 0 */ 00455 { 00456 C4_24( 0, 0), C4_24( 1, 0), C4_24( 2, 0), C4_24( 3, 0), 00457 C4_24( 4, 0), C4_24( 5, 0), C4_24( 6, 0), C4_24( 7, 0), 00458 C4_24( 8, 0), C4_24( 9, 0), C4_24(10, 0), C4_24(11, 0), 00459 C4_24(12, 0), C4_24(13, 0), C4_24(14, 0), C4_24(15, 0), 00460 }, 00461 /* rotate 8 */ 00462 { 00463 C4_24( 0, 8), C4_24( 1, 8), C4_24( 2, 8), C4_24( 3, 8), 00464 C4_24( 4, 8), C4_24( 5, 8), C4_24( 6, 8), C4_24( 7, 8), 00465 C4_24( 8, 8), C4_24( 9, 8), C4_24(10, 8), C4_24(11, 8), 00466 C4_24(12, 8), C4_24(13, 8), C4_24(14, 8), C4_24(15, 8), 00467 }, 00468 /* rotate 16 */ 00469 { 00470 C4_24( 0,16), C4_24( 1,16), C4_24( 2,16), C4_24( 3,16), 00471 C4_24( 4,16), C4_24( 5,16), C4_24( 6,16), C4_24( 7,16), 00472 C4_24( 8,16), C4_24( 9,16), C4_24(10,16), C4_24(11,16), 00473 C4_24(12,16), C4_24(13,16), C4_24(14,16), C4_24(15,16), 00474 } 00475 }; 00476 00477 #endif 00478 00479 #if FB_UNIT == 32 00480 #define C2_24(b,r) \ 00481 (SelMask24(b,0,r) | \ 00482 SelMask24(b,1,r)) 00483 00484 #define FbStip24Len 2 00485 #if BITMAP_BIT_ORDER == MSBFirst 00486 #define FbStip24New(rot) (1 + (rot == 0)) 00487 #else 00488 #define FbStip24New(rot) (1 + (rot == 8)) 00489 #endif 00490 00491 const FbBits fbStipple24Bits[3][1 << FbStip24Len] = { 00492 /* rotate 0 */ 00493 { 00494 C2_24( 0, 0), C2_24 ( 1, 0), C2_24 ( 2, 0), C2_24 ( 3, 0), 00495 }, 00496 /* rotate 8 */ 00497 { 00498 C2_24( 0, 8), C2_24 ( 1, 8), C2_24 ( 2, 8), C2_24 ( 3, 8), 00499 }, 00500 /* rotate 16 */ 00501 { 00502 C2_24( 0,16), C2_24 ( 1,16), C2_24 ( 2,16), C2_24 ( 3,16), 00503 } 00504 }; 00505 #endif 00506 00507 #if BITMAP_BIT_ORDER == LSBFirst 00508 #define FbMergeStip24Bits(left, right, new) (((left) >> (new)) | \ 00509 (right) << (FbStip24Len - (new))) 00510 #else 00511 #define FbMergeStip24Bits(left, right, new) (((left << new) & \ 00512 ((1 << FbStip24Len) - 1)) | \ 00513 right) 00514 #endif 00515 00516 #define fbFirstStipBits(len,stip) {\ 00517 int __len = (len); \ 00518 if (len <= remain) { \ 00519 stip = FbLeftStipBits(bits, len); \ 00520 } else { \ 00521 stip = FbLeftStipBits(bits, remain); \ 00522 bits = *src++; \ 00523 __len = (len) - remain; \ 00524 stip |= FbStipRight(FbLeftStipBits(bits, __len), remain); \ 00525 remain = FB_STIP_UNIT; \ 00526 } \ 00527 bits = FbStipLeft (bits, __len); \ 00528 remain -= __len; \ 00529 } 00530 00531 #define fbInitStipBits(offset,len,stip) {\ 00532 bits = FbStipLeft (*src++,offset); \ 00533 remain = FB_STIP_UNIT - offset; \ 00534 fbFirstStipBits(len,stip); \ 00535 stip = FbMergeStip24Bits (0, stip, len); \ 00536 } 00537 00538 #define fbNextStipBits(rot,stip) {\ 00539 int __new = FbStip24New(rot); \ 00540 FbStip __right; \ 00541 fbFirstStipBits(__new, __right); \ 00542 stip = FbMergeStip24Bits (stip, __right, __new); \ 00543 rot = FbNext24Rot (rot); \ 00544 } 00545 00546 /* 00547 * Use deep mask tables that incorporate rotation, pull 00548 * a variable number of bits out of the stipple and 00549 * reuse the right bits as needed for the next write 00550 * 00551 * Yes, this is probably too much code, but most 24-bpp screens 00552 * have no acceleration so this code is used for stipples, copyplane 00553 * and text 00554 */ 00555 void 00556 fbBltOne24 (FbStip *srcLine, 00557 FbStride srcStride, /* FbStip units per scanline */ 00558 int srcX, /* bit position of source */ 00559 FbBits *dst, 00560 FbStride dstStride, /* FbBits units per scanline */ 00561 int dstX, /* bit position of dest */ 00562 int dstBpp, /* bits per destination unit */ 00563 00564 int width, /* width in bits of destination */ 00565 int height, /* height in scanlines */ 00566 00567 FbBits fgand, /* rrop values */ 00568 FbBits fgxor, 00569 FbBits bgand, 00570 FbBits bgxor) 00571 { 00572 FbStip *src; 00573 FbBits leftMask, rightMask, mask; 00574 int nlMiddle, nl; 00575 FbStip stip, bits; 00576 int remain; 00577 int dstS; 00578 int firstlen; 00579 int rot0, rot; 00580 int nDst; 00581 00582 srcLine += srcX >> FB_STIP_SHIFT; 00583 dst += dstX >> FB_SHIFT; 00584 srcX &= FB_STIP_MASK; 00585 dstX &= FB_MASK; 00586 rot0 = FbFirst24Rot (dstX); 00587 00588 FbMaskBits (dstX, width, leftMask, nlMiddle, rightMask); 00589 00590 dstS = (dstX + 23) / 24; 00591 firstlen = FbStip24Len - dstS; 00592 00593 nDst = nlMiddle; 00594 if (leftMask) 00595 nDst++; 00596 dstStride -= nDst; 00597 00598 /* opaque copy */ 00599 if (bgand == 0 && fgand == 0) 00600 { 00601 while (height--) 00602 { 00603 rot = rot0; 00604 src = srcLine; 00605 srcLine += srcStride; 00606 fbInitStipBits (srcX,firstlen, stip); 00607 if (leftMask) 00608 { 00609 mask = fbStipple24Bits[rot >> 3][stip]; 00610 *dst = (*dst & ~leftMask) | (FbOpaqueStipple (mask, 00611 FbRot24(fgxor, rot), 00612 FbRot24(bgxor, rot)) 00613 & leftMask); 00614 dst++; 00615 fbNextStipBits(rot,stip); 00616 } 00617 nl = nlMiddle; 00618 while (nl--) 00619 { 00620 mask = fbStipple24Bits[rot>>3][stip]; 00621 *dst = FbOpaqueStipple (mask, 00622 FbRot24(fgxor, rot), 00623 FbRot24(bgxor, rot)); 00624 dst++; 00625 fbNextStipBits(rot,stip); 00626 } 00627 if (rightMask) 00628 { 00629 mask = fbStipple24Bits[rot >> 3][stip]; 00630 *dst = (*dst & ~rightMask) | (FbOpaqueStipple (mask, 00631 FbRot24(fgxor, rot), 00632 FbRot24(bgxor, rot)) 00633 & rightMask); 00634 } 00635 dst += dstStride; 00636 src += srcStride; 00637 } 00638 } 00639 /* transparent copy */ 00640 else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0) 00641 { 00642 while (height--) 00643 { 00644 rot = rot0; 00645 src = srcLine; 00646 srcLine += srcStride; 00647 fbInitStipBits (srcX, firstlen, stip); 00648 if (leftMask) 00649 { 00650 if (stip) 00651 { 00652 mask = fbStipple24Bits[rot >> 3][stip] & leftMask; 00653 *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask); 00654 } 00655 dst++; 00656 fbNextStipBits (rot, stip); 00657 } 00658 nl = nlMiddle; 00659 while (nl--) 00660 { 00661 if (stip) 00662 { 00663 mask = fbStipple24Bits[rot>>3][stip]; 00664 *dst = (*dst & ~mask) | (FbRot24(fgxor,rot) & mask); 00665 } 00666 dst++; 00667 fbNextStipBits (rot, stip); 00668 } 00669 if (rightMask) 00670 { 00671 if (stip) 00672 { 00673 mask = fbStipple24Bits[rot >> 3][stip] & rightMask; 00674 *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask); 00675 } 00676 } 00677 dst += dstStride; 00678 } 00679 } 00680 else 00681 { 00682 while (height--) 00683 { 00684 rot = rot0; 00685 src = srcLine; 00686 srcLine += srcStride; 00687 fbInitStipBits (srcX, firstlen, stip); 00688 if (leftMask) 00689 { 00690 mask = fbStipple24Bits[rot >> 3][stip]; 00691 *dst = FbStippleRRopMask (*dst, mask, 00692 FbRot24(fgand, rot), 00693 FbRot24(fgxor, rot), 00694 FbRot24(bgand, rot), 00695 FbRot24(bgxor, rot), 00696 leftMask); 00697 dst++; 00698 fbNextStipBits(rot,stip); 00699 } 00700 nl = nlMiddle; 00701 while (nl--) 00702 { 00703 mask = fbStipple24Bits[rot >> 3][stip]; 00704 *dst = FbStippleRRop (*dst, mask, 00705 FbRot24(fgand, rot), 00706 FbRot24(fgxor, rot), 00707 FbRot24(bgand, rot), 00708 FbRot24(bgxor, rot)); 00709 dst++; 00710 fbNextStipBits(rot,stip); 00711 } 00712 if (rightMask) 00713 { 00714 mask = fbStipple24Bits[rot >> 3][stip]; 00715 *dst = FbStippleRRopMask (*dst, mask, 00716 FbRot24(fgand, rot), 00717 FbRot24(fgxor, rot), 00718 FbRot24(bgand, rot), 00719 FbRot24(bgxor, rot), 00720 rightMask); 00721 } 00722 dst += dstStride; 00723 } 00724 } 00725 } 00726 #endif 00727 00728 /* 00729 * Not very efficient, but simple -- copy a single plane 00730 * from an N bit image to a 1 bit image 00731 */ 00732 00733 void 00734 fbBltPlane (FbBits *src, 00735 FbStride srcStride, 00736 int srcX, 00737 int srcBpp, 00738 00739 FbStip *dst, 00740 FbStride dstStride, 00741 int dstX, 00742 00743 int width, 00744 int height, 00745 00746 FbStip fgand, 00747 FbStip fgxor, 00748 FbStip bgand, 00749 FbStip bgxor, 00750 Pixel planeMask) 00751 { 00752 FbBits *s; 00753 FbBits pm; 00754 FbBits srcMask; 00755 FbBits srcMaskFirst; 00756 FbBits srcMask0 = 0; 00757 FbBits srcBits; 00758 00759 FbStip dstBits; 00760 FbStip *d; 00761 FbStip dstMask; 00762 FbStip dstMaskFirst; 00763 FbStip dstUnion; 00764 int w; 00765 int wt; 00766 int rot0; 00767 00768 if (!width) 00769 return; 00770 00771 src += srcX >> FB_SHIFT; 00772 srcX &= FB_MASK; 00773 00774 dst += dstX >> FB_STIP_SHIFT; 00775 dstX &= FB_STIP_MASK; 00776 00777 w = width / srcBpp; 00778 00779 pm = fbReplicatePixel (planeMask, srcBpp); 00780 #ifdef FB_24BIT 00781 if (srcBpp == 24) 00782 { 00783 int w = 24; 00784 00785 rot0 = FbFirst24Rot (srcX); 00786 if (srcX + w > FB_UNIT) 00787 w = FB_UNIT - srcX; 00788 srcMaskFirst = FbRot24(pm,rot0) & FbBitsMask(srcX,w); 00789 } 00790 else 00791 #endif 00792 { 00793 rot0 = 0; 00794 srcMaskFirst = pm & FbBitsMask(srcX, srcBpp); 00795 srcMask0 = pm & FbBitsMask(0, srcBpp); 00796 } 00797 00798 dstMaskFirst = FbStipMask(dstX,1); 00799 while (height--) 00800 { 00801 d = dst; 00802 dst += dstStride; 00803 s = src; 00804 src += srcStride; 00805 00806 srcMask = srcMaskFirst; 00807 #ifdef FB_24BIT 00808 if (srcBpp == 24) 00809 srcMask0 = FbRot24(pm,rot0) & FbBitsMask(0, srcBpp); 00810 #endif 00811 srcBits = *s++; 00812 00813 dstMask = dstMaskFirst; 00814 dstUnion = 0; 00815 dstBits = 0; 00816 00817 wt = w; 00818 00819 while (wt--) 00820 { 00821 if (!srcMask) 00822 { 00823 srcBits = *s++; 00824 #ifdef FB_24BIT 00825 if (srcBpp == 24) 00826 srcMask0 = FbNext24Pix(srcMask0) & FbBitsMask(0,24); 00827 #endif 00828 srcMask = srcMask0; 00829 } 00830 if (!dstMask) 00831 { 00832 *d = FbStippleRRopMask(*d, dstBits, 00833 fgand, fgxor, bgand, bgxor, 00834 dstUnion); 00835 d++; 00836 dstMask = FbStipMask(0,1); 00837 dstUnion = 0; 00838 dstBits = 0; 00839 } 00840 if (srcBits & srcMask) 00841 dstBits |= dstMask; 00842 dstUnion |= dstMask; 00843 if (srcBpp == FB_UNIT) 00844 srcMask = 0; 00845 else 00846 srcMask = FbScrRight(srcMask,srcBpp); 00847 dstMask = FbStipRight(dstMask,1); 00848 } 00849 if (dstUnion) 00850 *d = FbStippleRRopMask(*d,dstBits, 00851 fgand, fgxor, bgand, bgxor, 00852 dstUnion); 00853 } 00854 } 00855

Generated on Mon May 10 20:17:42 2004 for XFree86 by doxygen 1.3.7