2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: dib4bpp.c,v 1.36 2004/07/03 13:55:35 navaraf Exp $ */
23 DIB_4BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
25 PBYTE addr
= SurfObj
->pvScan0
+ (x
>>1) + y
* SurfObj
->lDelta
;
26 *addr
= (*addr
& notmask
[x
&1]) | (c
<< ((1-(x
&1))<<2));
30 DIB_4BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
32 PBYTE addr
= SurfObj
->pvScan0
+ (x
>>1) + y
* SurfObj
->lDelta
;
33 return (*addr
>> ((1-(x
&1))<<2)) & 0x0f;
37 DIB_4BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
39 PBYTE addr
= SurfObj
->pvScan0
+ (x1
>>1) + y
* SurfObj
->lDelta
;
43 *addr
= (*addr
& notmask
[x1
&1]) | (c
<< ((1-(x1
&1))<<2));
51 DIB_4BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
53 PBYTE addr
= SurfObj
->pvScan0
;
54 int lDelta
= SurfObj
->lDelta
;
56 addr
+= (x
>>1) + y1
* lDelta
;
58 *addr
= (*addr
& notmask
[x
&1]) | (c
<< ((1-(x
&1))<<2));
64 DIB_4BPP_BitBltSrcCopy(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
65 PRECTL DestRect
, POINTL
*SourcePoint
,
66 XLATEOBJ
* ColorTranslation
)
68 LONG i
, j
, sx
, sy
, f2
, xColor
;
69 PBYTE SourceBits_24BPP
, SourceLine_24BPP
;
70 PBYTE DestBits
, DestLine
, SourceBits_8BPP
, SourceLine_8BPP
;
71 PBYTE SourceBits
, SourceLine
;
73 DestBits
= DestSurf
->pvScan0
+ (DestRect
->left
>>1) + DestRect
->top
* DestSurf
->lDelta
;
75 switch(SourceSurf
->iBitmapFormat
)
81 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
84 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
86 if(DIB_1BPP_GetPixel(SourceSurf
, sx
, sy
) == 0)
88 DIB_4BPP_PutPixel(DestSurf
, i
, j
, XLATEOBJ_iXlate(ColorTranslation
, 0));
90 DIB_4BPP_PutPixel(DestSurf
, i
, j
, XLATEOBJ_iXlate(ColorTranslation
, 1));
101 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
105 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
107 if (NULL
!= ColorTranslation
)
109 DIB_4BPP_PutPixel(DestSurf
, i
, j
, XLATEOBJ_iXlate(ColorTranslation
, DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
)));
113 DIB_4BPP_PutPixel(DestSurf
, i
, j
, DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
));
122 SourceBits_8BPP
= SourceSurf
->pvScan0
+ (SourcePoint
->y
* SourceSurf
->lDelta
) + SourcePoint
->x
;
124 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
126 SourceLine_8BPP
= SourceBits_8BPP
;
128 f2
= DestRect
->left
& 1;
130 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
132 *DestLine
= (*DestLine
& notmask
[f2
]) |
133 ((XLATEOBJ_iXlate(ColorTranslation
, *SourceLine_8BPP
)) << ((4 * (1 - f2
))));
134 if(f2
== 1) { DestLine
++; f2
= 0; } else { f2
= 1; }
138 SourceBits_8BPP
+= SourceSurf
->lDelta
;
139 DestBits
+= DestSurf
->lDelta
;
144 SourceLine
= SourceSurf
->pvScan0
+ (SourcePoint
->y
* SourceSurf
->lDelta
) + 2 * SourcePoint
->x
;
147 for (j
= DestRect
->top
; j
< DestRect
->bottom
; j
++)
149 SourceBits
= SourceLine
;
151 f2
= DestRect
->left
& 1;
153 for (i
= DestRect
->left
; i
< DestRect
->right
; i
++)
155 xColor
= *((PWORD
) SourceBits
);
156 *DestBits
= (*DestBits
& notmask
[f2
]) |
157 ((XLATEOBJ_iXlate(ColorTranslation
, xColor
)) << ((4 * (1 - f2
))));
158 if(f2
== 1) { DestBits
++; f2
= 0; } else { f2
= 1; }
162 SourceLine
+= SourceSurf
->lDelta
;
163 DestLine
+= DestSurf
->lDelta
;
168 SourceBits_24BPP
= SourceSurf
->pvScan0
+ (SourcePoint
->y
* SourceSurf
->lDelta
) + SourcePoint
->x
* 3;
170 for (j
=DestRect
->top
; j
<DestRect
->bottom
; j
++)
172 SourceLine_24BPP
= SourceBits_24BPP
;
174 f2
= DestRect
->left
& 1;
176 for (i
=DestRect
->left
; i
<DestRect
->right
; i
++)
178 xColor
= (*(SourceLine_24BPP
+ 2) << 0x10) +
179 (*(SourceLine_24BPP
+ 1) << 0x08) +
180 (*(SourceLine_24BPP
));
181 *DestLine
= (*DestLine
& notmask
[f2
]) |
182 ((XLATEOBJ_iXlate(ColorTranslation
, xColor
)) << ((4 * (1 - f2
))));
183 if(f2
== 1) { DestLine
++; f2
= 0; } else { f2
= 1; }
187 SourceBits_24BPP
+= SourceSurf
->lDelta
;
188 DestBits
+= DestSurf
->lDelta
;
193 SourceLine
= SourceSurf
->pvScan0
+ (SourcePoint
->y
* SourceSurf
->lDelta
) + 4 * SourcePoint
->x
;
196 for (j
= DestRect
->top
; j
< DestRect
->bottom
; j
++)
198 SourceBits
= SourceLine
;
200 f2
= DestRect
->left
& 1;
202 for (i
= DestRect
->left
; i
< DestRect
->right
; i
++)
204 xColor
= *((PDWORD
) SourceBits
);
205 *DestBits
= (*DestBits
& notmask
[f2
]) |
206 ((XLATEOBJ_iXlate(ColorTranslation
, xColor
)) << ((4 * (1 - f2
))));
207 if(f2
== 1) { DestBits
++; f2
= 0; } else { f2
= 1; }
211 SourceLine
+= SourceSurf
->lDelta
;
212 DestLine
+= DestSurf
->lDelta
;
217 DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf
->iBitmapFormat
));
224 DIB_4BPP_BitBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
225 PRECTL DestRect
, POINTL
*SourcePoint
,
226 BRUSHOBJ
*Brush
, POINTL BrushOrigin
,
227 XLATEOBJ
*ColorTranslation
, ULONG Rop4
)
230 ULONG Dest
, Source
, Pattern
= 0, PatternY
;
235 /* Pattern brushes */
236 PGDIBRUSHOBJ GdiBrush
;
237 HBITMAP PatternSurface
= NULL
;
239 ULONG PatternWidth
, PatternHeight
;
240 static const ULONG ExpandSolidColor
[16] =
262 return DIB_4BPP_BitBltSrcCopy(
270 UsesSource
= ((Rop4
& 0xCC0000) >> 2) != (Rop4
& 0x330000);
271 UsesPattern
= (((Rop4
& 0xF00000) >> 4) != (Rop4
& 0x0F0000)) && Brush
;
275 if (Brush
->iSolidColor
== 0xFFFFFFFF)
277 PBITMAPOBJ PatternBitmap
;
279 GdiBrush
= CONTAINING_RECORD(
284 PatternSurface
= GdiBrush
->hbmPattern
;
285 PatternBitmap
= BITMAPOBJ_LockBitmap(GdiBrush
->hbmPattern
);
287 PatternObj
= &PatternBitmap
->SurfObj
;
288 PatternWidth
= PatternObj
->sizlBitmap
.cx
;
289 PatternHeight
= PatternObj
->sizlBitmap
.cy
;
296 Pattern
= ExpandSolidColor
[Brush
->iSolidColor
& 0xF];
301 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x7);
303 for (j
= DestRect
->top
; j
< DestRect
->bottom
; j
++, sy
++)
305 DestBits
= (PULONG
)(DestSurf
->pvScan0
+ (DestRect
->left
>> 1) + j
* DestSurf
->lDelta
);
310 PatternY
= (j
+ BrushOrigin
.y
) % PatternHeight
;
314 Dest
= DIB_4BPP_GetPixel(DestSurf
, i
, j
);
318 Source
= DIB_GetSource(SourceSurf
, sx
, sy
, ColorTranslation
);
323 Pattern
= DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
;
326 DIB_4BPP_PutPixel(DestSurf
, i
, j
, DIB_DoRop(Rop4
, Dest
, Source
, Pattern
) & 0xF);
330 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 1);
333 for (; i
< RoundedRight
; i
+= 8, sx
+= 8, DestBits
++)
339 (DIB_GetSource(SourceSurf
, sx
+ 1, sy
, ColorTranslation
)) |
340 (DIB_GetSource(SourceSurf
, sx
+ 0, sy
, ColorTranslation
) << 4) |
341 (DIB_GetSource(SourceSurf
, sx
+ 3, sy
, ColorTranslation
) << 8) |
342 (DIB_GetSource(SourceSurf
, sx
+ 2, sy
, ColorTranslation
) << 12) |
343 (DIB_GetSource(SourceSurf
, sx
+ 5, sy
, ColorTranslation
) << 16) |
344 (DIB_GetSource(SourceSurf
, sx
+ 4, sy
, ColorTranslation
) << 20) |
345 (DIB_GetSource(SourceSurf
, sx
+ 7, sy
, ColorTranslation
) << 24) |
346 (DIB_GetSource(SourceSurf
, sx
+ 6, sy
, ColorTranslation
) << 28);
350 Pattern
= DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 1) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
;
351 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 0) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 4;
352 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 3) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 8;
353 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 2) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 12;
354 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 5) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 16;
355 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 4) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 20;
356 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 7) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 24;
357 Pattern
|= (DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
+ 6) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
) << 28;
359 *DestBits
= DIB_DoRop(Rop4
, Dest
, Source
, Pattern
);
362 /* Process the rest of pixel on the line */
363 for (; i
< DestRect
->right
; i
++, sx
++)
365 Dest
= DIB_4BPP_GetPixel(DestSurf
, i
, j
);
368 Source
= DIB_GetSource(SourceSurf
, sx
, sy
, ColorTranslation
);
372 Pattern
= DIB_1BPP_GetPixel(PatternObj
, (i
+ BrushOrigin
.x
) % PatternWidth
, PatternY
) ? GdiBrush
->crFore
: GdiBrush
->crBack
;
374 DIB_4BPP_PutPixel(DestSurf
, i
, j
, DIB_DoRop(Rop4
, Dest
, Source
, Pattern
) & 0xF);
378 if (PatternSurface
!= NULL
)
379 BITMAPOBJ_UnlockBitmap(PatternSurface
);
384 BOOLEAN
DIB_4BPP_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
385 RECTL
* DestRect
, RECTL
*SourceRect
,
386 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
387 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
390 DbgPrint("DIB_4BPP_StretchBlt: Source BPP: %u\n", BitsPerFormat(SourceSurf
->iBitmapFormat
));
395 DIB_4BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
396 RECTL
* DestRect
, POINTL
*SourcePoint
,
397 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)