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