void fbGlyph24(FbBits * dstBits, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int x, int height) { int lshift; FbStip bits; CARD8 *dstLine; CARD8 *dst; FbStip f0, f1, f2; int n; int shift; f0 = fg; f1 = FbRot24(f0, 16); f2 = FbRot24(f0, 8); dstLine = (CARD8 *) dstBits; dstLine += (x & ~3) * 3; dstStride *= (sizeof(FbBits) / sizeof(CARD8)); shift = x & 3; lshift = 4 - shift; while (height--) { bits = *stipple++; n = lshift; dst = dstLine; while (bits) { switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) { case CASE(0, 0, 0, 0): break; case CASE(1, 0, 0, 0): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); break; case CASE(0, 1, 0, 0): WRITE1(dst, 3, _A); WRITE2(dst, 4, _BC); break; case CASE(1, 1, 0, 0): WRITE4(dst, 0, _ABCA); WRITE2(dst, 4, _BC); break; case CASE(0, 0, 1, 0): WRITE2(dst, 6, _AB); WRITE1(dst, 8, _C); break; case CASE(1, 0, 1, 0): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); WRITE2(dst, 6, _AB); WRITE1(dst, 8, _C); break; case CASE(0, 1, 1, 0): WRITE1(dst, 3, _A); WRITE4(dst, 4, _BCAB); WRITE1(dst, 8, _C); break; case CASE(1, 1, 1, 0): WRITE8(dst); WRITE1(dst, 8, _C); break; case CASE(0, 0, 0, 1): WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(1, 0, 0, 1): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(0, 1, 0, 1): WRITE1(dst, 3, _A); WRITE2(dst, 4, _BC); WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(1, 1, 0, 1): WRITE4(dst, 0, _ABCA); WRITE2(dst, 4, _BC); WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(0, 0, 1, 1): WRITE2(dst, 6, _AB); WRITE4(dst, 8, _CABC); break; case CASE(1, 0, 1, 1): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); WRITE2(dst, 6, _AB); WRITE4(dst, 8, _CABC); break; case CASE(0, 1, 1, 1): WRITE1(dst, 3, _A); WRITE4(dst, 4, _BCAB); WRITE4(dst, 8, _CABC); break; case CASE(1, 1, 1, 1): WRITE8(dst); WRITE4(dst, 8, _CABC); break; } bits = FbStipLeft(bits, n); n = 4; dst += 12; } dstLine += dstStride; } }
/* * Use deep mask tables that incorporate rotation, pull * a variable number of bits out of the stipple and * reuse the right bits as needed for the next write * * Yes, this is probably too much code, but most 24-bpp screens * have no acceleration so this code is used for stipples, copyplane * and text */ void fbBltOne24(FbStip * srcLine, FbStride srcStride, /* FbStip units per scanline */ int srcX, /* bit position of source */ FbBits * dst, FbStride dstStride, /* FbBits units per scanline */ int dstX, /* bit position of dest */ int dstBpp, /* bits per destination unit */ int width, /* width in bits of destination */ int height, /* height in scanlines */ FbBits fgand, /* rrop values */ FbBits fgxor, FbBits bgand, FbBits bgxor) { FbStip *src, *srcEnd; FbBits leftMask, rightMask, mask; int nlMiddle, nl; FbStip stip, bits; int remain; int dstS; int firstlen; int rot0, rot; int nDst; /* * Do not read past the end of the buffer! */ srcEnd = srcLine + height * srcStride; srcLine += srcX >> FB_STIP_SHIFT; dst += dstX >> FB_SHIFT; srcX &= FB_STIP_MASK; dstX &= FB_MASK; rot0 = FbFirst24Rot(dstX); FbMaskBits(dstX, width, leftMask, nlMiddle, rightMask); dstS = (dstX + 23) / 24; firstlen = FbStip24Len - dstS; nDst = nlMiddle; if (leftMask) nDst++; dstStride -= nDst; /* opaque copy */ if (bgand == 0 && fgand == 0) { while (height--) { rot = rot0; src = srcLine; srcLine += srcStride; fbInitStipBits(srcX, firstlen, stip); if (leftMask) { mask = fbStipple24Bits[rot >> 3][stip]; WRITE(dst, (READ(dst) & ~leftMask) | (FbOpaqueStipple(mask, FbRot24(fgxor, rot), FbRot24(bgxor, rot)) & leftMask)); dst++; fbNextStipBits(rot, stip); } nl = nlMiddle; while (nl--) { mask = fbStipple24Bits[rot >> 3][stip]; WRITE(dst, FbOpaqueStipple(mask, FbRot24(fgxor, rot), FbRot24(bgxor, rot))); dst++; fbNextStipBits(rot, stip); } if (rightMask) { mask = fbStipple24Bits[rot >> 3][stip]; WRITE(dst, (READ(dst) & ~rightMask) | (FbOpaqueStipple(mask, FbRot24(fgxor, rot), FbRot24(bgxor, rot)) & rightMask)); } dst += dstStride; src += srcStride; } } /* transparent copy */ else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0) {