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.
23 DIB_16BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
25 PBYTE byteaddr
= SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
;
26 PWORD addr
= (PWORD
)byteaddr
+ x
;
32 DIB_16BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
34 PBYTE byteaddr
= SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
;
35 PWORD addr
= (PWORD
)byteaddr
+ x
;
37 return (ULONG
)(*addr
);
41 DIB_16BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
43 PDWORD addr
= (PDWORD
)((PWORD
)(SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
) + x1
);
46 /* This is about 10% faster than the generic C code below */
51 " andl $0xffff, %0\n" /* If the pixel value is "abcd", put "abcdabcd" in %eax */
55 " test $0x01, %%edi\n" /* Align to fullword boundary */
61 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */
63 " rep stosl\n" /* The actual fill */
64 " test $0x01, %1\n" /* One left to do at the right side? */
69 : "r"(c
), "r"(Count
), "D"(addr
)
75 if (0 != (cx
& 0x01)) {
78 addr
= (PDWORD
)((PWORD
)(addr
) + 1);
80 cc
= ((c
& 0xffff) << 16) | (c
& 0xffff);
92 DIB_16BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
94 PBYTE byteaddr
= SurfObj
->pvScan0
+ y1
* SurfObj
->lDelta
;
95 PWORD addr
= (PWORD
)byteaddr
+ x
;
96 LONG lDelta
= SurfObj
->lDelta
;
98 byteaddr
= (PBYTE
)addr
;
103 addr
= (PWORD
)byteaddr
;
108 DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
110 LONG i
, j
, sx
, sy
, xColor
, f1
;
111 PBYTE SourceBits
, DestBits
, SourceLine
, DestLine
;
112 PBYTE SourceBits_4BPP
, SourceLine_4BPP
;
113 DestBits
= BltInfo
->DestSurface
->pvScan0
+ (BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
115 switch(BltInfo
->SourceSurface
->iBitmapFormat
)
118 sx
= BltInfo
->SourcePoint
.x
;
119 sy
= BltInfo
->SourcePoint
.y
;
121 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
123 sx
= BltInfo
->SourcePoint
.x
;
124 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
126 if(DIB_1BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
) == 0)
128 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 0));
130 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 1));
139 SourceBits_4BPP
= BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + (BltInfo
->SourcePoint
.x
>> 1);
141 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
143 SourceLine_4BPP
= SourceBits_4BPP
;
144 sx
= BltInfo
->SourcePoint
.x
;
147 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
149 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
,
150 (*SourceLine_4BPP
& altnotmask
[f1
]) >> (4 * (1 - f1
)));
151 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, xColor
);
152 if(f1
== 1) { SourceLine_4BPP
++; f1
= 0; } else { f1
= 1; }
156 SourceBits_4BPP
+= BltInfo
->SourceSurface
->lDelta
;
161 SourceLine
= BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
164 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
166 SourceBits
= SourceLine
;
169 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
171 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *SourceBits
);
176 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
177 DestLine
+= BltInfo
->DestSurface
->lDelta
;
182 if (NULL
== BltInfo
->XlateSourceToDest
|| 0 != (BltInfo
->XlateSourceToDest
->flXlate
& XO_TRIVIAL
))
184 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
186 SourceBits
= BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
187 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
189 RtlMoveMemory(DestBits
, SourceBits
, 2 * (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
));
190 SourceBits
+= BltInfo
->SourceSurface
->lDelta
;
191 DestBits
+= BltInfo
->DestSurface
->lDelta
;
196 SourceBits
= BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
197 DestBits
= BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
198 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
200 RtlMoveMemory(DestBits
, SourceBits
, 2 * (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
));
201 SourceBits
-= BltInfo
->SourceSurface
->lDelta
;
202 DestBits
-= BltInfo
->DestSurface
->lDelta
;
208 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
210 SourceLine
= BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
212 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
214 SourceBits
= SourceLine
;
216 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
218 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((WORD
*)SourceBits
));
222 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
223 DestLine
+= BltInfo
->DestSurface
->lDelta
;
228 SourceLine
= BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
229 DestLine
= BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
230 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
232 SourceBits
= SourceLine
;
234 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
236 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((WORD
*)SourceBits
));
240 SourceLine
-= BltInfo
->SourceSurface
->lDelta
;
241 DestLine
-= BltInfo
->DestSurface
->lDelta
;
248 SourceLine
= BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 3 * BltInfo
->SourcePoint
.x
;
251 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
253 SourceBits
= SourceLine
;
256 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
258 xColor
= (*(SourceBits
+ 2) << 0x10) +
259 (*(SourceBits
+ 1) << 0x08) +
261 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, xColor
);
266 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
267 DestLine
+= BltInfo
->DestSurface
->lDelta
;
272 SourceLine
= BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 4 * BltInfo
->SourcePoint
.x
;
275 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
277 SourceBits
= SourceLine
;
280 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
282 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((PDWORD
) SourceBits
));
287 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
288 DestLine
+= BltInfo
->DestSurface
->lDelta
;
293 DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
301 DIB_16BPP_BitBlt(PBLTINFO BltInfo
)
304 ULONG SourceX
, SourceY
;
306 ULONG Dest
, Source
= 0, Pattern
= 0;
312 UsesSource
= ROP4_USES_SOURCE(BltInfo
->Rop4
);
313 UsesPattern
= ROP4_USES_PATTERN(BltInfo
->Rop4
);
315 RoundedRight
= BltInfo
->DestRect
.right
-
316 ((BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
) & 0x1);
317 SourceY
= BltInfo
->SourcePoint
.y
;
319 BltInfo
->DestSurface
->pvScan0
+
320 (BltInfo
->DestRect
.left
<< 1) +
321 BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
);
325 if (BltInfo
->PatternSurface
)
327 PatternY
= (BltInfo
->DestRect
.top
+ BltInfo
->BrushOrigin
.y
) %
328 BltInfo
->PatternSurface
->sizlBitmap
.cy
;
332 Pattern
= BltInfo
->Brush
->iSolidColor
|
333 (BltInfo
->Brush
->iSolidColor
<< 16);
337 for (DestY
= BltInfo
->DestRect
.top
; DestY
< BltInfo
->DestRect
.bottom
; DestY
++)
339 SourceX
= BltInfo
->SourcePoint
.x
;
341 for (DestX
= BltInfo
->DestRect
.left
; DestX
< RoundedRight
; DestX
+= 2, DestBits
++, SourceX
+= 2)
347 Source
= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
, SourceY
, BltInfo
->XlateSourceToDest
);
348 Source
|= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
+ 1, SourceY
, BltInfo
->XlateSourceToDest
) << 16;
351 if (BltInfo
->PatternSurface
)
353 Pattern
= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
);
354 Pattern
|= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
+ 1) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
) << 16;
357 *DestBits
= DIB_DoRop(BltInfo
->Rop4
, Dest
, Source
, Pattern
);
360 if (DestX
< BltInfo
->DestRect
.right
)
362 Dest
= *((PUSHORT
)DestBits
);
366 Source
= DIB_GetSource(BltInfo
->SourceSurface
, SourceX
, SourceY
, BltInfo
->XlateSourceToDest
);
369 if (BltInfo
->PatternSurface
)
371 Pattern
= DIB_GetSource(BltInfo
->PatternSurface
, (DestX
+ BltInfo
->BrushOrigin
.x
) % BltInfo
->PatternSurface
->sizlBitmap
.cx
, PatternY
, BltInfo
->XlatePatternToDest
);
374 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, DestX
, DestY
, DIB_DoRop(BltInfo
->Rop4
, Dest
, Source
, Pattern
) & 0xFFFF);
375 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
379 if (BltInfo
->PatternSurface
)
382 PatternY
%= BltInfo
->PatternSurface
->sizlBitmap
.cy
;
385 (ULONG_PTR
)DestBits
-
386 ((BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
) << 1) +
387 BltInfo
->DestSurface
->lDelta
);
395 =======================================
396 Stretching functions goes below
397 Some parts of code are based on an
398 article "Bresenhame image scaling"
399 Dr. Dobb Journal, May 2002
400 =======================================
403 typedef unsigned short PIXEL
;
405 /* 16-bit HiColor (565 format) */
406 inline PIXEL
average16(PIXEL a
, PIXEL b
)
408 // This one doesn't work
413 unsigned short mask = ~ (((a | b) & 0x0410) << 1);
414 return ((a & mask) + (b & mask)) >> 1;
417 // This one should be correct, but it's too long
419 unsigned char r1, g1, b1, r2, g2, b2, rr, gr, br;
422 r1 = (a & 0xF800) >> 11;
423 g1 = (a & 0x7E0) >> 5;
426 r2 = (b & 0xF800) >> 11;
427 g2 = (b & 0x7E0) >> 5;
434 res = (rr << 11) + (gr << 5) + br;
438 return a
; // FIXME: Depend on SetStretchMode
441 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
442 void ScaleLineAvg16(PIXEL
*Target
, PIXEL
*Source
, int SrcWidth
, int TgtWidth
)
444 int NumPixels
= TgtWidth
;
445 int IntPart
= SrcWidth
/ TgtWidth
;
446 int FractPart
= SrcWidth
% TgtWidth
;
447 int Mid
= TgtWidth
>> 1;
452 skip
= (TgtWidth
< SrcWidth
) ? 0 : (TgtWidth
/ (2*SrcWidth
) + 1);
455 while (NumPixels
-- > 0) {
458 p
= average16(p
, *(Source
+1));
472 FinalCopy16(PIXEL
*Target
, PIXEL
*Source
, PSPAN ClipSpans
, UINT ClipSpansCount
, UINT
*SpanIndex
,
473 UINT DestY
, RECTL
*DestRect
)
477 while (ClipSpans
[*SpanIndex
].Y
< DestY
478 || (ClipSpans
[*SpanIndex
].Y
== DestY
479 && ClipSpans
[*SpanIndex
].X
+ ClipSpans
[*SpanIndex
].Width
< DestRect
->left
))
482 if (ClipSpansCount
<= *SpanIndex
)
484 /* No more spans, everything else is clipped away, we're done */
488 while (ClipSpans
[*SpanIndex
].Y
== DestY
)
490 if (ClipSpans
[*SpanIndex
].X
< DestRect
->right
)
492 Left
= max(ClipSpans
[*SpanIndex
].X
, DestRect
->left
);
493 Right
= min(ClipSpans
[*SpanIndex
].X
+ ClipSpans
[*SpanIndex
].Width
, DestRect
->right
);
494 memcpy(Target
+ Left
- DestRect
->left
, Source
+ Left
- DestRect
->left
,
495 (Right
- Left
) * sizeof(PIXEL
));
498 if (ClipSpansCount
<= *SpanIndex
)
500 /* No more spans, everything else is clipped away, we're done */
508 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
509 BOOLEAN
ScaleRectAvg16(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
510 RECTL
* DestRect
, RECTL
*SourceRect
,
511 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
512 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
515 int NumPixels
= DestRect
->bottom
- DestRect
->top
;
516 int IntPart
= (((SourceRect
->bottom
- SourceRect
->top
) / (DestRect
->bottom
- DestRect
->top
)) * SourceSurf
->lDelta
) >> 1;
517 int FractPart
= (SourceRect
->bottom
- SourceRect
->top
) % (DestRect
->bottom
- DestRect
->top
);
518 int Mid
= (DestRect
->bottom
- DestRect
->top
) >> 1;
521 PIXEL
*ScanLine
, *ScanLineAhead
;
522 PIXEL
*PrevSource
= NULL
;
523 PIXEL
*PrevSourceAhead
= NULL
;
524 PIXEL
*Target
= (PIXEL
*) (DestSurf
->pvScan0
+ (DestRect
->top
* DestSurf
->lDelta
) + 2 * DestRect
->left
);
525 PIXEL
*Source
= (PIXEL
*) (SourceSurf
->pvScan0
+ (SourceRect
->top
* SourceSurf
->lDelta
) + 2 * SourceRect
->left
);
531 if (! ClipobjToSpans(&ClipSpans
, &ClipSpansCount
, ClipRegion
, DestRect
))
535 if (0 == ClipSpansCount
)
537 /* No clip spans == empty clipping region, everything clipped away */
538 ASSERT(NULL
== ClipSpans
);
541 skip
= (DestRect
->bottom
- DestRect
->top
< SourceRect
->bottom
- SourceRect
->top
) ? 0 : ((DestRect
->bottom
- DestRect
->top
) / (2 * (SourceRect
->bottom
- SourceRect
->top
)) + 1);
544 ScanLine
= (PIXEL
*)ExAllocatePool(PagedPool
, (DestRect
->right
- DestRect
->left
) * sizeof(PIXEL
));
545 ScanLineAhead
= (PIXEL
*)ExAllocatePool(PagedPool
, (DestRect
->right
- DestRect
->left
) * sizeof(PIXEL
));
547 DestY
= DestRect
->top
;
549 while (NumPixels
-- > 0) {
550 if (Source
!= PrevSource
) {
551 if (Source
== PrevSourceAhead
) {
552 /* the next scan line has already been scaled and stored in
553 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
556 PIXEL
*tmp
= ScanLine
;
557 ScanLine
= ScanLineAhead
;
560 ScaleLineAvg16(ScanLine
, Source
, SourceRect
->right
- SourceRect
->left
, DestRect
->right
- DestRect
->left
);
565 if (E
>= Mid
&& PrevSourceAhead
!= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
)) {
567 ScaleLineAvg16(ScanLineAhead
, (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
), SourceRect
->right
- SourceRect
->left
, DestRect
->right
- DestRect
->left
);
568 for (x
= 0; x
< DestRect
->right
- DestRect
->left
; x
++)
569 ScanLine
[x
] = average16(ScanLine
[x
], ScanLineAhead
[x
]);
570 PrevSourceAhead
= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
);
573 if (! FinalCopy16(Target
, ScanLine
, ClipSpans
, ClipSpansCount
, &SpanIndex
, DestY
, DestRect
))
575 /* No more spans, everything else is clipped away, we're done */
576 ExFreePool(ClipSpans
);
577 ExFreePool(ScanLine
);
578 ExFreePool(ScanLineAhead
);
582 Target
= (PIXEL
*)((BYTE
*)Target
+ DestSurf
->lDelta
);
585 if (E
>= DestRect
->bottom
- DestRect
->top
) {
586 E
-= DestRect
->bottom
- DestRect
->top
;
587 Source
= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
);
591 if (skip
> 0 && Source
!= PrevSource
)
592 ScaleLineAvg16(ScanLine
, Source
, SourceRect
->right
- SourceRect
->left
, DestRect
->right
- DestRect
->left
);
594 if (! FinalCopy16(Target
, ScanLine
, ClipSpans
, ClipSpansCount
, &SpanIndex
, DestY
, DestRect
))
596 /* No more spans, everything else is clipped away, we're done */
597 ExFreePool(ClipSpans
);
598 ExFreePool(ScanLine
);
599 ExFreePool(ScanLineAhead
);
603 Target
= (PIXEL
*)((BYTE
*)Target
+ DestSurf
->lDelta
);
606 ExFreePool(ClipSpans
);
607 ExFreePool(ScanLine
);
608 ExFreePool(ScanLineAhead
);
613 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
614 BOOLEAN
DIB_16BPP_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
615 RECTL
* DestRect
, RECTL
*SourceRect
,
616 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
617 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
630 DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
631 BitsPerFormat(SourceSurf
->iBitmapFormat
), SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
632 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
634 SrcSizeY
= SourceRect
->bottom
;
635 SrcSizeX
= SourceRect
->right
;
637 DesSizeY
= DestRect
->bottom
;
638 DesSizeX
= DestRect
->right
;
641 switch(SourceSurf
->iBitmapFormat
)
644 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
645 /* This is a reference implementation, it hasn't been optimized for speed */
647 for (DesY
=0; DesY
<DestRect
->bottom
; DesY
++)
649 if (DesSizeY
>SrcSizeY
)
650 sy
= (int) ((ULONG
) SrcSizeY
* (ULONG
) DesY
) / ((ULONG
) DesSizeY
);
652 sy
= (int) ((ULONG
) DesSizeY
* (ULONG
) DesY
) / ((ULONG
) SrcSizeY
);
654 if (sy
> SourceRect
->bottom
) break;
656 for (DesX
=0; DesX
<DestRect
->right
; DesX
++)
658 if (DesSizeX
>SrcSizeX
)
659 sx
= (int) ((ULONG
) SrcSizeX
* (ULONG
) DesX
) / ((ULONG
) DesSizeX
);
661 sx
= (int) ((ULONG
) DesSizeX
* (ULONG
) DesX
) / ((ULONG
) SrcSizeX
);
663 if (sx
> SourceRect
->right
) break;
665 if(DIB_1BPP_GetPixel(SourceSurf
, sx
, sy
) == 0)
667 DIB_16BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, 0));
669 DIB_16BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, 1));
676 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
677 /* This is a reference implementation, it hasn't been optimized for speed */
679 for (DesY
=0; DesY
<DestRect
->bottom
; DesY
++)
681 if (DesSizeY
>SrcSizeY
)
682 sy
= (int) ((ULONG
) SrcSizeY
* (ULONG
) DesY
) / ((ULONG
) DesSizeY
);
684 sy
= (int) ((ULONG
) DesSizeY
* (ULONG
) DesY
) / ((ULONG
) SrcSizeY
);
687 if (sy
> SourceRect
->bottom
) break;
690 for (DesX
=0; DesX
<DestRect
->right
; DesX
++)
692 if (DesSizeX
>SrcSizeX
)
693 sx
= (int) ((ULONG
) SrcSizeX
* (ULONG
) DesX
) / ((ULONG
) DesSizeX
);
695 sx
= (int) ((ULONG
) DesSizeX
* (ULONG
) DesX
) / ((ULONG
) SrcSizeX
);
697 if (sx
> SourceRect
->right
) break;
699 color
= DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
);
700 DIB_16BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
706 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
707 /* This is a reference implementation, it hasn't been optimized for speed */
709 for (DesY
=0; DesY
<DestRect
->bottom
; DesY
++)
711 if (DesSizeY
>SrcSizeY
)
712 sy
= (int) ((ULONG
) SrcSizeY
* (ULONG
) DesY
) / ((ULONG
) DesSizeY
);
714 sy
= (int) ((ULONG
) DesSizeY
* (ULONG
) DesY
) / ((ULONG
) SrcSizeY
);
716 if (sy
> SourceRect
->bottom
) break;
718 for (DesX
=0; DesX
<DestRect
->right
; DesX
++)
720 if (DesSizeX
>SrcSizeX
)
721 sx
= (int) ((ULONG
) SrcSizeX
* (ULONG
) DesX
) / ((ULONG
) DesSizeX
);
723 sx
= (int) ((ULONG
) DesSizeX
* (ULONG
) DesX
) / ((ULONG
) SrcSizeX
);
725 if (sx
> SourceRect
->right
) break;
727 color
= DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
);
728 DIB_16BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
734 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
735 /* This is a reference implementation, it hasn't been optimized for speed */
737 for (DesY
=0; DesY
<DestRect
->bottom
; DesY
++)
739 if (DesSizeY
>SrcSizeY
)
740 sy
= (int) ((ULONG
) SrcSizeY
* (ULONG
) DesY
) / ((ULONG
) DesSizeY
);
742 sy
= (int) ((ULONG
) DesSizeY
* (ULONG
) DesY
) / ((ULONG
) SrcSizeY
);
744 if (sy
> SourceRect
->bottom
) break;
746 for (DesX
=0; DesX
<DestRect
->right
; DesX
++)
748 if (DesSizeX
>SrcSizeX
)
749 sx
= (int) ((ULONG
) SrcSizeX
* (ULONG
) DesX
) / ((ULONG
) DesSizeX
);
751 sx
= (int) ((ULONG
) DesSizeX
* (ULONG
) DesX
) / ((ULONG
) SrcSizeX
);
753 if (sx
> SourceRect
->right
) break;
755 color
= DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
);
756 DIB_16BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
762 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
763 /* This is a reference implementation, it hasn't been optimized for speed */
765 for (DesY
=0; DesY
<DestRect
->bottom
; DesY
++)
767 if (DesSizeY
>SrcSizeY
)
768 sy
= (int) ((ULONG
) SrcSizeY
* (ULONG
) DesY
) / ((ULONG
) DesSizeY
);
770 sy
= (int) ((ULONG
) DesSizeY
* (ULONG
) DesY
) / ((ULONG
) SrcSizeY
);
772 if (sy
> SourceRect
->bottom
) break;
774 for (DesX
=0; DesX
<DestRect
->right
; DesX
++)
776 if (DesSizeX
>SrcSizeX
)
777 sx
= (int) ((ULONG
) SrcSizeX
* (ULONG
) DesX
) / ((ULONG
) DesSizeX
);
779 sx
= (int) ((ULONG
) DesSizeX
* (ULONG
) DesX
) / ((ULONG
) SrcSizeX
);
781 if (sx
> SourceRect
->right
) break;
783 color
= DIB_16BPP_GetPixel(SourceSurf
, sx
, sy
);
784 DIB_32BPP_PutPixel(DestSurf
, DesX
, DesY
, XLATEOBJ_iXlate(ColorTranslation
, color
));
791 return ScaleRectAvg16(DestSurf
, SourceSurf
, DestRect
, SourceRect
, MaskOrigin
, BrushOrigin
,
792 ClipRegion
, ColorTranslation
, Mode
);
796 DPRINT1("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf
->iBitmapFormat
));
806 DIB_16BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
807 RECTL
* DestRect
, POINTL
*SourcePoint
,
808 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
810 ULONG RoundedRight
, X
, Y
, SourceX
, SourceY
, Source
, wd
, Dest
;
813 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x1);
814 SourceY
= SourcePoint
->y
;
815 DestBits
= (ULONG
*)(DestSurf
->pvScan0
+
816 (DestRect
->left
<< 1) +
817 DestRect
->top
* DestSurf
->lDelta
);
818 wd
= DestSurf
->lDelta
- ((DestRect
->right
- DestRect
->left
) << 1);
820 for(Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
822 SourceX
= SourcePoint
->x
;
823 for(X
= DestRect
->left
; X
< RoundedRight
; X
+= 2, DestBits
++, SourceX
+= 2)
827 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
828 if(Source
!= iTransColor
)
831 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFFFF);
834 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
+ 1, SourceY
);
835 if(Source
!= iTransColor
)
838 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) << 16);
844 if(X
< DestRect
->right
)
846 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
847 if(Source
!= iTransColor
)
849 *((USHORT
*)DestBits
) = (USHORT
)XLATEOBJ_iXlate(ColorTranslation
, Source
);
852 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
855 DestBits
= (ULONG
*)((ULONG_PTR
)DestBits
+ wd
);