1 /* 2 * PROJECT: ReactOS VGA display driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: win32ss/drivers/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 } 253