56b6b250662f92f76ac7ec38adf03b79d4abf0fa
[reactos.git] / reactos / subsys / win32k / dib / dib24bpp.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 VOID
23 DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
24 {
25 PBYTE addr = SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
26 *(PUSHORT)(addr) = c & 0xFFFF;
27 *(addr + 2) = (c >> 16) & 0xFF;
28 }
29
30 ULONG
31 DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
32 {
33 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
34 return *(PUSHORT)(addr) + (*(addr + 2) << 16);
35 }
36
37 VOID
38 DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
39 {
40 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
41 LONG cx = x1;
42
43 c &= 0xFFFFFF;
44 while(cx < x2) {
45 *(PUSHORT)(addr) = c & 0xFFFF;
46 addr += 2;
47 *(addr) = c >> 16;
48 addr += 1;
49 ++cx;
50 }
51 }
52
53 VOID
54 DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
55 {
56 PBYTE addr = SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
57 LONG lDelta = SurfObj->lDelta;
58
59 c &= 0xFFFFFF;
60 while(y1++ < y2) {
61 *(PUSHORT)(addr) = c & 0xFFFF;
62 *(addr + 2) = c >> 16;
63
64 addr += lDelta;
65 }
66 }
67
68 BOOLEAN
69 DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
70 {
71 LONG i, j, sx, sy, xColor, f1;
72 PBYTE SourceBits, DestBits, SourceLine, DestLine;
73 PBYTE SourceBits_4BPP, SourceLine_4BPP;
74 PWORD SourceBits_16BPP, SourceLine_16BPP;
75
76 DestBits = BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
77
78 switch(BltInfo->SourceSurface->iBitmapFormat)
79 {
80 case BMF_1BPP:
81 sx = BltInfo->SourcePoint.x;
82 sy = BltInfo->SourcePoint.y;
83
84 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
85 {
86 sx = BltInfo->SourcePoint.x;
87 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
88 {
89 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
90 {
91 DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
92 } else {
93 DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
94 }
95 sx++;
96 }
97 sy++;
98 }
99 break;
100
101 case BMF_4BPP:
102 SourceBits_4BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
103
104 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
105 {
106 SourceLine_4BPP = SourceBits_4BPP;
107 DestLine = DestBits;
108 sx = BltInfo->SourcePoint.x;
109 f1 = sx & 1;
110
111 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
112 {
113 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
114 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
115 *DestLine++ = xColor & 0xff;
116 *(PWORD)DestLine = xColor >> 8;
117 DestLine += 2;
118 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
119 sx++;
120 }
121
122 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
123 DestBits += BltInfo->DestSurface->lDelta;
124 }
125 break;
126
127 case BMF_8BPP:
128 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
129 DestLine = DestBits;
130
131 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
132 {
133 SourceBits = SourceLine;
134 DestBits = DestLine;
135
136 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
137 {
138 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
139 *DestBits = xColor & 0xff;
140 *(PWORD)(DestBits + 1) = xColor >> 8;
141 SourceBits += 1;
142 DestBits += 3;
143 }
144
145 SourceLine += BltInfo->SourceSurface->lDelta;
146 DestLine += BltInfo->DestSurface->lDelta;
147 }
148 break;
149
150 case BMF_16BPP:
151 SourceBits_16BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
152
153 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
154 {
155 SourceLine_16BPP = SourceBits_16BPP;
156 DestLine = DestBits;
157
158 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
159 {
160 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_16BPP);
161 *DestLine++ = xColor & 0xff;
162 *(PWORD)DestLine = xColor >> 8;
163 DestLine += 2;
164 SourceLine_16BPP++;
165 }
166
167 SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
168 DestBits += BltInfo->DestSurface->lDelta;
169 }
170 break;
171
172 case BMF_24BPP:
173 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
174 {
175 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
176 {
177 SourceBits = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
178 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
179 {
180 RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
181 SourceBits += BltInfo->SourceSurface->lDelta;
182 DestBits += BltInfo->DestSurface->lDelta;
183 }
184 }
185 else
186 {
187 SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
188 DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
189 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
190 {
191 RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
192 SourceBits -= BltInfo->SourceSurface->lDelta;
193 DestBits -= BltInfo->DestSurface->lDelta;
194 }
195 }
196 }
197 else
198 {
199 /* FIXME */
200 DPRINT1("DIB_24BPP_Bitblt: Unhandled BltInfo->XlateSourceToDest for 16 -> 16 copy\n");
201 return FALSE;
202 }
203 break;
204
205 case BMF_32BPP:
206 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
207 DestLine = DestBits;
208
209 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
210 {
211 SourceBits = SourceLine;
212 DestBits = DestLine;
213
214 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
215 {
216 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
217 *DestBits = xColor & 0xff;
218 *(PWORD)(DestBits + 1) = xColor >> 8;
219 SourceBits += 4;
220 DestBits += 3;
221 }
222
223 SourceLine += BltInfo->SourceSurface->lDelta;
224 DestLine += BltInfo->DestSurface->lDelta;
225 }
226 break;
227
228 default:
229 DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
230 return FALSE;
231 }
232
233 return TRUE;
234 }
235
236 BOOLEAN
237 DIB_24BPP_BitBlt(PBLTINFO BltInfo)
238 {
239 ULONG DestX, DestY;
240 ULONG SourceX, SourceY;
241 ULONG PatternY = 0;
242 ULONG Dest, Source = 0, Pattern = 0;
243 BOOL UsesSource;
244 BOOL UsesPattern;
245 PBYTE DestBits;
246
247 UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
248 UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
249
250 SourceY = BltInfo->SourcePoint.y;
251 DestBits = (PBYTE)(
252 BltInfo->DestSurface->pvScan0 +
253 (BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
254 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
255
256 if (UsesPattern)
257 {
258 if (BltInfo->PatternSurface)
259 {
260 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
261 BltInfo->PatternSurface->sizlBitmap.cy;
262 }
263 else
264 {
265 Pattern = BltInfo->Brush->iSolidColor;
266 }
267 }
268
269 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
270 {
271 SourceX = BltInfo->SourcePoint.x;
272
273 for (DestX = BltInfo->DestRect.left; DestX < BltInfo->DestRect.right; DestX++, DestBits += 3, SourceX++)
274 {
275 Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
276
277 if (UsesSource)
278 {
279 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
280 }
281
282 if (BltInfo->PatternSurface)
283 {
284 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
285 }
286
287 Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFFFF;
288 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
289 *(DestBits + 2) = Dest >> 16;
290 }
291
292 SourceY++;
293 if (BltInfo->PatternSurface)
294 {
295 PatternY++;
296 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
297 }
298 DestBits -= (BltInfo->DestRect.right - BltInfo->DestRect.left) * 3;
299 DestBits += BltInfo->DestSurface->lDelta;
300 }
301
302 return TRUE;
303 }
304
305 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
306 BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
307 RECTL* DestRect, RECTL *SourceRect,
308 POINTL* MaskOrigin, POINTL BrushOrigin,
309 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
310 ULONG Mode)
311 {
312 int SrcSizeY;
313 int SrcSizeX;
314 int DesSizeY;
315 int DesSizeX;
316 int sx;
317 int sy;
318 int DesX;
319 int DesY;
320 int color;
321 int zoomX;
322 int zoomY;
323 int count;
324 int saveX;
325 int saveY;
326 BOOLEAN DesIsBiggerY=FALSE;
327
328 SrcSizeY = SourceRect->bottom;
329 SrcSizeX = SourceRect->right;
330
331 DesSizeY = DestRect->bottom;
332 DesSizeX = DestRect->right;
333
334 zoomX = DesSizeX / SrcSizeX;
335 if (zoomX==0) zoomX=1;
336
337 zoomY = DesSizeY / SrcSizeY;
338 if (zoomY==0) zoomY=1;
339
340 if (DesSizeY>SrcSizeY)
341 DesIsBiggerY = TRUE;
342
343 switch(SourceSurf->iBitmapFormat)
344 {
345 case BMF_1BPP:
346 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
347 /* This is a reference implementation, it hasn't been optimized for speed */
348 if (zoomX>1)
349 {
350 /* Draw one Hline on X - Led to the Des Zoom In*/
351 if (DesSizeX>SrcSizeX)
352 {
353 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
354 {
355 if (DesIsBiggerY)
356 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
357 else
358 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
359
360 if (sy > SourceRect->bottom) break;
361
362 saveY = DesY+zoomY;
363
364 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
365 {
366 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
367
368 if (sx > SourceRect->right) break;
369
370 saveX = DesX + zoomX;
371
372 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
373 for (count=DesY;count<saveY;count++)
374 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 0);
375 else
376 for (count=DesY;count<saveY;count++)
377 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 1);
378
379 }
380 }
381 }
382 else
383 {
384 /* Draw one Hline on X - Led to the Des Zoom Out*/
385
386 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
387 {
388 if (DesIsBiggerY)
389 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
390 else
391 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
392
393 if (sy > SourceRect->bottom) break;
394
395 saveY = DesY+zoomY;
396
397 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
398 {
399 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
400
401 if (sx > SourceRect->right) break;
402
403 saveX = DesX + zoomX;
404
405 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
406 for (count=DesY;count<saveY;count++)
407 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 0);
408 else
409 for (count=DesY;count<saveY;count++)
410 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 1);
411
412 }
413 }
414 }
415 }
416 else
417 {
418
419 if (DesSizeX>SrcSizeX)
420 {
421 /* Draw one pixel on X - Led to the Des Zoom In*/
422 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
423 {
424 if (DesIsBiggerY)
425 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
426 else
427 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
428
429 if (sy > SourceRect->bottom) break;
430
431 saveY = DesY+zoomY;
432
433 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
434 {
435 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
436
437 if (sx > SourceRect->right) break;
438
439 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
440 for (count=DesY;count<saveY;count++)
441 DIB_24BPP_PutPixel(DestSurf, DesX, count, 0);
442 else
443 for (count=DesY;count<saveY;count++)
444 DIB_24BPP_PutPixel(DestSurf, DesX, count, 1);
445
446
447 }
448 }
449 }
450 else
451 {
452 /* Draw one pixel on X - Led to the Des Zoom Out*/
453 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
454 {
455 if (DesIsBiggerY)
456 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
457 else
458 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
459
460 if (sy > SourceRect->bottom) break;
461
462 saveY = DesY+zoomY;
463
464 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
465 {
466 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
467
468 if (sx > SourceRect->right) break;
469
470 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
471 for (count=DesY;count<saveY;count++)
472 DIB_24BPP_PutPixel(DestSurf, DesX, count, 0);
473 else
474 for (count=DesY;count<saveY;count++)
475 DIB_24BPP_PutPixel(DestSurf, DesX, count, 1);
476
477 }
478 }
479 }
480 }
481 break;
482
483 case BMF_4BPP:
484 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
485 /* This is a reference implementation, it hasn't been optimized for speed */
486 if (zoomX>1)
487 {
488 /* Draw one Hline on X - Led to the Des Zoom In*/
489 if (DesSizeX>SrcSizeX)
490 {
491 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
492 {
493 if (DesIsBiggerY)
494 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
495 else
496 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
497
498 if (sy > SourceRect->bottom) break;
499
500 saveY = DesY+zoomY;
501
502 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
503 {
504 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
505
506 if (sx > SourceRect->right) break;
507
508 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
509
510 saveX = DesX + zoomX;
511 for (count=DesY;count<saveY;count++)
512 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
513 }
514 }
515 }
516 else
517 {
518 /* Draw one Hline on X - Led to the Des Zoom Out*/
519
520 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
521 {
522 if (DesIsBiggerY)
523 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
524 else
525 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
526
527 if (sy > SourceRect->bottom) break;
528
529 saveY = DesY+zoomY;
530
531 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
532 {
533 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
534
535 if (sx > SourceRect->right) break;
536
537 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
538
539 saveX = DesX + zoomX;
540 for (count=DesY;count<saveY;count++)
541 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
542 }
543 }
544 }
545 }
546
547 else
548 {
549
550 if (DesSizeX>SrcSizeX)
551 {
552 /* Draw one pixel on X - Led to the Des Zoom In*/
553 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
554 {
555 if (DesIsBiggerY)
556 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
557 else
558 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
559
560 if (sy > SourceRect->bottom) break;
561
562 saveY = DesY+zoomY;
563
564 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
565 {
566 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
567
568 if (sx > SourceRect->right) break;
569
570 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
571
572 for (count=DesY;count<saveY;count++)
573 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
574 }
575 }
576 }
577 else
578 {
579 /* Draw one pixel on X - Led to the Des Zoom Out*/
580 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
581 {
582 if (DesIsBiggerY)
583 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
584 else
585 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
586
587 if (sy > SourceRect->bottom) break;
588
589 saveY = DesY+zoomY;
590
591 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
592 {
593 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
594
595 if (sx > SourceRect->right) break;
596
597 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
598
599 for (count=DesY;count<saveY;count++)
600 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
601 }
602 }
603 }
604 }
605 break;
606
607 case BMF_8BPP:
608 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
609 /* This is a reference implementation, it hasn't been optimized for speed */
610 if (zoomX>1)
611 {
612 /* Draw one Hline on X - Led to the Des Zoom In*/
613 if (DesSizeX>SrcSizeX)
614 {
615 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
616 {
617 if (DesIsBiggerY)
618 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
619 else
620 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
621
622 if (sy > SourceRect->bottom) break;
623
624 saveY = DesY+zoomY;
625
626 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
627 {
628 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
629
630 if (sx > SourceRect->right) break;
631
632 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
633
634 saveX = DesX + zoomX;
635 for (count=DesY;count<saveY;count++)
636 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
637 }
638 }
639 }
640 else
641 {
642 /* Draw one Hline on X - Led to the Des Zoom Out*/
643
644 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
645 {
646 if (DesIsBiggerY)
647 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
648 else
649 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
650
651 if (sy > SourceRect->bottom) break;
652
653 saveY = DesY+zoomY;
654
655 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
656 {
657 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
658
659 if (sx > SourceRect->right) break;
660
661 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
662
663 saveX = DesX + zoomX;
664 for (count=DesY;count<saveY;count++)
665 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
666 }
667 }
668 }
669 }
670
671 else
672 {
673
674 if (DesSizeX>SrcSizeX)
675 {
676 /* Draw one pixel on X - Led to the Des Zoom In*/
677 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
678 {
679 if (DesIsBiggerY)
680 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
681 else
682 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
683
684 if (sy > SourceRect->bottom) break;
685
686 saveY = DesY+zoomY;
687
688 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
689 {
690 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
691
692 if (sx > SourceRect->right) break;
693
694 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
695
696 for (count=DesY;count<saveY;count++)
697 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
698 }
699 }
700 }
701 else
702 {
703 /* Draw one pixel on X - Led to the Des Zoom Out*/
704 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
705 {
706 if (DesIsBiggerY)
707 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
708 else
709 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
710
711 if (sy > SourceRect->bottom) break;
712
713 saveY = DesY+zoomY;
714
715 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
716 {
717 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
718
719 if (sx > SourceRect->right) break;
720
721 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
722
723 for (count=DesY;count<saveY;count++)
724 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
725 }
726 }
727 }
728 }
729 break;
730
731 case BMF_16BPP:
732 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
733 /* This is a reference implementation, it hasn't been optimized for speed */
734 if (zoomX>1)
735 {
736 /* Draw one Hline on X - Led to the Des Zoom In*/
737 if (DesSizeX>SrcSizeX)
738 {
739 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
740 {
741 if (DesIsBiggerY)
742 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
743 else
744 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
745
746 if (sy > SourceRect->bottom) break;
747
748 saveY = DesY+zoomY;
749
750 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
751 {
752 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
753
754 if (sx > SourceRect->right) break;
755
756 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
757
758 saveX = DesX + zoomX;
759 for (count=DesY;count<saveY;count++)
760 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
761 }
762 }
763 }
764 else
765 {
766 /* Draw one Hline on X - Led to the Des Zoom Out*/
767
768 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
769 {
770 if (DesIsBiggerY)
771 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
772 else
773 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
774
775 if (sy > SourceRect->bottom) break;
776
777 saveY = DesY+zoomY;
778
779 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
780 {
781 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
782
783 if (sx > SourceRect->right) break;
784
785 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
786
787 saveX = DesX + zoomX;
788 for (count=DesY;count<saveY;count++)
789 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
790 }
791 }
792 }
793 }
794
795 else
796 {
797
798 if (DesSizeX>SrcSizeX)
799 {
800 /* Draw one pixel on X - Led to the Des Zoom In*/
801 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
802 {
803 if (DesIsBiggerY)
804 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
805 else
806 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
807
808 if (sy > SourceRect->bottom) break;
809
810 saveY = DesY+zoomY;
811
812 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
813 {
814 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
815
816 if (sx > SourceRect->right) break;
817
818 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
819
820 for (count=DesY;count<saveY;count++)
821 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
822 }
823 }
824 }
825 else
826 {
827 /* Draw one pixel on X - Led to the Des Zoom Out*/
828 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
829 {
830 if (DesIsBiggerY)
831 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
832 else
833 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
834
835 if (sy > SourceRect->bottom) break;
836
837 saveY = DesY+zoomY;
838
839 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
840 {
841 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
842
843 if (sx > SourceRect->right) break;
844
845 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
846
847 for (count=DesY;count<saveY;count++)
848 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
849 }
850 }
851 }
852 }
853 break;
854
855 case BMF_24BPP:
856 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
857 /* This is a reference implementation, it hasn't been optimized for speed */
858 if (zoomX>1)
859 {
860 /* Draw one Hline on X - Led to the Des Zoom In*/
861 if (DesSizeX>SrcSizeX)
862 {
863 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
864 {
865 if (DesIsBiggerY)
866 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
867 else
868 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
869
870 if (sy > SourceRect->bottom) break;
871
872 saveY = DesY+zoomY;
873
874 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
875 {
876 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
877
878 if (sx > SourceRect->right) break;
879
880 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
881
882 saveX = DesX + zoomX;
883 for (count=DesY;count<saveY;count++)
884 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
885 }
886 }
887 }
888 else
889 {
890 /* Draw one Hline on X - Led to the Des Zoom Out*/
891
892 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
893 {
894 if (DesIsBiggerY)
895 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
896 else
897 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
898
899 if (sy > SourceRect->bottom) break;
900
901 saveY = DesY+zoomY;
902
903 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
904 {
905 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
906
907 if (sx > SourceRect->right) break;
908
909 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
910
911 saveX = DesX + zoomX;
912 for (count=DesY;count<saveY;count++)
913 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
914 }
915 }
916 }
917 }
918
919 else
920 {
921
922 if (DesSizeX>SrcSizeX)
923 {
924 /* Draw one pixel on X - Led to the Des Zoom In*/
925 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
926 {
927 if (DesIsBiggerY)
928 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
929 else
930 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
931
932 if (sy > SourceRect->bottom) break;
933
934 saveY = DesY+zoomY;
935
936 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
937 {
938 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
939
940 if (sx > SourceRect->right) break;
941
942 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
943
944 for (count=DesY;count<saveY;count++)
945 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
946 }
947 }
948 }
949 else
950 {
951 /* Draw one pixel on X - Led to the Des Zoom Out*/
952 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
953 {
954 if (DesIsBiggerY)
955 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
956 else
957 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
958
959 if (sy > SourceRect->bottom) break;
960
961 saveY = DesY+zoomY;
962
963 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
964 {
965 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
966
967 if (sx > SourceRect->right) break;
968
969 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
970
971 for (count=DesY;count<saveY;count++)
972 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
973 }
974 }
975 }
976 }
977 break;
978
979 case BMF_32BPP:
980 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
981 /* This is a reference implementation, it hasn't been optimized for speed */
982 if (zoomX>1)
983 {
984 /* Draw one Hline on X - Led to the Des Zoom In*/
985 if (DesSizeX>SrcSizeX)
986 {
987 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
988 {
989 if (DesIsBiggerY)
990 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
991 else
992 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
993
994 if (sy > SourceRect->bottom) break;
995
996 saveY = DesY+zoomY;
997
998 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
999 {
1000 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1001
1002 if (sx > SourceRect->right) break;
1003
1004 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1005
1006 saveX = DesX + zoomX;
1007 for (count=DesY;count<saveY;count++)
1008 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
1009 }
1010 }
1011 }
1012 else
1013 {
1014 /* Draw one Hline on X - Led to the Des Zoom Out*/
1015
1016 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1017 {
1018 if (DesIsBiggerY)
1019 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1020 else
1021 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1022
1023 if (sy > SourceRect->bottom) break;
1024
1025 saveY = DesY+zoomY;
1026
1027 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1028 {
1029 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1030
1031 if (sx > SourceRect->right) break;
1032
1033 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1034
1035 saveX = DesX + zoomX;
1036 for (count=DesY;count<saveY;count++)
1037 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
1038 }
1039 }
1040 }
1041 }
1042
1043 else
1044 {
1045
1046 if (DesSizeX>SrcSizeX)
1047 {
1048 /* Draw one pixel on X - Led to the Des Zoom In*/
1049 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1050 {
1051 if (DesIsBiggerY)
1052 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1053 else
1054 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1055
1056 if (sy > SourceRect->bottom) break;
1057
1058 saveY = DesY+zoomY;
1059
1060 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1061 {
1062 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1063
1064 if (sx > SourceRect->right) break;
1065
1066 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1067
1068 for (count=DesY;count<saveY;count++)
1069 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1070 }
1071 }
1072 }
1073 else
1074 {
1075 /* Draw one pixel on X - Led to the Des Zoom Out*/
1076 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1077 {
1078 if (DesIsBiggerY)
1079 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1080 else
1081 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1082
1083 if (sy > SourceRect->bottom) break;
1084
1085 saveY = DesY+zoomY;
1086
1087 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1088 {
1089 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1090
1091 if (sx > SourceRect->right) break;
1092
1093 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1094
1095 for (count=DesY;count<saveY;count++)
1096 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1097 }
1098 }
1099 }
1100 }
1101 break;
1102
1103 default:
1104 //DPRINT1("DIB_24BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
1105 return FALSE;
1106 }
1107
1108 return TRUE;
1109 }
1110
1111 BOOLEAN
1112 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
1113 RECTL* DestRect, POINTL *SourcePoint,
1114 XLATEOBJ *ColorTranslation, ULONG iTransColor)
1115 {
1116 ULONG X, Y, SourceX, SourceY, Source, wd, Dest;
1117 BYTE *DestBits;
1118
1119 SourceY = SourcePoint->y;
1120 DestBits = (BYTE*)(DestSurf->pvScan0 +
1121 (DestRect->left << 2) +
1122 DestRect->top * DestSurf->lDelta);
1123 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
1124
1125 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
1126 {
1127 SourceX = SourcePoint->x;
1128 for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
1129 {
1130 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
1131 if(Source != iTransColor)
1132 {
1133 Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
1134 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
1135 *(DestBits + 2) = Dest >> 16;
1136 }
1137 }
1138
1139 SourceY++;
1140 DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
1141 }
1142
1143 return TRUE;
1144 }
1145
1146 /* EOF */