revert 17709 for it break streach for windows mode. That why I did only got black...
[reactos.git] / reactos / subsys / win32k / dib / dib8bpp.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id$ */
20
21 #include <w32k.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 VOID
27 DIB_8BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
28 {
29 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x;
30
31 *byteaddr = c;
32 }
33
34 ULONG
35 DIB_8BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
36 {
37 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x;
38
39 return (ULONG)(*byteaddr);
40 }
41
42 VOID
43 DIB_8BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
44 {
45 memset((PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x1, (BYTE) c, x2 - x1);
46 }
47
48 VOID
49 DIB_8BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
50 {
51 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta;
52 PBYTE addr = byteaddr + x;
53 LONG lDelta = SurfObj->lDelta;
54
55 byteaddr = addr;
56 while(y1++ < y2) {
57 *addr = c;
58
59 addr += lDelta;
60 }
61 }
62
63 BOOLEAN
64 DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
65 {
66 LONG i, j, sx, sy, xColor, f1;
67 PBYTE SourceBits, DestBits, SourceLine, DestLine;
68 PBYTE SourceBits_4BPP, SourceLine_4BPP;
69
70 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
71
72 switch(BltInfo->SourceSurface->iBitmapFormat)
73 {
74 case BMF_1BPP:
75 sx = BltInfo->SourcePoint.x;
76 sy = BltInfo->SourcePoint.y;
77
78 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
79 {
80 sx = BltInfo->SourcePoint.x;
81 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
82 {
83 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
84 {
85 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
86 } else {
87 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
88 }
89 sx++;
90 }
91 sy++;
92 }
93 break;
94
95 case BMF_4BPP:
96 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
97
98 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
99 {
100 SourceLine_4BPP = SourceBits_4BPP;
101 sx = BltInfo->SourcePoint.x;
102 f1 = sx & 1;
103
104 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
105 {
106 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
107 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
108 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
109 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
110 sx++;
111 }
112
113 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
114 }
115 break;
116
117 case BMF_8BPP:
118 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
119 {
120 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
121 {
122 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
123 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
124 {
125 RtlMoveMemory(DestBits, SourceBits, BltInfo->DestRect.right - BltInfo->DestRect.left);
126 SourceBits += BltInfo->SourceSurface->lDelta;
127 DestBits += BltInfo->DestSurface->lDelta;
128 }
129 }
130 else
131 {
132 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
133 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
134 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
135 {
136 RtlMoveMemory(DestBits, SourceBits, BltInfo->DestRect.right - BltInfo->DestRect.left);
137 SourceBits -= BltInfo->SourceSurface->lDelta;
138 DestBits -= BltInfo->DestSurface->lDelta;
139 }
140 }
141 }
142 else
143 {
144 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
145 {
146 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
147 DestLine = DestBits;
148 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
149 {
150 SourceBits = SourceLine;
151 DestBits = DestLine;
152 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
153 {
154 *DestBits++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits++);
155 }
156 SourceLine += BltInfo->SourceSurface->lDelta;
157 DestLine += BltInfo->DestSurface->lDelta;
158 }
159 }
160 else
161 {
162 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
163 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
164 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
165 {
166 SourceBits = SourceLine;
167 DestBits = DestLine;
168 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
169 {
170 *DestBits++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits++);
171 }
172 SourceLine -= BltInfo->SourceSurface->lDelta;
173 DestLine -= BltInfo->DestSurface->lDelta;
174 }
175 }
176 }
177 break;
178
179 case BMF_16BPP:
180 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
181 DestLine = DestBits;
182
183 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
184 {
185 SourceBits = SourceLine;
186 DestBits = DestLine;
187
188 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
189 {
190 xColor = *((PWORD) SourceBits);
191 *DestBits = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
192 SourceBits += 2;
193 DestBits += 1;
194 }
195
196 SourceLine += BltInfo->SourceSurface->lDelta;
197 DestLine += BltInfo->DestSurface->lDelta;
198 }
199 break;
200
201 case BMF_24BPP:
202 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
203 DestLine = DestBits;
204
205 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
206 {
207 SourceBits = SourceLine;
208 DestBits = DestLine;
209
210 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
211 {
212 xColor = (*(SourceBits + 2) << 0x10) +
213 (*(SourceBits + 1) << 0x08) +
214 (*(SourceBits));
215 *DestBits = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
216 SourceBits += 3;
217 DestBits += 1;
218 }
219
220 SourceLine += BltInfo->SourceSurface->lDelta;
221 DestLine += BltInfo->DestSurface->lDelta;
222 }
223 break;
224
225 case BMF_32BPP:
226 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
227 DestLine = DestBits;
228
229 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
230 {
231 SourceBits = SourceLine;
232 DestBits = DestLine;
233
234 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
235 {
236 xColor = *((PDWORD) SourceBits);
237 *DestBits = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
238 SourceBits += 4;
239 DestBits += 1;
240 }
241
242 SourceLine += BltInfo->SourceSurface->lDelta;
243 DestLine += BltInfo->DestSurface->lDelta;
244 }
245 break;
246
247 default:
248 DPRINT1("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
249 return FALSE;
250 }
251
252 return TRUE;
253 }
254
255 /* BitBlt Optimize */
256 BOOLEAN
257 DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
258 {
259 ULONG DestY;
260 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
261 {
262 DIB_8BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
263 }
264
265 return TRUE;
266 }
267 /*
268 =======================================
269 Stretching functions goes below
270 Some parts of code are based on an
271 article "Bresenhame image scaling"
272 Dr. Dobb Journal, May 2002
273 =======================================
274 */
275
276 typedef unsigned char PIXEL;
277
278 /* 16-bit HiColor (565 format) */
279 __inline PIXEL average8(PIXEL a, PIXEL b)
280 {
281 return a; // FIXME: Depend on SetStretchMode
282 }
283
284 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
285 void ScaleLineAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
286 {
287 int NumPixels = TgtWidth;
288 int IntPart = SrcWidth / TgtWidth;
289 int FractPart = SrcWidth % TgtWidth;
290 int Mid = TgtWidth >> 1;
291 int E = 0;
292 int skip;
293 PIXEL p;
294
295 skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
296 NumPixels -= skip;
297
298 while (NumPixels-- > 0) {
299 p = *Source;
300 if (E >= Mid)
301 p = average8(p, *(Source+1));
302 *Target++ = p;
303 Source += IntPart;
304 E += FractPart;
305 if (E >= TgtWidth) {
306 E -= TgtWidth;
307 Source++;
308 } /* if */
309 } /* while */
310 while (skip-- > 0)
311 *Target++ = *Source;
312 }
313
314 static BOOLEAN
315 FinalCopy8(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
316 UINT DestY, RECTL *DestRect)
317 {
318 LONG Left, Right;
319
320 while (ClipSpans[*SpanIndex].Y < DestY
321 || (ClipSpans[*SpanIndex].Y == DestY
322 && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
323 {
324 (*SpanIndex)++;
325 if (ClipSpansCount <= *SpanIndex)
326 {
327 /* No more spans, everything else is clipped away, we're done */
328 return FALSE;
329 }
330 }
331 while (ClipSpans[*SpanIndex].Y == DestY)
332 {
333 if (ClipSpans[*SpanIndex].X < DestRect->right)
334 {
335 Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
336 Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
337 memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
338 (Right - Left) * sizeof(PIXEL));
339 }
340 (*SpanIndex)++;
341 if (ClipSpansCount <= *SpanIndex)
342 {
343 /* No more spans, everything else is clipped away, we're done */
344 return FALSE;
345 }
346 }
347
348 return TRUE;
349 }
350
351 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
352 BOOLEAN ScaleRectAvg8(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
353 RECTL* DestRect, RECTL *SourceRect,
354 POINTL* MaskOrigin, POINTL BrushOrigin,
355 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
356 ULONG Mode)
357 {
358 int NumPixels = DestRect->bottom - DestRect->top;
359 int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceSurf->lDelta); //((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left);
360 int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
361 int Mid = (DestRect->bottom - DestRect->top) >> 1;
362 int E = 0;
363 int skip;
364 PIXEL *ScanLine, *ScanLineAhead;
365 PIXEL *PrevSource = NULL;
366 PIXEL *PrevSourceAhead = NULL;
367 PIXEL *Target = (PIXEL *) ((PBYTE)DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left);
368 PIXEL *Source = (PIXEL *) ((PBYTE)SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left);
369 PSPAN ClipSpans;
370 UINT ClipSpansCount;
371 UINT SpanIndex;
372 LONG DestY;
373
374 if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
375 {
376 return FALSE;
377 }
378 if (0 == ClipSpansCount)
379 {
380 /* No clip spans == empty clipping region, everything clipped away */
381 ASSERT(NULL == ClipSpans);
382 return TRUE;
383 }
384 skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
385 NumPixels -= skip;
386
387 ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
388 ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
389
390 DestY = DestRect->top;
391 SpanIndex = 0;
392 while (NumPixels-- > 0) {
393 if (Source != PrevSource) {
394 if (Source == PrevSourceAhead) {
395 /* the next scan line has already been scaled and stored in
396 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
397 * point to
398 */
399 PIXEL *tmp = ScanLine;
400 ScanLine = ScanLineAhead;
401 ScanLineAhead = tmp;
402 } else {
403 ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
404 } /* if */
405 PrevSource = Source;
406 } /* if */
407
408 if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceSurf->lDelta)) {
409 int x;
410 ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceSurf->lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
411 for (x = 0; x < DestRect->right - DestRect->left; x++)
412 ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
413 PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
414 } /* if */
415
416 if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
417 {
418 /* No more spans, everything else is clipped away, we're done */
419 ExFreePool(ClipSpans);
420 ExFreePool(ScanLine);
421 ExFreePool(ScanLineAhead);
422 return TRUE;
423 }
424 DestY++;
425 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
426 Source += IntPart;
427 E += FractPart;
428 if (E >= DestRect->bottom - DestRect->top) {
429 E -= DestRect->bottom - DestRect->top;
430 Source = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
431 } /* if */
432 } /* while */
433
434 if (skip > 0 && Source != PrevSource)
435 ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
436 while (skip-- > 0) {
437 if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
438 {
439 /* No more spans, everything else is clipped away, we're done */
440 ExFreePool(ClipSpans);
441 ExFreePool(ScanLine);
442 ExFreePool(ScanLineAhead);
443 return TRUE;
444 }
445 DestY++;
446 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
447 } /* while */
448
449 ExFreePool(ClipSpans);
450 ExFreePool(ScanLine);
451 ExFreePool(ScanLineAhead);
452
453 return TRUE;
454 }
455
456 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
457 BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
458 RECTL* DestRect, RECTL *SourceRect,
459 POINTL* MaskOrigin, POINTL BrushOrigin,
460 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
461 ULONG Mode)
462 {
463 int SrcSizeY;
464 int SrcSizeX;
465 int DesSizeY;
466 int DesSizeX;
467 int sx;
468 int sy;
469 int DesX;
470 int DesY;
471 int color;
472 int zoomX;
473 int zoomY;
474 int count;
475 int saveX;
476 int saveY;
477 BOOLEAN DesIsBiggerY=FALSE;
478
479 DPRINT("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
480 BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
481 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
482
483 SrcSizeY = SourceRect->bottom;
484 SrcSizeX = SourceRect->right;
485
486 DesSizeY = DestRect->bottom;
487 DesSizeX = DestRect->right;
488
489 zoomX = DesSizeX / SrcSizeX;
490 if (zoomX==0) zoomX=1;
491
492 zoomY = DesSizeY / SrcSizeY;
493 if (zoomY==0) zoomY=1;
494
495 if (DesSizeY>SrcSizeY)
496 DesIsBiggerY = TRUE;
497
498 switch(SourceSurf->iBitmapFormat)
499 {
500 case BMF_1BPP:
501 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
502 /* This is a reference implementation, it hasn't been optimized for speed */
503 if (zoomX>1)
504 {
505 /* Draw one Hline on X - Led to the Des Zoom In*/
506 if (DesSizeX>SrcSizeX)
507 {
508 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
509 {
510 if (DesIsBiggerY)
511 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
512 else
513 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
514
515 if (sy > SourceRect->bottom) break;
516
517 saveY = DesY+zoomY;
518
519 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
520 {
521 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
522
523 if (sx > SourceRect->right) break;
524
525 saveX = DesX + zoomX;
526
527 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
528 for (count=DesY;count<saveY;count++)
529 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 0);
530 else
531 for (count=DesY;count<saveY;count++)
532 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 1);
533
534 }
535 }
536 }
537 else
538 {
539 /* Draw one Hline on X - Led to the Des Zoom Out*/
540
541 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
542 {
543 if (DesIsBiggerY)
544 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
545 else
546 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
547
548 if (sy > SourceRect->bottom) break;
549
550 saveY = DesY+zoomY;
551
552 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
553 {
554 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
555
556 if (sx > SourceRect->right) break;
557
558 saveX = DesX + zoomX;
559
560 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
561 for (count=DesY;count<saveY;count++)
562 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 0);
563 else
564 for (count=DesY;count<saveY;count++)
565 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 1);
566
567 }
568 }
569 }
570 }
571 else
572 {
573
574 if (DesSizeX>SrcSizeX)
575 {
576 /* Draw one pixel on X - Led to the Des Zoom In*/
577 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
578 {
579 if (DesIsBiggerY)
580 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
581 else
582 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
583
584 if (sy > SourceRect->bottom) break;
585
586 saveY = DesY+zoomY;
587
588 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
589 {
590 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
591
592 if (sx > SourceRect->right) break;
593
594 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
595 for (count=DesY;count<saveY;count++)
596 DIB_8BPP_PutPixel(DestSurf, DesX, count, 0);
597 else
598 for (count=DesY;count<saveY;count++)
599 DIB_8BPP_PutPixel(DestSurf, DesX, count, 1);
600
601
602 }
603 }
604 }
605 else
606 {
607 /* Draw one pixel on X - Led to the Des Zoom Out*/
608 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
609 {
610 if (DesIsBiggerY)
611 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
612 else
613 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
614
615 if (sy > SourceRect->bottom) break;
616
617 saveY = DesY+zoomY;
618
619 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
620 {
621 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
622
623 if (sx > SourceRect->right) break;
624
625 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
626 for (count=DesY;count<saveY;count++)
627 DIB_8BPP_PutPixel(DestSurf, DesX, count, 0);
628 else
629 for (count=DesY;count<saveY;count++)
630 DIB_8BPP_PutPixel(DestSurf, DesX, count, 1);
631
632 }
633 }
634 }
635 }
636 break;
637
638 case BMF_4BPP:
639 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
640 /* This is a reference implementation, it hasn't been optimized for speed */
641 if (zoomX>1)
642 {
643 /* Draw one Hline on X - Led to the Des Zoom In*/
644 if (DesSizeX>SrcSizeX)
645 {
646 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
647 {
648 if (DesIsBiggerY)
649 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
650 else
651 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
652
653 if (sy > SourceRect->bottom) break;
654
655 saveY = DesY+zoomY;
656
657 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
658 {
659 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
660
661 if (sx > SourceRect->right) break;
662
663 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
664
665 saveX = DesX + zoomX;
666 for (count=DesY;count<saveY;count++)
667 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
668 }
669 }
670 }
671 else
672 {
673 /* Draw one Hline on X - Led to the Des Zoom Out*/
674
675 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
676 {
677 if (DesIsBiggerY)
678 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
679 else
680 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
681
682 if (sy > SourceRect->bottom) break;
683
684 saveY = DesY+zoomY;
685
686 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
687 {
688 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
689
690 if (sx > SourceRect->right) break;
691
692 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
693
694 saveX = DesX + zoomX;
695 for (count=DesY;count<saveY;count++)
696 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
697 }
698 }
699 }
700 }
701
702 else
703 {
704
705 if (DesSizeX>SrcSizeX)
706 {
707 /* Draw one pixel on X - Led to the Des Zoom In*/
708 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
709 {
710 if (DesIsBiggerY)
711 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
712 else
713 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
714
715 if (sy > SourceRect->bottom) break;
716
717 saveY = DesY+zoomY;
718
719 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
720 {
721 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
722
723 if (sx > SourceRect->right) break;
724
725 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
726
727 for (count=DesY;count<saveY;count++)
728 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
729 }
730 }
731 }
732 else
733 {
734 /* Draw one pixel on X - Led to the Des Zoom Out*/
735 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
736 {
737 if (DesIsBiggerY)
738 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
739 else
740 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
741
742 if (sy > SourceRect->bottom) break;
743
744 saveY = DesY+zoomY;
745
746 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
747 {
748 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
749
750 if (sx > SourceRect->right) break;
751
752 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
753
754 for (count=DesY;count<saveY;count++)
755 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
756 }
757 }
758 }
759 }
760 break;
761
762 case BMF_8BPP:
763 return ScaleRectAvg8(DestSurf, SourceSurf, DestRect, SourceRect, MaskOrigin, BrushOrigin,
764 ClipRegion, ColorTranslation, Mode);
765 break;
766
767 case BMF_16BPP:
768 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
769 /* This is a reference implementation, it hasn't been optimized for speed */
770 if (zoomX>1)
771 {
772 /* Draw one Hline on X - Led to the Des Zoom In*/
773 if (DesSizeX>SrcSizeX)
774 {
775 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
776 {
777 if (DesIsBiggerY)
778 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
779 else
780 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
781
782 if (sy > SourceRect->bottom) break;
783
784 saveY = DesY+zoomY;
785
786 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
787 {
788 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
789
790 if (sx > SourceRect->right) break;
791
792 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
793
794 saveX = DesX + zoomX;
795 for (count=DesY;count<saveY;count++)
796 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
797 }
798 }
799 }
800 else
801 {
802 /* Draw one Hline on X - Led to the Des Zoom Out*/
803
804 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
805 {
806 if (DesIsBiggerY)
807 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
808 else
809 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
810
811 if (sy > SourceRect->bottom) break;
812
813 saveY = DesY+zoomY;
814
815 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
816 {
817 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
818
819 if (sx > SourceRect->right) break;
820
821 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
822
823 saveX = DesX + zoomX;
824 for (count=DesY;count<saveY;count++)
825 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
826 }
827 }
828 }
829 }
830
831 else
832 {
833
834 if (DesSizeX>SrcSizeX)
835 {
836 /* Draw one pixel on X - Led to the Des Zoom In*/
837 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
838 {
839 if (DesIsBiggerY)
840 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
841 else
842 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
843
844 if (sy > SourceRect->bottom) break;
845
846 saveY = DesY+zoomY;
847
848 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
849 {
850 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
851
852 if (sx > SourceRect->right) break;
853
854 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
855
856 for (count=DesY;count<saveY;count++)
857 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
858 }
859 }
860 }
861 else
862 {
863 /* Draw one pixel on X - Led to the Des Zoom Out*/
864 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
865 {
866 if (DesIsBiggerY)
867 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
868 else
869 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
870
871 if (sy > SourceRect->bottom) break;
872
873 saveY = DesY+zoomY;
874
875 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
876 {
877 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
878
879 if (sx > SourceRect->right) break;
880
881 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
882
883 for (count=DesY;count<saveY;count++)
884 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
885 }
886 }
887 }
888 }
889 break;
890
891 case BMF_24BPP:
892 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
893 /* This is a reference implementation, it hasn't been optimized for speed */
894 if (zoomX>1)
895 {
896 /* Draw one Hline on X - Led to the Des Zoom In*/
897 if (DesSizeX>SrcSizeX)
898 {
899 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
900 {
901 if (DesIsBiggerY)
902 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
903 else
904 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
905
906 if (sy > SourceRect->bottom) break;
907
908 saveY = DesY+zoomY;
909
910 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
911 {
912 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
913
914 if (sx > SourceRect->right) break;
915
916 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
917
918 saveX = DesX + zoomX;
919 for (count=DesY;count<saveY;count++)
920 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
921 }
922 }
923 }
924 else
925 {
926 /* Draw one Hline on X - Led to the Des Zoom Out*/
927
928 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
929 {
930 if (DesIsBiggerY)
931 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
932 else
933 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
934
935 if (sy > SourceRect->bottom) break;
936
937 saveY = DesY+zoomY;
938
939 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
940 {
941 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
942
943 if (sx > SourceRect->right) break;
944
945 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
946
947 saveX = DesX + zoomX;
948 for (count=DesY;count<saveY;count++)
949 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
950 }
951 }
952 }
953 }
954
955 else
956 {
957
958 if (DesSizeX>SrcSizeX)
959 {
960 /* Draw one pixel on X - Led to the Des Zoom In*/
961 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
962 {
963 if (DesIsBiggerY)
964 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
965 else
966 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
967
968 if (sy > SourceRect->bottom) break;
969
970 saveY = DesY+zoomY;
971
972 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
973 {
974 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
975
976 if (sx > SourceRect->right) break;
977
978 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
979
980 for (count=DesY;count<saveY;count++)
981 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
982 }
983 }
984 }
985 else
986 {
987 /* Draw one pixel on X - Led to the Des Zoom Out*/
988 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
989 {
990 if (DesIsBiggerY)
991 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
992 else
993 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
994
995 if (sy > SourceRect->bottom) break;
996
997 saveY = DesY+zoomY;
998
999 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1000 {
1001 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1002
1003 if (sx > SourceRect->right) break;
1004
1005 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1006
1007 for (count=DesY;count<saveY;count++)
1008 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1009 }
1010 }
1011 }
1012 }
1013 break;
1014
1015 case BMF_32BPP:
1016 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1017 /* This is a reference implementation, it hasn't been optimized for speed */
1018 if (zoomX>1)
1019 {
1020 /* Draw one Hline on X - Led to the Des Zoom In*/
1021 if (DesSizeX>SrcSizeX)
1022 {
1023 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1024 {
1025 if (DesIsBiggerY)
1026 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1027 else
1028 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1029
1030 if (sy > SourceRect->bottom) break;
1031
1032 saveY = DesY+zoomY;
1033
1034 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1035 {
1036 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1037
1038 if (sx > SourceRect->right) break;
1039
1040 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1041
1042 saveX = DesX + zoomX;
1043 for (count=DesY;count<saveY;count++)
1044 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
1045 }
1046 }
1047 }
1048 else
1049 {
1050 /* Draw one Hline on X - Led to the Des Zoom Out*/
1051
1052 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1053 {
1054 if (DesIsBiggerY)
1055 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1056 else
1057 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1058
1059 if (sy > SourceRect->bottom) break;
1060
1061 saveY = DesY+zoomY;
1062
1063 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1064 {
1065 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1066
1067 if (sx > SourceRect->right) break;
1068
1069 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1070
1071 saveX = DesX + zoomX;
1072 for (count=DesY;count<saveY;count++)
1073 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
1074 }
1075 }
1076 }
1077 }
1078
1079 else
1080 {
1081
1082 if (DesSizeX>SrcSizeX)
1083 {
1084 /* Draw one pixel on X - Led to the Des Zoom In*/
1085 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1086 {
1087 if (DesIsBiggerY)
1088 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1089 else
1090 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1091
1092 if (sy > SourceRect->bottom) break;
1093
1094 saveY = DesY+zoomY;
1095
1096 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1097 {
1098 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1099
1100 if (sx > SourceRect->right) break;
1101
1102 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1103
1104 for (count=DesY;count<saveY;count++)
1105 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1106 }
1107 }
1108 }
1109 else
1110 {
1111 /* Draw one pixel on X - Led to the Des Zoom Out*/
1112 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1113 {
1114 if (DesIsBiggerY)
1115 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1116 else
1117 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1118
1119 if (sy > SourceRect->bottom) break;
1120
1121 saveY = DesY+zoomY;
1122
1123 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1124 {
1125 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1126
1127 if (sx > SourceRect->right) break;
1128
1129 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1130
1131 for (count=DesY;count<saveY;count++)
1132 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1133 }
1134 }
1135 }
1136 }
1137 break;
1138
1139
1140 default:
1141 DPRINT1("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
1142 return FALSE;
1143 }
1144
1145 return TRUE;
1146 }
1147
1148 BOOLEAN
1149 DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
1150 RECTL* DestRect, POINTL *SourcePoint,
1151 XLATEOBJ *ColorTranslation, ULONG iTransColor)
1152 {
1153 ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest;
1154 ULONG *DestBits;
1155
1156 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
1157 SourceY = SourcePoint->y;
1158 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
1159 (DestRect->top * DestSurf->lDelta));
1160 wd = DestSurf->lDelta - (DestRect->right - DestRect->left);
1161
1162 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
1163 {
1164 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
1165 (Y * DestSurf->lDelta));
1166 SourceX = SourcePoint->x;
1167 for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++)
1168 {
1169 Dest = *DestBits;
1170
1171 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1172 if(Source != iTransColor)
1173 {
1174 Dest &= 0xFFFFFF00;
1175 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
1176 }
1177
1178 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1179 if(Source != iTransColor)
1180 {
1181 Dest &= 0xFFFF00FF;
1182 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
1183 }
1184
1185 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1186 if(Source != iTransColor)
1187 {
1188 Dest &= 0xFF00FFFF;
1189 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
1190 }
1191
1192 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1193 if(Source != iTransColor)
1194 {
1195 Dest &= 0x00FFFFFF;
1196 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
1197 }
1198
1199 *DestBits = Dest;
1200 }
1201
1202 if(X < DestRect->right)
1203 {
1204 for (; X < DestRect->right; X++)
1205 {
1206 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1207 if(Source != iTransColor)
1208 {
1209 *((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
1210 }
1211 DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
1212 }
1213 }
1214 SourceY++;
1215 }
1216
1217 return TRUE;
1218 }
1219
1220 typedef union {
1221 ULONG ul;
1222 struct {
1223 UCHAR red;
1224 UCHAR green;
1225 UCHAR blue;
1226 UCHAR alpha;
1227 } col;
1228 } NICEPIXEL32;
1229
1230 typedef union {
1231 USHORT us;
1232 struct {
1233 USHORT red:5,
1234 green:6,
1235 blue:5;
1236 } col;
1237 } NICEPIXEL16;
1238
1239 STATIC inline UCHAR
1240 Clamp8(ULONG val)
1241 {
1242 return (val > 255) ? 255 : val;
1243 }
1244
1245 BOOLEAN
1246 DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
1247 RECTL* SourceRect, CLIPOBJ* ClipRegion,
1248 XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
1249 {
1250 INT Rows, Cols, SrcX, SrcY;
1251 register PUCHAR Dst;
1252 ULONG DstDelta;
1253 BLENDFUNCTION BlendFunc;
1254 register NICEPIXEL32 DstPixel;
1255 register NICEPIXEL32 SrcPixel;
1256 register NICEPIXEL16 SrcPixel16;
1257 UCHAR Alpha, SrcBpp;
1258 HPALETTE SrcPalette, DstPalette;
1259 XLATEOBJ *SrcTo32Xlate, *DstTo32Xlate, *DstFrom32Xlate;
1260
1261 DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
1262 SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
1263 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
1264
1265 ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
1266 DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
1267
1268 BlendFunc = BlendObj->BlendFunction;
1269 if (BlendFunc.BlendOp != AC_SRC_OVER)
1270 {
1271 DPRINT1("BlendOp != AC_SRC_OVER\n");
1272 return FALSE;
1273 }
1274 if (BlendFunc.BlendFlags != 0)
1275 {
1276 DPRINT1("BlendFlags != 0\n");
1277 return FALSE;
1278 }
1279 if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
1280 {
1281 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
1282 return FALSE;
1283 }
1284 if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
1285 BitsPerFormat(Source->iBitmapFormat) != 32)
1286 {
1287 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
1288 return FALSE;
1289 }
1290
1291 SrcBpp = BitsPerFormat(Source->iBitmapFormat);
1292 SrcPalette = IntEngGetXlatePalette(ColorTranslation, XO_SRCPALETTE);
1293 if (SrcPalette != 0)
1294 {
1295 SrcTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, SrcPalette);
1296 if (SrcTo32Xlate == NULL)
1297 {
1298 DPRINT1("IntEngCreateXlate failed\n");
1299 return FALSE;
1300 }
1301 }
1302 else
1303 {
1304 SrcTo32Xlate = NULL;
1305 ASSERT(SrcBpp >= 16);
1306 }
1307
1308 DstPalette = IntEngGetXlatePalette(ColorTranslation, XO_DESTPALETTE);
1309 DstTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, DstPalette);
1310 DstFrom32Xlate = IntEngCreateXlate(0, PAL_RGB, DstPalette, NULL);
1311 if (DstTo32Xlate == NULL || DstFrom32Xlate == NULL)
1312 {
1313 if (SrcTo32Xlate != NULL)
1314 EngDeleteXlate(SrcTo32Xlate);
1315 if (DstTo32Xlate != NULL)
1316 EngDeleteXlate(DstTo32Xlate);
1317 if (DstFrom32Xlate != NULL)
1318 EngDeleteXlate(DstFrom32Xlate);
1319 DPRINT1("IntEngCreateXlate failed\n");
1320 return FALSE;
1321 }
1322
1323 Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
1324 DestRect->left);
1325 DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
1326
1327 Rows = DestRect->bottom - DestRect->top;
1328 SrcY = SourceRect->top;
1329 while (--Rows >= 0)
1330 {
1331 Cols = DestRect->right - DestRect->left;
1332 SrcX = SourceRect->left;
1333 while (--Cols >= 0)
1334 {
1335 if (SrcTo32Xlate != NULL)
1336 {
1337 SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, SrcTo32Xlate);
1338 }
1339 else if (SrcBpp <= 16)
1340 {
1341 SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
1342 SrcPixel.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
1343 SrcPixel.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
1344 SrcPixel.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
1345 }
1346 else
1347 {
1348 SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
1349 }
1350 SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
1351 SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
1352 SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
1353 SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
1354
1355 Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
1356 SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
1357
1358 DstPixel.ul = XLATEOBJ_iXlate(DstTo32Xlate, *Dst);
1359 DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
1360 DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
1361 DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
1362 *Dst++ = XLATEOBJ_iXlate(DstFrom32Xlate, DstPixel.ul);
1363 }
1364 Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
1365 SrcY++;
1366 }
1367
1368 if (SrcTo32Xlate != NULL)
1369 EngDeleteXlate(SrcTo32Xlate);
1370 if (DstTo32Xlate != NULL)
1371 EngDeleteXlate(DstTo32Xlate);
1372 if (DstFrom32Xlate != NULL)
1373 EngDeleteXlate(DstFrom32Xlate);
1374
1375 return TRUE;
1376 }
1377
1378 /* EOF */