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