branch update for HEAD-2003050101
[reactos.git] / subsys / win32k / eng / transblt.c
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * PURPOSE:          GDI TransparentBlt Function
5  * FILE:             subsys/win32k/eng/transblt.c
6  * PROGRAMER:        Jason Filby
7  * REVISION HISTORY:
8  *        4/6/2001: Created
9  */
10
11 #include <ddk/winddi.h>
12 #include <ddk/ntddk.h>
13 #include <ntos/minmax.h>
14 #include <include/dib.h>
15 #include <include/object.h>
16 #include <include/surface.h>
17
18 #include "brush.h"
19 #include "clip.h"
20 #include "objects.h"
21
22 #include <include/mouse.h>
23
24 BOOL STDCALL
25 EngTransparentBlt(PSURFOBJ Dest,
26                   PSURFOBJ Source,
27                   PCLIPOBJ Clip,
28                   PXLATEOBJ ColorTranslation,
29                   PRECTL DestRect,
30                   PRECTL SourceRect,
31                   ULONG TransparentColor,
32                   ULONG Reserved)
33 {
34   PSURFGDI DestGDI   = (PSURFGDI)AccessInternalObjectFromUserObject(Dest),
35            SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
36   HSURF     hTemp;
37   PSURFOBJ  TempSurf;
38   POINTL    TempPoint, SourcePoint;
39   RECTL     TempRect;
40   SIZEL     TempSize;
41   BOOLEAN   ret;
42   LONG dx, dy, sx, sy;
43
44   dx = abs(DestRect->right  - DestRect->left);
45   dy = abs(DestRect->bottom - DestRect->top);
46
47   sx = abs(SourceRect->right  - SourceRect->left);
48   sy = abs(SourceRect->bottom - SourceRect->top);
49
50   if(sx<dx) dx = sx;
51   if(sy<dy) dy = sy;
52
53   MouseSafetyOnDrawStart(Source, SourceGDI, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
54   MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
55
56   if(DestGDI->TransparentBlt != NULL)
57   {
58     // The destination is device managed, therefore get the source into a format compatible surface
59     TempPoint.x = 0;
60     TempPoint.y = 0;
61     TempRect.top    = 0;
62     TempRect.left   = 0;
63     TempRect.bottom = dy;
64     TempRect.right  = dx;
65     TempSize.cx = TempRect.right;
66     TempSize.cy = TempRect.bottom;
67
68     hTemp = EngCreateBitmap(TempSize,
69                             DIB_GetDIBWidthBytes(dx, BitsPerFormat(Dest->iBitmapFormat)),
70                             Dest->iBitmapFormat, 0, NULL);
71     TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp);
72
73     SourcePoint.x = SourceRect->left;
74     SourcePoint.y = SourceRect->top;
75
76     // FIXME: Skip creating a TempSurf if we have the same BPP and palette
77     EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, &SourcePoint, NULL, NULL, NULL, 0);
78
79     ret = DestGDI->TransparentBlt(Dest, TempSurf, Clip, NULL, DestRect, SourceRect,
80                                   TransparentColor, Reserved);
81
82     MouseSafetyOnDrawEnd(Source, SourceGDI);
83     MouseSafetyOnDrawEnd(Dest, DestGDI);
84
85     if(EngDeleteSurface(hTemp) == FALSE)
86     {
87       DbgPrint("Win32k: Failed to delete surface: %d\n", hTemp);        
88       return FALSE;
89     }
90
91     return ret;
92   }
93
94   // Simulate a transparent blt
95
96   MouseSafetyOnDrawEnd(Source, SourceGDI);
97   MouseSafetyOnDrawEnd(Dest, DestGDI);
98
99   return TRUE;
100 }