Start source tree (final, I hope!) restructuration. Part 1/X
[reactos.git] / reactos / win32ss / core / drivers / displays / vga / objects / paint.c
1 /*
2 * PROJECT: ReactOS VGA display driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/video/displays/vga/objects/paint.c
5 * PURPOSE:
6 * PROGRAMMERS:
7 */
8
9 #include <vgaddi.h>
10
11 #include "brush.h"
12
13 BOOL VGADDIFillSolid(SURFOBJ *Surface, RECTL Dimensions, ULONG iColor)
14 {
15 int x, y, x2, y2, w, h, j;
16 ULONG orgx, pre1, midpre1, tmppre1;
17 //ULONG offset, orgpre1;
18 int ileftpix, imidpix, irightpix;
19 /* double leftpix, midpix, rightpix;*/
20
21 /* Swap dimensions so that x, y are at topmost left */
22 if ( Dimensions.right < Dimensions.left )
23 {
24 x = Dimensions.right;
25 x2 = Dimensions.left;
26 }
27 else
28 {
29 x2 = Dimensions.right;
30 x = Dimensions.left;
31 }
32 if ( Dimensions.bottom < Dimensions.top )
33 {
34 y = Dimensions.bottom;
35 y2 = Dimensions.top;
36 }
37 else
38 {
39 y2 = Dimensions.bottom;
40 y = Dimensions.top;
41 }
42
43 /* Calculate the width and height */
44 w = x2 - x;
45 h = y2 - y;
46
47 DPRINT("VGADDIFillSolid: x:%d, y:%d, w:%d, h:%d\n", x, y, w, h);
48
49 /* Calculate the starting offset */
50 //offset = xconv[x]+y80[y];
51
52 /* Make a note of original x */
53 orgx = x;
54
55 /* Calculate the left mask pixels, middle bytes and right mask pixel */
56 ileftpix = 7 - mod8(x-1);
57 irightpix = mod8(x+w);
58 imidpix = (w-ileftpix-irightpix) / 8;
59
60 pre1 = xconv[(x-1)&~7] + y80[y];
61 //orgpre1=pre1;
62
63 /* check for overlap ( very horizontally skinny rect ) */
64 if ( (ileftpix+irightpix) > w )
65 {
66 int mask = startmasks[ileftpix] & endmasks[irightpix];
67
68 WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask
69 WRITE_PORT_UCHAR((PUCHAR)GRA_D,mask);
70
71 tmppre1 = pre1;
72 for ( j = y; j < y+h; j++ )
73 {
74 READ_REGISTER_UCHAR ( vidmem+tmppre1 );
75 WRITE_REGISTER_UCHAR ( vidmem+tmppre1, iColor );
76 tmppre1 += 80;
77 }
78 return TRUE;
79 }
80
81 if ( ileftpix > 0 )
82 {
83 /* Write left pixels */
84 WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask
85 WRITE_PORT_UCHAR((PUCHAR)GRA_D,startmasks[ileftpix]);
86
87 tmppre1 = pre1;
88 for ( j = y; j < y+h; j++ )
89 {
90 READ_REGISTER_UCHAR(vidmem + tmppre1);
91 WRITE_REGISTER_UCHAR(vidmem + tmppre1, iColor);
92 tmppre1 += 80;
93 }
94
95 /* Prepare new x for the middle */
96 x = orgx + 8;
97 }
98
99 if ( imidpix > 0 )
100 {
101 midpre1=xconv[x] + y80[y];
102
103 /* Set mask to all pixels in byte */
104 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
105
106 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xff);
107
108 for ( j = y; j < y+h; j++ )
109 {
110 memset(vidmem+midpre1, iColor, imidpix); // write middle pixels, no need to read in latch because of the width
111 midpre1 += 80;
112 }
113 }
114
115 x = orgx + w - irightpix;
116 pre1 = xconv[x] + y80[y];
117
118 /* Write right pixels */
119 WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask bits
120 WRITE_PORT_UCHAR((PUCHAR)GRA_D,endmasks[irightpix]);
121
122 for ( j = y; j < y+h; j++ )
123 {
124 READ_REGISTER_UCHAR(vidmem + pre1);
125 WRITE_REGISTER_UCHAR(vidmem + pre1, iColor);
126 pre1 += 80;
127 }
128
129 return TRUE;
130 }
131
132 BOOL VGADDIPaintRgn(
133 IN SURFOBJ *Surface,
134 IN CLIPOBJ *ClipRegion,
135 IN ULONG iColor,
136 IN MIX Mix,
137 IN BRUSHINST *BrushInst,
138 IN POINTL *BrushPoint)
139 {
140 RECT_ENUM RectEnum;
141 BOOL EnumMore;
142
143 DPRINT("VGADDIPaintRgn: iMode: %d, iDComplexity: %d\n Color:%d\n", ClipRegion->iMode, ClipRegion->iDComplexity, iColor);
144 switch(ClipRegion->iMode)
145 {
146 case TC_RECTANGLES:
147
148 /* Rectangular clipping can be handled without enumeration.
149 Note that trivial clipping is not possible, since the clipping
150 region defines the area to fill */
151
152 if (ClipRegion->iDComplexity == DC_RECT)
153 {
154 DPRINT("VGADDIPaintRgn Rect:%d %d %d %d\n", ClipRegion->rclBounds.left, ClipRegion->rclBounds.top, ClipRegion->rclBounds.right, ClipRegion->rclBounds.bottom);
155 VGADDIFillSolid(Surface, ClipRegion->rclBounds, iColor);
156 }
157 else
158 {
159 /* Enumerate all the rectangles and draw them */
160
161 CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
162
163 do
164 {
165 UINT i;
166 EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
167 DPRINT("EnumMore: %d, count: %d\n", EnumMore, RectEnum.c);
168 for( i=0; i<RectEnum.c; i++)
169 {
170 DPRINT("VGADDI enum Rect:%d %d %d %d\n", RectEnum.arcl[i].left, RectEnum.arcl[i].top, RectEnum.arcl[i].right, RectEnum.arcl[i].bottom);
171 VGADDIFillSolid(Surface, RectEnum.arcl[i], iColor);
172 }
173 } while (EnumMore);
174 }
175 return TRUE;
176
177 default:
178 return FALSE;
179 }
180 }
181
182
183 BOOL APIENTRY
184 DrvPaint(
185 IN SURFOBJ *Surface,
186 IN CLIPOBJ *ClipRegion,
187 IN BRUSHOBJ *Brush,
188 IN POINTL *BrushOrigin,
189 IN MIX Mix)
190 {
191 ULONG iSolidColor;
192
193 iSolidColor = Brush->iSolidColor; // FIXME: Realizations and the like
194
195 // If the foreground and background Mixes are the same,
196 // (LATER or if there's no brush mask)
197 // then see if we can use the solid brush accelerators
198
199 // FIXME: Put in the mix switch below
200 // Brush color parameter doesn't matter for these rops
201 return(VGADDIPaintRgn(Surface, ClipRegion, iSolidColor, Mix, NULL, BrushOrigin));
202
203 if ((Mix & 0xFF) == ((Mix >> 8) & 0xFF))
204 {
205 switch (Mix & 0xFF)
206 {
207 case 0:
208 break;
209
210 // FIXME: Implement all these millions of ROPs
211 // For now we don't support brushes -- everything is solid
212
213 case R2_MASKNOTPEN:
214 case R2_NOTCOPYPEN:
215 case R2_XORPEN:
216 case R2_MASKPEN:
217 case R2_NOTXORPEN:
218 case R2_MERGENOTPEN:
219 case R2_COPYPEN:
220 case R2_MERGEPEN:
221 case R2_NOTMERGEPEN:
222 case R2_MASKPENNOT:
223 case R2_NOTMASKPEN:
224 case R2_MERGEPENNOT:
225
226 // Rops that are implicit solid colors
227 case R2_NOT:
228 case R2_WHITE:
229 case R2_BLACK:
230
231
232 // FIXME: The Paint region belongs HERE
233
234 case R2_NOP:
235 return TRUE;
236
237 default:
238 break;
239 }
240 }
241
242 /*
243 doBitBlt:
244
245 // If VGADDIPaint can't do it, VGADDIBitBlt can.. or it might just loop back
246 // here and we have a nice infinite loop
247
248 return( VGADDIBitBlt(Surface, (SURFOBJ *)NULL, (SURFOBJ *)NULL, ClipRegion,
249 (XLATEOBJ *)NULL, &ClipRegion->rclBounds,
250 NULL, (POINTL *)NULL, Brush, BrushOrigin,
251 NULL) ); UNIMPLEMENTED */
252 }