update for HEAD-2003091401
[reactos.git] / subsys / win32k / eng / paint.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  * 
21  * COPYRIGHT:         See COPYING in the top level directory
22  * PROJECT:           ReactOS kernel
23  * PURPOSE:           GDI Driver Paint Functions
24  * FILE:              subsys/win32k/eng/paint.c
25  * PROGRAMER:         Jason Filby
26  * REVISION HISTORY:
27  *                 3/7/1999: Created
28  */
29
30 #include <ddk/winddi.h>
31 #include <ddk/ntddmou.h>
32 #include <include/object.h>
33 #include <include/paint.h>
34 #include <include/surface.h>
35
36 #include "objects.h"
37 #include <include/mouse.h>
38 #include "../dib/dib.h"
39
40 #include "brush.h"
41 #include "clip.h"
42
43 //#define NDEBUG
44 #include <win32k/debug1.h>
45
46 BOOL STDCALL FillSolid(SURFOBJ *Surface, PRECTL pRect, ULONG iColor)
47 {
48   LONG y;
49   ULONG LineWidth;
50   SURFGDI *SurfaceGDI;
51
52   SurfaceGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
53   MouseSafetyOnDrawStart(Surface, SurfaceGDI, pRect->left, pRect->top, pRect->right, pRect->bottom);
54   LineWidth  = pRect->right - pRect->left;
55   DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom);
56   for (y = pRect->top; y < pRect->bottom; y++)
57   {
58     SurfaceGDI->DIB_HLine(Surface, pRect->left, pRect->right, y, iColor);
59   }
60   MouseSafetyOnDrawEnd(Surface, SurfaceGDI);
61
62   return TRUE;
63 }
64
65 BOOL STDCALL
66 EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
67                BRUSHINST *BrushInst, POINTL *BrushPoint)
68 {
69   RECT_ENUM RectEnum;
70   BOOL EnumMore;
71   ULONG i;
72
73   DPRINT("ClipRegion->iMode:%d, ClipRegion->iDComplexity: %d\n Color: %d", ClipRegion->iMode, ClipRegion->iDComplexity, iColor);
74   switch(ClipRegion->iMode) {
75
76     case TC_RECTANGLES:
77
78     /* Rectangular clipping can be handled without enumeration.
79        Note that trivial clipping is not possible, since the clipping
80        region defines the area to fill */
81
82     if (ClipRegion->iDComplexity == DC_RECT)
83     {
84       FillSolid(Surface, &(ClipRegion->rclBounds), iColor);
85     } else {
86
87       /* Enumerate all the rectangles and draw them */
88       CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
89
90       do {
91         EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
92         for (i = 0; i < RectEnum.c; i++) {
93           FillSolid(Surface, RectEnum.arcl + i, iColor);
94         }
95       } while (EnumMore);
96     }
97
98     return(TRUE);
99
100     default:
101        return(FALSE);
102   }
103 }
104
105 /*
106  * @unimplemented
107  */
108 BOOL STDCALL
109 EngPaint(IN SURFOBJ *Surface,
110          IN CLIPOBJ *ClipRegion,
111          IN BRUSHOBJ *Brush,
112          IN POINTL *BrushOrigin,
113          IN MIX  Mix)
114 {
115   BOOLEAN ret;
116
117   // FIXME: We only support a brush's solid color attribute
118   ret = EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin);
119
120   return ret;
121 }
122
123 BOOL STDCALL
124 IntEngPaint(IN SURFOBJ *Surface,
125          IN CLIPOBJ *ClipRegion,
126          IN BRUSHOBJ *Brush,
127          IN POINTL *BrushOrigin,
128          IN MIX  Mix)
129 {
130   SURFGDI *SurfGDI;
131   BOOL ret;
132
133   // Is the surface's Paint function hooked?
134   SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
135
136   DPRINT("SurfGDI type: %d, sgdi paint: %x\n", Surface->iType, SurfGDI->Paint);
137   if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
138   {
139     // Call the driver's DrvPaint
140     MouseSafetyOnDrawStart(Surface, SurfGDI, ClipRegion->rclBounds.left,
141                                  ClipRegion->rclBounds.top, ClipRegion->rclBounds.right,
142                                                          ClipRegion->rclBounds.bottom);
143
144     ret = SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
145     MouseSafetyOnDrawEnd(Surface, SurfGDI);
146     return ret;
147   }
148   return EngPaint( Surface, ClipRegion, Brush, BrushOrigin, Mix );
149
150 }
151 /* EOF */