/* * ReactOS W32 Subsystem * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id$ */ #undef WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include "../eng/objects.h" #include "dib.h" VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) { PBYTE addr = SurfObj->pvScan0; addr += (x>>1) + y * SurfObj->lDelta; *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2)); } ULONG DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) { PBYTE addr = SurfObj->pvScan0; return (addr[(x>>1) + y * SurfObj->lDelta] >> ((1-(x&1))<<2) ) & 0x0f; } VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) { PBYTE addr = SurfObj->pvScan0 + (x1>>1) + y * SurfObj->lDelta; LONG cx = x1; while(cx < x2) { *addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2)); if((++x1 & 1) == 0) ++addr; ++cx; } } VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) { PBYTE addr = SurfObj->pvScan0; int lDelta = SurfObj->lDelta; addr += (x>>1) + y1 * lDelta; while(y1++ < y2) { *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2)); addr += lDelta; } } BOOLEAN STATIC DIB_4BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFGDI *DestGDI, SURFGDI *SourceGDI, PRECTL DestRect, POINTL *SourcePoint, XLATEOBJ* ColorTranslation) { LONG i, j, sx, sy, f2, xColor; PBYTE SourceBits_24BPP, SourceLine_24BPP; PBYTE DestBits, DestLine, SourceBits_8BPP, SourceLine_8BPP; PBYTE SourceBits, SourceLine; DestBits = DestSurf->pvScan0 + (DestRect->left>>1) + DestRect->top * DestSurf->lDelta; switch(SourceGDI->BitsPerPixel) { case 1: sx = SourcePoint->x; sy = SourcePoint->y; for (j=DestRect->top; jbottom; j++) { sx = SourcePoint->x; for (i=DestRect->left; iright; i++) { if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) { DIB_4BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0)); } else { DIB_4BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1)); } sx++; } sy++; } break; case 4: sy = SourcePoint->y; for (j=DestRect->top; jbottom; j++) { sx = SourcePoint->x; for (i=DestRect->left; iright; i++) { if (NULL != ColorTranslation) { DIB_4BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy))); } else { DIB_4BPP_PutPixel(DestSurf, i, j, DIB_4BPP_GetPixel(SourceSurf, sx, sy)); } sx++; } sy++; } break; case 8: SourceBits_8BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; for (j=DestRect->top; jbottom; j++) { SourceLine_8BPP = SourceBits_8BPP; DestLine = DestBits; f2 = DestRect->left & 1; for (i=DestRect->left; iright; i++) { *DestLine = (*DestLine & notmask[i&1]) | ((XLATEOBJ_iXlate(ColorTranslation, *SourceLine_8BPP)) << ((4 * (1-(i & 1))))); if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; } SourceLine_8BPP++; } SourceBits_8BPP += SourceSurf->lDelta; DestBits += DestSurf->lDelta; } break; case 16: SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x; DestLine = DestBits; for (j = DestRect->top; j < DestRect->bottom; j++) { SourceBits = SourceLine; DestBits = DestLine; f2 = DestRect->left & 1; for (i = DestRect->left; i < DestRect->right; i++) { xColor = *((PWORD) SourceBits); *DestBits = (*DestBits & notmask[i&1]) | ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(i & 1))))); if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; } SourceBits += 2; } SourceLine += SourceSurf->lDelta; DestLine += DestSurf->lDelta; } break; case 24: SourceBits_24BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3; for (j=DestRect->top; jbottom; j++) { SourceLine_24BPP = SourceBits_24BPP; DestLine = DestBits; f2 = DestRect->left & 1; for (i=DestRect->left; iright; i++) { xColor = (*(SourceLine_24BPP + 2) << 0x10) + (*(SourceLine_24BPP + 1) << 0x08) + (*(SourceLine_24BPP)); *DestLine = (*DestLine & notmask[i&1]) | ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(i & 1))))); if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; } SourceLine_24BPP+=3; } SourceBits_24BPP += SourceSurf->lDelta; DestBits += DestSurf->lDelta; } break; case 32: SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x; DestLine = DestBits; for (j = DestRect->top; j < DestRect->bottom; j++) { SourceBits = SourceLine; DestBits = DestLine; f2 = DestRect->left & 1; for (i = DestRect->left; i < DestRect->right; i++) { xColor = *((PDWORD) SourceBits); *DestBits = (*DestBits & notmask[i&1]) | ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(i & 1))))); if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; } SourceBits += 4; } SourceLine += SourceSurf->lDelta; DestLine += DestSurf->lDelta; } break; default: DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); return FALSE; } return(TRUE); } BOOLEAN DIB_4BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFGDI *DestGDI, SURFGDI *SourceGDI, PRECTL DestRect, POINTL *SourcePoint, PBRUSHOBJ Brush, PPOINTL BrushOrigin, XLATEOBJ *ColorTranslation, ULONG Rop4) { LONG i, j, k, sx, sy; ULONG Dest, Source, Pattern; PULONG DestBits; BOOL UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000); BOOL UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000); LONG RoundedRight = DestRect->right - (DestRect->right & 0x7); static const ULONG ExpandSolidColor[16] = { 0x00000000 /* 0 */, 0x11111111 /* 1 */, 0x22222222 /* 2 */, 0x33333333 /* 3 */, 0x44444444 /* 4 */, 0x55555555 /* 5 */, 0x66666666 /* 6 */, 0x77777777 /* 7 */, 0x88888888 /* 8 */, 0x99999999 /* 9 */, 0xAAAAAAAA /* 10 */, 0xBBBBBBBB /* 11 */, 0xCCCCCCCC /* 12 */, 0xDDDDDDDD /* 13 */, 0xEEEEEEEE /* 14 */, 0xFFFFFFFF /* 15 */, }; if (Rop4 == SRCCOPY) { return(DIB_4BPP_BitBltSrcCopy(DestSurf, SourceSurf, DestGDI, SourceGDI, DestRect, SourcePoint, ColorTranslation)); } else { sy = SourcePoint->y; for (j=DestRect->top; jbottom; j++) { sx = SourcePoint->x; DestBits = (PULONG)(DestSurf->pvScan0 + (DestRect->left>>1) + j * DestSurf->lDelta); for (i=DestRect->left; iiSolidColor & 0xF]; } *DestBits = DIB_DoRop(Rop4, Dest, Source, Pattern); } if (i < DestRect->right) { Dest = *DestBits; for (; i < DestRect->right; i++) { if (UsesSource) { Source = DIB_GetSource(SourceSurf, SourceGDI, sx + i, sy, ColorTranslation); } if (UsesPattern) { /* FIXME: No support for pattern brushes. */ Pattern = ExpandSolidColor[Brush->iSolidColor & 0xF]; } DIB_4BPP_PutPixel(DestSurf, i, j, DIB_DoRop(Rop4, Dest, Source, Pattern) & 0xF); Dest >>= 4; } } } } return TRUE; } /* EOF */