fix head so it compile agein
[reactos.git] / reactos / subsys / win32k / dib / dib32bpp.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 #include <w32k.h>
21
22
23
24
25 VOID
26 DIB_32BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
27 {
28 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
29 PDWORD addr = (PDWORD)byteaddr + x;
30
31 *addr = c;
32 }
33
34 ULONG
35 DIB_32BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
36 {
37 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
38 PDWORD addr = (PDWORD)byteaddr + x;
39
40 return (ULONG)(*addr);
41 }
42
43
44 #ifdef _M_IX86
45 VOID
46 DIB_32BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
47 {
48 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
49 PDWORD addr = (PDWORD)byteaddr + x1;
50 LONG cx = x2 - x1;
51 if (cx>0) memset4(addr, c, cx);
52 }
53 #else
54 VOID
55 DIB_32BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
56 {
57 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
58 PDWORD addr = (PDWORD)byteaddr + x1;
59 LONG cx = x1;
60
61 while(cx < x2) {
62 *addr = (DWORD)c;
63 ++addr;
64 ++cx;
65 }
66 }
67 #endif
68
69 VOID
70 DIB_32BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
71 {
72 PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta;
73 PDWORD addr = (PDWORD)byteaddr + x;
74 LONG lDelta = SurfObj->lDelta >> 2; /* >> 2 == / sizeof(DWORD) */
75
76 byteaddr = (PBYTE)addr;
77 while(y1++ < y2) {
78 *addr = (DWORD)c;
79
80 addr += lDelta;
81 }
82 }
83
84 BOOLEAN
85 DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
86 {
87 LONG i, j, sx, sy, xColor, f1;
88 PBYTE SourceBits, DestBits, SourceLine, DestLine;
89 PBYTE SourceBits_4BPP, SourceLine_4BPP;
90 PDWORD Source32, Dest32;
91
92 DestBits = BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
93
94 switch(BltInfo->SourceSurface->iBitmapFormat)
95 {
96 case BMF_1BPP:
97
98 sx = BltInfo->SourcePoint.x;
99 sy = BltInfo->SourcePoint.y;
100
101 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
102 {
103 sx = BltInfo->SourcePoint.x;
104 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
105 {
106 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
107 {
108 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
109 } else {
110 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
111 }
112 sx++;
113 }
114 sy++;
115 }
116 break;
117
118 case BMF_4BPP:
119 SourceBits_4BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
120
121 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
122 {
123 SourceLine_4BPP = SourceBits_4BPP;
124 sx = BltInfo->SourcePoint.x;
125 f1 = sx & 1;
126
127 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
128 {
129 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
130 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
131 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
132 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
133 sx++;
134 }
135
136 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
137 }
138 break;
139
140 case BMF_8BPP:
141 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
142 DestLine = DestBits;
143
144 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
145 {
146 SourceBits = SourceLine;
147 DestBits = DestLine;
148
149 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
150 {
151 xColor = *SourceBits;
152 *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
153 SourceBits += 1;
154 DestBits += 4;
155 }
156
157 SourceLine += BltInfo->SourceSurface->lDelta;
158 DestLine += BltInfo->DestSurface->lDelta;
159 }
160 break;
161
162 case BMF_16BPP:
163 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
164 DestLine = DestBits;
165
166 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
167 {
168 SourceBits = SourceLine;
169 DestBits = DestLine;
170
171 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
172 {
173 xColor = *((PWORD) SourceBits);
174 *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
175 SourceBits += 2;
176 DestBits += 4;
177 }
178
179 SourceLine += BltInfo->SourceSurface->lDelta;
180 DestLine += BltInfo->DestSurface->lDelta;
181 }
182 break;
183
184 case BMF_24BPP:
185 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
186 DestLine = DestBits;
187
188 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
189 {
190 SourceBits = SourceLine;
191 DestBits = DestLine;
192
193 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
194 {
195 xColor = (*(SourceBits + 2) << 0x10) +
196 (*(SourceBits + 1) << 0x08) +
197 (*(SourceBits));
198 *((PDWORD)DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
199 SourceBits += 3;
200 DestBits += 4;
201 }
202
203 SourceLine += BltInfo->SourceSurface->lDelta;
204 DestLine += BltInfo->DestSurface->lDelta;
205 }
206 break;
207
208 case BMF_32BPP:
209 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
210 {
211 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
212 {
213 SourceBits = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
214 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
215 {
216 RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
217 SourceBits += BltInfo->SourceSurface->lDelta;
218 DestBits += BltInfo->DestSurface->lDelta;
219 }
220 }
221 else
222 {
223 SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
224 DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
225 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
226 {
227 RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
228 SourceBits -= BltInfo->SourceSurface->lDelta;
229 DestBits -= BltInfo->DestSurface->lDelta;
230 }
231 }
232 }
233 else
234 {
235 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
236 {
237 SourceBits = (BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x);
238 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
239 {
240 if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
241 {
242 Dest32 = (DWORD *) DestBits;
243 Source32 = (DWORD *) SourceBits;
244 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
245 {
246 *Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
247 }
248 }
249 else
250 {
251 Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
252 Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
253 for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
254 {
255 *Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
256 }
257 }
258 SourceBits += BltInfo->SourceSurface->lDelta;
259 DestBits += BltInfo->DestSurface->lDelta;
260 }
261 }
262 else
263 {
264 SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
265 DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
266 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
267 {
268 if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
269 {
270 Dest32 = (DWORD *) DestBits;
271 Source32 = (DWORD *) SourceBits;
272 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
273 {
274 *Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
275 }
276 }
277 else
278 {
279 Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
280 Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
281 for (i = BltInfo->DestRect.right; BltInfo->DestRect.left < i; i--)
282 {
283 *Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
284 }
285 }
286 SourceBits -= BltInfo->SourceSurface->lDelta;
287 DestBits -= BltInfo->DestSurface->lDelta;
288 }
289 }
290 }
291 break;
292
293 default:
294 DPRINT1("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
295 return FALSE;
296 }
297
298 return TRUE;
299 }
300
301 BOOLEAN
302 DIB_32BPP_BitBlt(PBLTINFO BltInfo)
303 {
304 ULONG DestX, DestY;
305 ULONG SourceX, SourceY;
306 ULONG PatternY = 0;
307 ULONG Dest, Source = 0, Pattern = 0;
308 BOOL UsesSource;
309 BOOL UsesPattern;
310 PULONG DestBits;
311
312 switch (BltInfo->Rop4)
313 {
314
315 case ROP4_BLACKNESS:
316 //return(0x00000000);
317 return DIB32_ColorFill(BltInfo, 0x00000000);
318 break;
319
320 case ROP4_WHITENESS:
321 //return(0xFFFFFFFF);
322 return DIB32_ColorFill(BltInfo, 0xFFFFFFFF);
323 break;
324
325 case ROP4_SRCCOPY:
326 // return(Source);
327 return DIB32_Srccopy(BltInfo);
328 break;
329
330 case ROP4_DSTINVERT:
331 // return(~Dest);
332 return DIB_32DstInvert(BltInfo);
333 break;
334
335 case ROP4_SRCPAINT:
336 // return(Dest | Source);
337 return DIB32_SrcPaint(BltInfo);
338 break;
339
340 default:
341 break;
342 }
343
344 UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
345 UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
346
347 SourceY = BltInfo->SourcePoint.y;
348 DestBits = (PULONG)(
349 BltInfo->DestSurface->pvScan0 +
350 (BltInfo->DestRect.left << 2) +
351 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
352
353 if (UsesPattern)
354 {
355 if (BltInfo->PatternSurface)
356 {
357 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
358 BltInfo->PatternSurface->sizlBitmap.cy;
359 }
360 else
361 {
362 Pattern = BltInfo->Brush->iSolidColor;
363 }
364 }
365
366 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
367 {
368 SourceX = BltInfo->SourcePoint.x;
369
370 for (DestX = BltInfo->DestRect.left; DestX < BltInfo->DestRect.right; DestX++, DestBits++, SourceX++)
371 {
372 Dest = *DestBits;
373
374 if (UsesSource)
375 {
376 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
377 }
378
379 if (BltInfo->PatternSurface)
380 {
381 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
382 }
383
384 *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
385 }
386
387 SourceY++;
388 if (BltInfo->PatternSurface)
389 {
390 PatternY++;
391 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
392 }
393 DestBits = (PULONG)(
394 (ULONG_PTR)DestBits -
395 ((BltInfo->DestRect.right - BltInfo->DestRect.left) << 2) +
396 BltInfo->DestSurface->lDelta);
397 }
398
399 return TRUE;
400 }
401
402 /* optimze functions for bitblt */
403 BOOLEAN
404 FASTCALL
405 DIB_32DstInvert(PBLTINFO BltInfo)
406 {
407 PULONG DestBits;
408 ULONG top = BltInfo->DestRect.top;
409 ULONG left = BltInfo->DestRect.left;
410 ULONG DestX = BltInfo->DestRect.right - left;
411 ULONG DestY = BltInfo->DestRect.bottom - top;
412 ULONG delta = BltInfo->DestSurface->lDelta - (DestX << 2);
413
414 /* Calculate the Initial Destination */
415 DestBits = (PULONG)(BltInfo->DestSurface->pvScan0 + (left << 2) +
416 top * BltInfo->DestSurface->lDelta);
417
418 while (DestY > 0)
419 {
420 while (DestX > 0)
421 {
422 /* Invert bits */
423 *DestBits =~ *DestBits;
424
425 /* Update Position */
426 DestBits++;
427
428 /* Decrease distance to do */
429 DestX--;
430 }
431
432 /* Update position */
433 DestBits = (PULONG)((ULONG_PTR)DestBits + delta);
434
435 /* Decrease distance to do */
436 DestY--;
437 }
438
439 /* Return TRUE */
440 return TRUE;
441 }
442
443 BOOLEAN
444 DIB32_SrcPaint(PBLTINFO BltInfo)
445 {
446 BOOLEAN status = FALSE;
447
448 // return(Source);
449 switch (BltInfo->SourceSurface->iBitmapFormat)
450 {
451 case BMF_1BPP:
452 case BMF_4BPP:
453 case BMF_16BPP:
454 case BMF_24BPP:
455 {
456 ULONG DestX, DestY;
457 ULONG SourceX, SourceY;
458 PULONG DestBits;
459
460 ULONG bottom = BltInfo->DestRect.bottom;
461 ULONG right = BltInfo->DestRect.right;
462 ULONG delta = BltInfo->DestSurface->lDelta - ((BltInfo->DestRect.right - BltInfo->DestRect.left) <<2) ;
463
464 DestBits = (PULONG)(BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.left << 2) +
465 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
466
467 SourceY = BltInfo->SourcePoint.y;
468
469 for (DestY = BltInfo->DestRect.top; DestY < bottom; DestY++)
470 {
471 SourceX = BltInfo->SourcePoint.x;
472 for (DestX = BltInfo->DestRect.left; DestX < right; DestX++, DestBits++, SourceX++)
473 {
474
475 *DestBits = (*DestBits | DIB_GetSource(BltInfo->SourceSurface, SourceX,
476 SourceY, BltInfo->XlateSourceToDest));
477 }
478
479 DestBits = (PULONG)((ULONG_PTR)DestBits + delta);
480 SourceY++;
481 }
482
483 }
484 status = TRUE;
485 break;
486
487 case BMF_32BPP:
488 {
489 ULONG DestX, DestY;
490 ULONG SourceX, SourceY;
491 PULONG DestBits;
492
493 ULONG bottom = BltInfo->DestRect.bottom;
494 ULONG right = BltInfo->DestRect.right;
495 ULONG delta = BltInfo->DestSurface->lDelta - ((BltInfo->DestRect.right - BltInfo->DestRect.left) <<2) ;
496
497 DestBits = (PULONG)(BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.left << 2) +
498 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
499
500 SourceY = BltInfo->SourcePoint.y;
501
502 for (DestY = BltInfo->DestRect.top; DestY < bottom; DestY++)
503 {
504
505 SourceX = BltInfo->SourcePoint.x;
506 for (DestX = BltInfo->DestRect.left; DestX < right; DestX++, DestBits++, SourceX++)
507 {
508 *DestBits = (*DestBits | DIB_32BPP_GetPixel(BltInfo->SourceSurface, SourceX, SourceY));
509 }
510
511 DestBits = (PULONG)((ULONG_PTR)DestBits + delta);
512 SourceY++;
513 }
514
515 }
516 status = TRUE;
517 break;
518
519 default:
520 break;
521 }
522
523 return status;
524 }
525 BOOLEAN
526 DIB32_Srccopy(PBLTINFO BltInfo)
527 {
528 BOOLEAN status = FALSE;
529
530 // return(Source);
531 switch (BltInfo->SourceSurface->iBitmapFormat)
532 {
533 case BMF_1BPP:
534 case BMF_4BPP:
535 case BMF_16BPP:
536 case BMF_24BPP:
537 {
538 ULONG DestX, DestY;
539 ULONG SourceX, SourceY;
540 PULONG DestBits;
541
542 ULONG bottom = BltInfo->DestRect.bottom;
543 ULONG right = BltInfo->DestRect.right;
544 ULONG delta = ((BltInfo->DestRect.right - BltInfo->DestRect.left) <<2) + BltInfo->DestSurface->lDelta;
545
546 DestBits = (PULONG)(BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.left << 2) +
547 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
548
549 SourceY = BltInfo->SourcePoint.y;
550
551 for (DestY = BltInfo->DestRect.top; DestY < bottom; DestY++)
552 {
553
554 SourceX = BltInfo->SourcePoint.x;
555 for (DestX = BltInfo->DestRect.left; DestX < right; DestX++, DestBits++, SourceX++)
556 {
557 if (SourceX > BltInfo->SourceSurface->sizlBitmap.cx) break;
558
559 *DestBits = DIB_GetSource(BltInfo->SourceSurface, SourceX,
560 SourceY, BltInfo->XlateSourceToDest);
561 }
562
563 DestBits = (PULONG)((ULONG_PTR)DestBits - delta);
564 SourceY++;
565 }
566
567 }
568 status = TRUE;
569 break;
570
571 case BMF_32BPP:
572 {
573 INT Destdelta;
574 INT Sourcedelta;
575 register PBYTE Destaddr;
576 register PBYTE Srcaddr;
577 LONG DesmaxX, DesmaxY;
578 LONG SrcmaxX, SrcmaxY;
579
580 SrcmaxX = BltInfo->SourceSurface->sizlBitmap.cx - BltInfo->SourcePoint.x;
581 SrcmaxY = BltInfo->SourceSurface->sizlBitmap.cy - BltInfo->SourcePoint.y;
582
583 DesmaxX = BltInfo->DestRect.right - BltInfo->DestRect.left;
584 DesmaxY = BltInfo->DestRect.bottom - BltInfo->DestRect.top;
585
586 if (DesmaxX > SrcmaxX ) DesmaxX = SrcmaxX;
587 if (DesmaxY > SrcmaxY ) DesmaxY = SrcmaxY;
588
589 Destdelta = BltInfo->DestSurface->lDelta;
590 Sourcedelta = BltInfo->SourceSurface->lDelta;
591 Destaddr = BltInfo->DestSurface->pvScan0 + BltInfo->DestRect.top * Destdelta + BltInfo->DestRect.left;
592 Srcaddr = BltInfo->SourceSurface->pvScan0 + BltInfo->SourcePoint.y * Sourcedelta + BltInfo->SourcePoint.x;
593
594 DesmaxX *= 4;
595 if (DesmaxY > 0)
596 {
597 do
598 {
599 RtlCopyMemory(Destaddr, Srcaddr, DesmaxX);
600 Destaddr += Destdelta;
601 Srcaddr += Sourcedelta;
602 }
603 while (--DesmaxY);
604 }
605 status = TRUE;
606 break;
607 }
608 default:
609 break;
610 }
611
612 return status;
613 }
614
615 BOOLEAN
616 DIB32_ColorFill(PBLTINFO BltInfo, ULONG color)
617 {
618 ULONG DestY;
619
620 #ifdef _M_IX86
621 ULONG SourceX;
622
623 if (BltInfo->DestRect.left!=0)
624 {
625 SourceX = (BltInfo->DestRect.right - BltInfo->DestRect.left) -1;
626 for (DestY=BltInfo->DestRect.bottom-1;DestY>=BltInfo->DestRect.top;DestY--)
627 {
628 memset4( (PDWORD) (BltInfo->DestSurface->pvScan0 + DestY *
629 BltInfo->DestSurface->lDelta +
630 BltInfo->DestRect.left), color, SourceX);
631 }
632
633 } else {
634 SourceX = ((BltInfo->DestRect.bottom - BltInfo->DestRect.top) * BltInfo->DestRect.right) -1;
635
636 memset4(BltInfo->DestSurface->pvScan0 + BltInfo->DestRect.top *
637 BltInfo->DestSurface->lDelta, color, SourceX);
638
639 }
640 #else
641 ULONG SourceY;
642
643 for (DestY=BltInfo->DestRect.bottom-1;DestY>=BltInfo->DestRect.top;DestY--)
644 {
645 DIB_32BPP_HLine(BltInfo->DestSurface, BltInfo->DestRect.left, BltInfo->DestRect.right, DestY, color);
646 }
647 #endif
648
649 return TRUE;
650 }
651 /*
652 =======================================
653 Stretching functions goes below
654 Some parts of code are based on an
655 article "Bresenhame image scaling"
656 Dr. Dobb Journal, May 2002
657 =======================================
658 */
659
660 typedef unsigned long PIXEL;
661
662 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
663
664 /* 32-bit Color (___ format) */
665 inline PIXEL average32(PIXEL a, PIXEL b)
666 {
667 return a; // FIXME: Temp hack to remove "PCB-effect" from the image
668 }
669
670 void ScaleLineAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
671 {
672 int NumPixels = TgtWidth;
673 int IntPart = SrcWidth / TgtWidth;
674 int FractPart = SrcWidth % TgtWidth;
675 int Mid = TgtWidth >> 1;
676 int E = 0;
677 int skip;
678 PIXEL p;
679
680 skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
681 NumPixels -= skip;
682
683 while (NumPixels-- > 0) {
684 p = *Source;
685 if (E >= Mid)
686 p = average32(p, *(Source+1));
687 *Target++ = p;
688 Source += IntPart;
689 E += FractPart;
690 if (E >= TgtWidth) {
691 E -= TgtWidth;
692 Source++;
693 } /* if */
694 } /* while */
695 while (skip-- > 0)
696 *Target++ = *Source;
697 }
698
699 static BOOLEAN
700 FinalCopy32(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
701 UINT DestY, RECTL *DestRect)
702 {
703 LONG Left, Right;
704
705 while (ClipSpans[*SpanIndex].Y < DestY
706 || (ClipSpans[*SpanIndex].Y == DestY
707 && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
708 {
709 (*SpanIndex)++;
710 if (ClipSpansCount <= *SpanIndex)
711 {
712 /* No more spans, everything else is clipped away, we're done */
713 return FALSE;
714 }
715 }
716 while (ClipSpans[*SpanIndex].Y == DestY)
717 {
718 if (ClipSpans[*SpanIndex].X < DestRect->right)
719 {
720 Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
721 Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
722 memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
723 (Right - Left) * sizeof(PIXEL));
724 }
725 (*SpanIndex)++;
726 if (ClipSpansCount <= *SpanIndex)
727 {
728 /* No more spans, everything else is clipped away, we're done */
729 return FALSE;
730 }
731 }
732
733 return TRUE;
734 }
735
736 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
737 BOOLEAN ScaleRectAvg32(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
738 RECTL* DestRect, RECTL *SourceRect,
739 POINTL* MaskOrigin, POINTL BrushOrigin,
740 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
741 ULONG Mode)
742 {
743 int NumPixels = DestRect->bottom - DestRect->top;
744 int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceSurf->lDelta) / 4;
745 int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
746 int Mid = (DestRect->bottom - DestRect->top) >> 1;
747 int E = 0;
748 int skip;
749 PIXEL *ScanLine, *ScanLineAhead;
750 PIXEL *PrevSource = NULL;
751 PIXEL *PrevSourceAhead = NULL;
752 PIXEL *Target = (PIXEL *) (DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left);
753 PIXEL *Source = (PIXEL *) (SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 4 * SourceRect->left);
754 PSPAN ClipSpans;
755 UINT ClipSpansCount;
756 UINT SpanIndex;
757 LONG DestY;
758
759 if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
760 {
761 return FALSE;
762 }
763 if (0 == ClipSpansCount)
764 {
765 /* No clip spans == empty clipping region, everything clipped away */
766 ASSERT(NULL == ClipSpans);
767 return TRUE;
768 }
769 skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
770 NumPixels -= skip;
771
772 ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
773 ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
774
775 DestY = DestRect->top;
776 SpanIndex = 0;
777 while (NumPixels-- > 0) {
778 if (Source != PrevSource) {
779 if (Source == PrevSourceAhead) {
780 /* the next scan line has already been scaled and stored in
781 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
782 * point to
783 */
784 PIXEL *tmp = ScanLine;
785 ScanLine = ScanLineAhead;
786 ScanLineAhead = tmp;
787 } else {
788 ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
789 } /* if */
790 PrevSource = Source;
791 } /* if */
792
793 if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceSurf->lDelta)) {
794 int x;
795 ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceSurf->lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
796 for (x = 0; x < DestRect->right - DestRect->left; x++)
797 ScanLine[x] = average32(ScanLine[x], ScanLineAhead[x]);
798 PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
799 } /* if */
800
801 if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
802 {
803 /* No more spans, everything else is clipped away, we're done */
804 ExFreePool(ClipSpans);
805 ExFreePool(ScanLine);
806 ExFreePool(ScanLineAhead);
807 return TRUE;
808 }
809 DestY++;
810 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
811 Source += IntPart;
812 E += FractPart;
813 if (E >= DestRect->bottom - DestRect->top) {
814 E -= DestRect->bottom - DestRect->top;
815 Source = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
816 } /* if */
817 } /* while */
818
819 if (skip > 0 && Source != PrevSource)
820 ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
821 while (skip-- > 0) {
822 if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
823 {
824 /* No more spans, everything else is clipped away, we're done */
825 ExFreePool(ClipSpans);
826 ExFreePool(ScanLine);
827 ExFreePool(ScanLineAhead);
828 return TRUE;
829 }
830 DestY++;
831 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
832 } /* while */
833
834 ExFreePool(ClipSpans);
835 ExFreePool(ScanLine);
836 ExFreePool(ScanLineAhead);
837
838 return TRUE;
839 }
840
841
842 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
843 BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
844 RECTL* DestRect, RECTL *SourceRect,
845 POINTL* MaskOrigin, POINTL BrushOrigin,
846 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
847 ULONG Mode)
848 {
849
850 int SrcSizeY;
851 int SrcSizeX;
852 int DesSizeY;
853 int DesSizeX;
854 int sx;
855 int sy;
856 int DesX;
857 int DesY;
858 int color;
859 int zoomX;
860 int zoomY;
861 int count;
862 int saveX;
863 int saveY;
864 BOOLEAN DesIsBiggerY=FALSE;
865
866 DPRINT("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
867 BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
868 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
869
870 SrcSizeY = SourceRect->bottom;
871 SrcSizeX = SourceRect->right;
872
873 DesSizeY = DestRect->bottom;
874 DesSizeX = DestRect->right;
875
876 zoomX = DesSizeX / SrcSizeX;
877 if (zoomX==0) zoomX=1;
878
879 zoomY = DesSizeY / SrcSizeY;
880 if (zoomY==0) zoomY=1;
881
882 if (DesSizeY>SrcSizeY)
883 DesIsBiggerY = TRUE;
884
885 switch(SourceSurf->iBitmapFormat)
886 {
887 case BMF_1BPP:
888 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
889 /* This is a reference implementation, it hasn't been optimized for speed */
890 if (zoomX>1)
891 {
892 /* Draw one Hline on X - Led to the Des Zoom In*/
893 if (DesSizeX>SrcSizeX)
894 {
895 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
896 {
897 if (DesIsBiggerY)
898 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
899 else
900 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
901
902 if (sy > SourceRect->bottom) break;
903
904 saveY = DesY+zoomY;
905
906 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
907 {
908 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
909
910 if (sx > SourceRect->right) break;
911
912 saveX = DesX + zoomX;
913
914 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
915 for (count=DesY;count<saveY;count++)
916 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 0);
917 else
918 for (count=DesY;count<saveY;count++)
919 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 1);
920
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 saveX = DesX + zoomX;
946
947 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
948 for (count=DesY;count<saveY;count++)
949 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 0);
950 else
951 for (count=DesY;count<saveY;count++)
952 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 1);
953
954 }
955 }
956 }
957 }
958 else
959 {
960
961 if (DesSizeX>SrcSizeX)
962 {
963 /* Draw one pixel on X - Led to the Des Zoom In*/
964 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
965 {
966 if (DesIsBiggerY)
967 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
968 else
969 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
970
971 if (sy > SourceRect->bottom) break;
972
973 saveY = DesY+zoomY;
974
975 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
976 {
977 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
978
979 if (sx > SourceRect->right) break;
980
981 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
982 for (count=DesY;count<saveY;count++)
983 DIB_32BPP_PutPixel(DestSurf, DesX, count, 0);
984 else
985 for (count=DesY;count<saveY;count++)
986 DIB_32BPP_PutPixel(DestSurf, DesX, count, 1);
987
988
989 }
990 }
991 }
992 else
993 {
994 /* Draw one pixel on X - Led to the Des Zoom Out*/
995 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
996 {
997 if (DesIsBiggerY)
998 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
999 else
1000 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1001
1002 if (sy > SourceRect->bottom) break;
1003
1004 saveY = DesY+zoomY;
1005
1006 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1007 {
1008 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1009
1010 if (sx > SourceRect->right) break;
1011
1012 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
1013 for (count=DesY;count<saveY;count++)
1014 DIB_32BPP_PutPixel(DestSurf, DesX, count, 0);
1015 else
1016 for (count=DesY;count<saveY;count++)
1017 DIB_32BPP_PutPixel(DestSurf, DesX, count, 1);
1018
1019 }
1020 }
1021 }
1022 }
1023 break;
1024
1025 case BMF_4BPP:
1026 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1027 /* This is a reference implementation, it hasn't been optimized for speed */
1028 if (zoomX>1)
1029 {
1030 /* Draw one Hline on X - Led to the Des Zoom In*/
1031 if (DesSizeX>SrcSizeX)
1032 {
1033 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1034 {
1035 if (DesIsBiggerY)
1036 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1037 else
1038 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1039
1040 if (sy > SourceRect->bottom) break;
1041
1042 saveY = DesY+zoomY;
1043
1044 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1045 {
1046 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1047
1048 if (sx > SourceRect->right) break;
1049
1050 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
1051
1052 saveX = DesX + zoomX;
1053 for (count=DesY;count<saveY;count++)
1054 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1055 }
1056 }
1057 }
1058 else
1059 {
1060 /* Draw one Hline on X - Led to the Des Zoom Out*/
1061
1062 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1063 {
1064 if (DesIsBiggerY)
1065 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1066 else
1067 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1068
1069 if (sy > SourceRect->bottom) break;
1070
1071 saveY = DesY+zoomY;
1072
1073 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1074 {
1075 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1076
1077 if (sx > SourceRect->right) break;
1078
1079 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
1080
1081 saveX = DesX + zoomX;
1082 for (count=DesY;count<saveY;count++)
1083 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1084 }
1085 }
1086 }
1087 }
1088
1089 else
1090 {
1091
1092 if (DesSizeX>SrcSizeX)
1093 {
1094 /* Draw one pixel on X - Led to the Des Zoom In*/
1095 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1096 {
1097 if (DesIsBiggerY)
1098 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1099 else
1100 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1101
1102 if (sy > SourceRect->bottom) break;
1103
1104 saveY = DesY+zoomY;
1105
1106 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1107 {
1108 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1109
1110 if (sx > SourceRect->right) break;
1111
1112 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
1113
1114 for (count=DesY;count<saveY;count++)
1115 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1116 }
1117 }
1118 }
1119 else
1120 {
1121 /* Draw one pixel on X - Led to the Des Zoom Out*/
1122 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1123 {
1124 if (DesIsBiggerY)
1125 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1126 else
1127 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1128
1129 if (sy > SourceRect->bottom) break;
1130
1131 saveY = DesY+zoomY;
1132
1133 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1134 {
1135 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1136
1137 if (sx > SourceRect->right) break;
1138
1139 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
1140
1141 for (count=DesY;count<saveY;count++)
1142 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1143 }
1144 }
1145 }
1146 }
1147 break;
1148
1149 case BMF_8BPP:
1150 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1151 /* This is a reference implementation, it hasn't been optimized for speed */
1152 if (zoomX>1)
1153 {
1154 /* Draw one Hline on X - Led to the Des Zoom In*/
1155 if (DesSizeX>SrcSizeX)
1156 {
1157 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1158 {
1159 if (DesIsBiggerY)
1160 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1161 else
1162 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1163
1164 if (sy > SourceRect->bottom) break;
1165
1166 saveY = DesY+zoomY;
1167
1168 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1169 {
1170 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1171
1172 if (sx > SourceRect->right) break;
1173
1174 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
1175
1176 saveX = DesX + zoomX;
1177 for (count=DesY;count<saveY;count++)
1178 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1179 }
1180 }
1181 }
1182 else
1183 {
1184 /* Draw one Hline on X - Led to the Des Zoom Out*/
1185
1186 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1187 {
1188 if (DesIsBiggerY)
1189 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1190 else
1191 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1192
1193 if (sy > SourceRect->bottom) break;
1194
1195 saveY = DesY+zoomY;
1196
1197 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1198 {
1199 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1200
1201 if (sx > SourceRect->right) break;
1202
1203 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
1204
1205 saveX = DesX + zoomX;
1206 for (count=DesY;count<saveY;count++)
1207 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1208 }
1209 }
1210 }
1211 }
1212
1213 else
1214 {
1215
1216 if (DesSizeX>SrcSizeX)
1217 {
1218 /* Draw one pixel on X - Led to the Des Zoom In*/
1219 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1220 {
1221 if (DesIsBiggerY)
1222 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1223 else
1224 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1225
1226 if (sy > SourceRect->bottom) break;
1227
1228 saveY = DesY+zoomY;
1229
1230 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1231 {
1232 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1233
1234 if (sx > SourceRect->right) break;
1235
1236 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
1237
1238 for (count=DesY;count<saveY;count++)
1239 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1240 }
1241 }
1242 }
1243 else
1244 {
1245 /* Draw one pixel on X - Led to the Des Zoom Out*/
1246 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1247 {
1248 if (DesIsBiggerY)
1249 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1250 else
1251 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1252
1253 if (sy > SourceRect->bottom) break;
1254
1255 saveY = DesY+zoomY;
1256
1257 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1258 {
1259 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1260
1261 if (sx > SourceRect->right) break;
1262
1263 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
1264
1265 for (count=DesY;count<saveY;count++)
1266 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1267 }
1268 }
1269 }
1270 }
1271 break;
1272
1273 case BMF_16BPP:
1274 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1275 /* This is a reference implementation, it hasn't been optimized for speed */
1276 if (zoomX>1)
1277 {
1278 /* Draw one Hline on X - Led to the Des Zoom In*/
1279 if (DesSizeX>SrcSizeX)
1280 {
1281 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1282 {
1283 if (DesIsBiggerY)
1284 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1285 else
1286 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1287
1288 if (sy > SourceRect->bottom) break;
1289
1290 saveY = DesY+zoomY;
1291
1292 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1293 {
1294 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1295
1296 if (sx > SourceRect->right) break;
1297
1298 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1299
1300 saveX = DesX + zoomX;
1301 for (count=DesY;count<saveY;count++)
1302 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1303 }
1304 }
1305 }
1306 else
1307 {
1308 /* Draw one Hline on X - Led to the Des Zoom Out*/
1309
1310 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1311 {
1312 if (DesIsBiggerY)
1313 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1314 else
1315 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1316
1317 if (sy > SourceRect->bottom) break;
1318
1319 saveY = DesY+zoomY;
1320
1321 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1322 {
1323 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1324
1325 if (sx > SourceRect->right) break;
1326
1327 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1328
1329 saveX = DesX + zoomX;
1330 for (count=DesY;count<saveY;count++)
1331 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1332 }
1333 }
1334 }
1335 }
1336
1337 else
1338 {
1339
1340 if (DesSizeX>SrcSizeX)
1341 {
1342 /* Draw one pixel on X - Led to the Des Zoom In*/
1343 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1344 {
1345 if (DesIsBiggerY)
1346 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1347 else
1348 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1349
1350 if (sy > SourceRect->bottom) break;
1351
1352 saveY = DesY+zoomY;
1353
1354 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1355 {
1356 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1357
1358 if (sx > SourceRect->right) break;
1359
1360 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1361
1362 for (count=DesY;count<saveY;count++)
1363 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1364 }
1365 }
1366 }
1367 else
1368 {
1369 /* Draw one pixel on X - Led to the Des Zoom Out*/
1370 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1371 {
1372 if (DesIsBiggerY)
1373 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1374 else
1375 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1376
1377 if (sy > SourceRect->bottom) break;
1378
1379 saveY = DesY+zoomY;
1380
1381 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1382 {
1383 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1384
1385 if (sx > SourceRect->right) break;
1386
1387 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1388
1389 for (count=DesY;count<saveY;count++)
1390 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1391 }
1392 }
1393 }
1394 }
1395 break;
1396
1397 case BMF_24BPP:
1398 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1399 /* This is a reference implementation, it hasn't been optimized for speed */
1400 if (zoomX>1)
1401 {
1402 /* Draw one Hline on X - Led to the Des Zoom In*/
1403 if (DesSizeX>SrcSizeX)
1404 {
1405 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1406 {
1407 if (DesIsBiggerY)
1408 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1409 else
1410 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1411
1412 if (sy > SourceRect->bottom) break;
1413
1414 saveY = DesY+zoomY;
1415
1416 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1417 {
1418 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1419
1420 if (sx > SourceRect->right) break;
1421
1422 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1423
1424 saveX = DesX + zoomX;
1425 for (count=DesY;count<saveY;count++)
1426 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1427 }
1428 }
1429 }
1430 else
1431 {
1432 /* Draw one Hline on X - Led to the Des Zoom Out*/
1433
1434 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1435 {
1436 if (DesIsBiggerY)
1437 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1438 else
1439 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1440
1441 if (sy > SourceRect->bottom) break;
1442
1443 saveY = DesY+zoomY;
1444
1445 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1446 {
1447 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1448
1449 if (sx > SourceRect->right) break;
1450
1451 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1452
1453 saveX = DesX + zoomX;
1454 for (count=DesY;count<saveY;count++)
1455 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1456 }
1457 }
1458 }
1459 }
1460
1461 else
1462 {
1463
1464 if (DesSizeX>SrcSizeX)
1465 {
1466 /* Draw one pixel on X - Led to the Des Zoom In*/
1467 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1468 {
1469 if (DesIsBiggerY)
1470 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1471 else
1472 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1473
1474 if (sy > SourceRect->bottom) break;
1475
1476 saveY = DesY+zoomY;
1477
1478 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1479 {
1480 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1481
1482 if (sx > SourceRect->right) break;
1483
1484 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1485
1486 for (count=DesY;count<saveY;count++)
1487 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1488 }
1489 }
1490 }
1491 else
1492 {
1493 /* Draw one pixel on X - Led to the Des Zoom Out*/
1494 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1495 {
1496 if (DesIsBiggerY)
1497 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1498 else
1499 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1500
1501 if (sy > SourceRect->bottom) break;
1502
1503 saveY = DesY+zoomY;
1504
1505 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1506 {
1507 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1508
1509 if (sx > SourceRect->right) break;
1510
1511 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1512
1513 for (count=DesY;count<saveY;count++)
1514 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1515 }
1516 }
1517 }
1518 }
1519 break;
1520
1521 case BMF_32BPP:
1522 return ScaleRectAvg32(DestSurf, SourceSurf, DestRect, SourceRect, MaskOrigin, BrushOrigin,
1523 ClipRegion, ColorTranslation, Mode);
1524 break;
1525
1526 default:
1527 //DPRINT1("DIB_32BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
1528 return FALSE;
1529 }
1530
1531
1532
1533 return TRUE;
1534 }
1535
1536 BOOLEAN
1537 DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
1538 RECTL* DestRect, POINTL *SourcePoint,
1539 XLATEOBJ *ColorTranslation, ULONG iTransColor)
1540 {
1541 ULONG X, Y, SourceX, SourceY, Source, wd;
1542 ULONG *DestBits;
1543
1544 SourceY = SourcePoint->y;
1545 DestBits = (ULONG*)(DestSurf->pvScan0 +
1546 (DestRect->left << 2) +
1547 DestRect->top * DestSurf->lDelta);
1548 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
1549
1550 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
1551 {
1552 SourceX = SourcePoint->x;
1553 for(X = DestRect->left; X < DestRect->right; X++, DestBits++, SourceX++)
1554 {
1555 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
1556 if(Source != iTransColor)
1557 {
1558 *DestBits = XLATEOBJ_iXlate(ColorTranslation, Source);
1559 }
1560 }
1561
1562 SourceY++;
1563 DestBits = (ULONG*)((ULONG_PTR)DestBits + wd);
1564 }
1565
1566 return TRUE;
1567 }
1568
1569 /* EOF */