:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / eng / paint.c
1 /*
2  * COPYRIGHT:         See COPYING in the top level directory
3  * PROJECT:           ReactOS kernel
4  * PURPOSE:           GDI Driver Paint Functions
5  * FILE:              subsys/win32k/eng/paint.c
6  * PROGRAMER:         Jason Filby
7  * REVISION HISTORY:
8  *                 3/7/1999: Created
9  */
10
11 #include <ddk/winddi.h>
12 #include <include/object.h>
13 #include <include/paint.h>
14 #include <include/surface.h>
15
16 #include "objects.h"
17 #include <include/mouse.h>
18 #include "../dib/dib.h"
19
20 #include "brush.h"
21 #include "clip.h"
22
23 //#define NDEBUG
24 #include <win32k/debug1.h>
25
26 BOOL FillSolid(SURFOBJ *Surface, PRECTL pRect, ULONG iColor)
27 {
28   // These functions are assigned if we're working with a DIB
29   // The assigned functions depend on the bitsPerPixel of the DIB
30   PFN_DIB_PutPixel DIB_PutPixel;
31   PFN_DIB_HLine    DIB_HLine;
32   PFN_DIB_VLine    DIB_VLine;
33   LONG y;
34   ULONG x, LineWidth, leftOfBitmap;
35   SURFGDI *SurfaceGDI;
36
37   SurfaceGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
38   MouseSafetyOnDrawStart(Surface, SurfaceGDI, pRect->left, pRect->top, pRect->right, pRect->bottom);
39 /*
40   if(Surface->iType!=STYPE_BITMAP)
41   {
42     // Call the driver's DrvLineTo
43     ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
44     MouseSafetyOnDrawEnd(Surface, SurfGDI);
45     return ret;
46   }
47 */
48   // Assign DIB functions according to bytes per pixel
49   DPRINT("BPF: %d\n", BitsPerFormat(Surface->iBitmapFormat));
50   switch(BitsPerFormat(Surface->iBitmapFormat))
51   {
52     case 4:
53       DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel;
54       DIB_HLine    = (PFN_DIB_HLine)DIB_4BPP_HLine;
55       DIB_VLine    = (PFN_DIB_VLine)DIB_4BPP_VLine;
56       break;
57
58     case 24:
59       DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel;
60       DIB_HLine    = (PFN_DIB_HLine)DIB_24BPP_HLine;
61       DIB_VLine    = (PFN_DIB_VLine)DIB_24BPP_VLine;
62       break;
63
64     default:
65       DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
66                BitsPerFormat(Surface->iBitmapFormat));
67
68       MouseSafetyOnDrawEnd(Surface, SurfaceGDI);
69       return FALSE;
70   }
71
72   LineWidth  = pRect->right - pRect->left;
73   DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom);
74   for (y = pRect->top; y < pRect->bottom; y++)
75   {
76       //EngLineTo(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
77           DIB_HLine(Surface, pRect->left, pRect->right, y, iColor);
78   }
79   MouseSafetyOnDrawEnd(Surface, SurfaceGDI);
80
81   return TRUE;
82 }
83
84 BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
85                BRUSHINST *BrushInst, POINTL *BrushPoint)
86 {
87   RECT_ENUM RectEnum;
88   BOOL EnumMore;
89
90   DPRINT("ClipRegion->iMode:%d, ClipRegion->iDComplexity: %d\n Color: %d", ClipRegion->iMode, ClipRegion->iDComplexity, iColor);
91   switch(ClipRegion->iMode) {
92
93     case TC_RECTANGLES:
94
95     /* Rectangular clipping can be handled without enumeration.
96        Note that trivial clipping is not possible, since the clipping
97        region defines the area to fill */
98
99     if (ClipRegion->iDComplexity == DC_RECT)
100     {
101       FillSolid(Surface, &(ClipRegion->rclBounds), iColor);
102     } else {
103
104       /* Enumerate all the rectangles and draw them */
105       CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
106
107       do {
108         EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
109         FillSolid(Surface, &RectEnum.arcl[0], iColor);
110       } while (EnumMore);
111     }
112
113     return(TRUE);
114
115     default:
116        return(FALSE);
117   }
118 }
119
120 BOOL STDCALL
121 EngPaint(IN SURFOBJ *Surface,
122          IN CLIPOBJ *ClipRegion,
123          IN BRUSHOBJ *Brush,
124          IN POINTL *BrushOrigin,
125          IN MIX  Mix)
126 {
127   BOOLEAN ret;
128
129   // FIXME: We only support a brush's solid color attribute
130   ret = EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin);
131
132   return ret;
133 }
134
135 BOOL STDCALL
136 IntEngPaint(IN SURFOBJ *Surface,
137          IN CLIPOBJ *ClipRegion,
138          IN BRUSHOBJ *Brush,
139          IN POINTL *BrushOrigin,
140          IN MIX  Mix)
141 {
142   SURFGDI *SurfGDI;
143   BOOL ret;
144
145   // Is the surface's Paint function hooked?
146   SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
147
148   DPRINT("SurfGDI type: %d, sgdi paint: %x\n", Surface->iType, SurfGDI->Paint);
149   if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
150   {
151     // Call the driver's DrvPaint
152     MouseSafetyOnDrawStart(Surface, SurfGDI, ClipRegion->rclBounds.left,
153                                  ClipRegion->rclBounds.top, ClipRegion->rclBounds.right,
154                                                          ClipRegion->rclBounds.bottom);
155
156     ret = SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
157     MouseSafetyOnDrawEnd(Surface, SurfGDI);
158     return ret;
159   }
160   return EngPaint( Surface, ClipRegion, Brush, BrushOrigin, Mix );
161
162 }