Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenengbrush.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * PURPOSE: GDI Driver Brush Functions 00005 * FILE: subsystem/win32/win32k/eng/engbrush.c 00006 * PROGRAMER: Jason Filby 00007 * Timo Kreuzer 00008 */ 00009 00010 #include <win32k.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 static const ULONG gaulHatchBrushes[HS_DDI_MAX][8] = 00016 { 00017 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */ 00018 {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */ 00019 {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */ 00020 {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */ 00021 {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */ 00022 {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */ 00023 }; 00024 00025 HSURF gahsurfHatch[HS_DDI_MAX]; 00026 00029 INIT_FUNCTION 00030 NTSTATUS 00031 NTAPI 00032 InitBrushImpl(VOID) 00033 { 00034 ULONG i; 00035 SIZEL sizl = {8, 8}; 00036 00037 /* Loop all hatch styles */ 00038 for (i = 0; i < HS_DDI_MAX; i++) 00039 { 00040 /* Create a default hatch bitmap */ 00041 gahsurfHatch[i] = (HSURF)EngCreateBitmap(sizl, 00042 0, 00043 BMF_1BPP, 00044 0, 00045 (PVOID)gaulHatchBrushes[i]); 00046 } 00047 00048 return STATUS_SUCCESS; 00049 } 00050 00051 VOID 00052 NTAPI 00053 EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) 00054 { 00055 ASSERT(pebo); 00056 ASSERT(pbrush); 00057 ASSERT(pdc); 00058 00059 pebo->BrushObject.flColorType = 0; 00060 pebo->BrushObject.pvRbrush = NULL; 00061 pebo->pbrush = pbrush; 00062 pebo->pengbrush = NULL; 00063 pebo->flattrs = pbrush->flAttrs; 00064 00065 /* Initialize 1 bpp fore and back colors */ 00066 pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr; 00067 pebo->crCurrentText = pdc->pdcattr->crForegroundClr; 00068 00069 pebo->psurfTrg = pdc->dclevel.pSurface; 00070 ASSERT(pebo->psurfTrg); 00071 ASSERT(pebo->psurfTrg->ppal); 00072 00073 pebo->ppalSurf = pebo->psurfTrg->ppal; 00074 GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject); 00075 pebo->ppalDC = pdc->dclevel.ppal; 00076 GDIOBJ_vReferenceObjectByPointer(&pebo->ppalDC->BaseObject); 00077 00078 if (pbrush->flAttrs & BR_IS_NULL) 00079 { 00080 /* NULL brushes don't need a color */ 00081 pebo->BrushObject.iSolidColor = 0; 00082 } 00083 else if (pbrush->flAttrs & BR_IS_SOLID) 00084 { 00085 /* Set the RGB color */ 00086 EBRUSHOBJ_vSetSolidRGBColor(pebo, pbrush->BrushAttr.lbColor); 00087 } 00088 else 00089 { 00090 /* This is a pattern brush that needs realization */ 00091 pebo->BrushObject.iSolidColor = 0xFFFFFFFF; 00092 00093 /* Use foreground color of hatch brushes */ 00094 if (pbrush->flAttrs & BR_IS_HATCH) 00095 pebo->crCurrentText = pbrush->BrushAttr.lbColor; 00096 } 00097 } 00098 00099 VOID 00100 FASTCALL 00101 EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor) 00102 { 00103 ULONG iSolidColor; 00104 EXLATEOBJ exlo; 00105 00106 /* Never use with non-solid brushes */ 00107 ASSERT(pebo->flattrs & BR_IS_SOLID); 00108 00109 /* Set the RGB color */ 00110 pebo->crRealize = crColor; 00111 pebo->ulRGBColor = crColor; 00112 00113 /* Initialize an XLATEOBJ RGB -> surface */ 00114 EXLATEOBJ_vInitialize(&exlo, 00115 &gpalRGB, 00116 pebo->ppalSurf, 00117 pebo->crCurrentBack, 00118 0, 00119 0); 00120 00121 /* Translate the brush color to the target format */ 00122 iSolidColor = XLATEOBJ_iXlate(&exlo.xlo, crColor); 00123 pebo->BrushObject.iSolidColor = iSolidColor; 00124 00125 /* Clean up the XLATEOBJ */ 00126 EXLATEOBJ_vCleanup(&exlo); 00127 } 00128 00129 VOID 00130 NTAPI 00131 EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo) 00132 { 00133 /* Check if there's a GDI realisation */ 00134 if (pebo->pengbrush) 00135 { 00136 /* Unlock the bitmap again */ 00137 SURFACE_ShareUnlockSurface(pebo->pengbrush); 00138 pebo->pengbrush = NULL; 00139 } 00140 00141 /* Check if there's a driver's realisation */ 00142 if (pebo->BrushObject.pvRbrush) 00143 { 00144 /* Free allocated driver memory */ 00145 EngFreeMem(pebo->BrushObject.pvRbrush); 00146 pebo->BrushObject.pvRbrush = NULL; 00147 } 00148 00149 /* Dereference the palettes */ 00150 PALETTE_ShareUnlockPalette(pebo->ppalSurf); 00151 PALETTE_ShareUnlockPalette(pebo->ppalDC); 00152 if (pebo->ppalDIB) PALETTE_ShareUnlockPalette(pebo->ppalDIB); 00153 } 00154 00155 VOID 00156 NTAPI 00157 EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) 00158 { 00159 /* Cleanup the brush */ 00160 EBRUSHOBJ_vCleanup(pebo); 00161 00162 /* Reinitialize */ 00163 EBRUSHOBJ_vInit(pebo, pbrush, pdc); 00164 } 00165 00169 BOOL 00170 APIENTRY 00171 EngRealizeBrush( 00172 BRUSHOBJ *pbo, 00173 SURFOBJ *psoDst, 00174 SURFOBJ *psoPattern, 00175 SURFOBJ *psoMask, 00176 XLATEOBJ *pxlo, 00177 ULONG iHatch) 00178 { 00179 EBRUSHOBJ *pebo; 00180 HBITMAP hbmpRealize; 00181 SURFOBJ *psoRealize; 00182 PSURFACE psurfRealize; 00183 POINTL ptlSrc = {0, 0}; 00184 RECTL rclDest; 00185 ULONG lWidth; 00186 00187 /* Calculate width in bytes of the realized brush */ 00188 lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx, 00189 BitsPerFormat(psoDst->iBitmapFormat)); 00190 00191 /* Allocate a bitmap */ 00192 hbmpRealize = EngCreateBitmap(psoPattern->sizlBitmap, 00193 lWidth, 00194 psoDst->iBitmapFormat, 00195 BMF_NOZEROINIT, 00196 NULL); 00197 if (!hbmpRealize) 00198 { 00199 return FALSE; 00200 } 00201 00202 /* Lock the bitmap */ 00203 psurfRealize = SURFACE_ShareLockSurface(hbmpRealize); 00204 00205 /* Already delete the pattern bitmap (will be kept until dereferenced) */ 00206 EngDeleteSurface((HSURF)hbmpRealize); 00207 00208 if (!psurfRealize) 00209 { 00210 return FALSE; 00211 } 00212 00213 /* Copy the bits to the new format bitmap */ 00214 rclDest.left = rclDest.top = 0; 00215 rclDest.right = psoPattern->sizlBitmap.cx; 00216 rclDest.bottom = psoPattern->sizlBitmap.cy; 00217 psoRealize = &psurfRealize->SurfObj; 00218 EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc); 00219 00220 00221 pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); 00222 pebo->pengbrush = (PVOID)psurfRealize; 00223 00224 return TRUE; 00225 } 00226 00227 static 00228 PPALETTE 00229 FixupDIBBrushPalette( 00230 _In_ PPALETTE ppalDIB, 00231 _In_ PPALETTE ppalDC) 00232 { 00233 PPALETTE ppalNew; 00234 ULONG i, iPalIndex, crColor; 00235 00236 /* Allocate a new palette */ 00237 ppalNew = PALETTE_AllocPalette(PAL_INDEXED, 00238 ppalDIB->NumColors, 00239 NULL, 00240 0, 00241 0, 00242 0); 00243 00244 /* Loop all colors */ 00245 for (i = 0; i < ppalDIB->NumColors; i++) 00246 { 00247 /* Get the RGB color, which is the index into the DC palette */ 00248 iPalIndex = PALETTE_ulGetRGBColorFromIndex(ppalDIB, i); 00249 00250 /* Roll over when index is too big */ 00251 iPalIndex %= ppalDC->NumColors; 00252 00253 /* Set the indexed DC color as the new color */ 00254 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, iPalIndex); 00255 PALETTE_vSetRGBColorForIndex(ppalNew, i, crColor); 00256 } 00257 00258 /* Return the new palette */ 00259 return ppalNew; 00260 } 00261 00262 BOOL 00263 NTAPI 00264 EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver) 00265 { 00266 BOOL bResult; 00267 PFN_DrvRealizeBrush pfnRealzizeBrush = NULL; 00268 PSURFACE psurfPattern, psurfMask; 00269 PPDEVOBJ ppdev; 00270 EXLATEOBJ exlo; 00271 PPALETTE ppalPattern; 00272 PBRUSH pbr = pebo->pbrush; 00273 HBITMAP hbmPattern; 00274 ULONG iHatch; 00275 00276 /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */ 00277 ASSERT(pebo->psurfTrg); 00278 00279 ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev; 00280 if (!ppdev) ppdev = gppdevPrimary; 00281 00282 if (bCallDriver) 00283 pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush; 00284 00285 if (!pfnRealzizeBrush) 00286 pfnRealzizeBrush = EngRealizeBrush; 00287 00288 /* Check if this is a hatch brush */ 00289 if (pbr->flAttrs & BR_IS_HATCH) 00290 { 00291 /* Get the hatch brush pattern from the PDEV */ 00292 hbmPattern = (HBITMAP)ppdev->ahsurf[pbr->ulStyle]; 00293 iHatch = pbr->ulStyle; 00294 } 00295 else 00296 { 00297 /* Use the brushes pattern */ 00298 hbmPattern = pbr->hbmPattern; 00299 iHatch = -1; 00300 } 00301 00302 psurfPattern = SURFACE_ShareLockSurface(hbmPattern); 00303 ASSERT(psurfPattern); 00304 ASSERT(psurfPattern->ppal); 00305 00306 /* FIXME: implement mask */ 00307 psurfMask = NULL; 00308 00309 /* DIB brushes with DIB_PAL_COLORS usage need a new palette */ 00310 if (pbr->flAttrs & BR_IS_DIBPALCOLORS) 00311 { 00312 /* Create a palette with the colors from the DC */ 00313 ppalPattern = FixupDIBBrushPalette(psurfPattern->ppal, pebo->ppalDC); 00314 pebo->ppalDIB = ppalPattern; 00315 } 00316 else 00317 { 00318 /* The palette is already as it should be */ 00319 ppalPattern = psurfPattern->ppal; 00320 } 00321 00322 /* Initialize XLATEOBJ for the brush */ 00323 EXLATEOBJ_vInitialize(&exlo, 00324 ppalPattern, 00325 pebo->psurfTrg->ppal, 00326 0, 00327 pebo->crCurrentBack, 00328 pebo->crCurrentText); 00329 00330 /* Create the realization */ 00331 bResult = pfnRealzizeBrush(&pebo->BrushObject, 00332 &pebo->psurfTrg->SurfObj, 00333 &psurfPattern->SurfObj, 00334 psurfMask ? &psurfMask->SurfObj : NULL, 00335 &exlo.xlo, 00336 iHatch); 00337 00338 /* Cleanup the XLATEOBJ */ 00339 EXLATEOBJ_vCleanup(&exlo); 00340 00341 /* Unlock surfaces */ 00342 if (psurfPattern) 00343 SURFACE_ShareUnlockSurface(psurfPattern); 00344 if (psurfMask) 00345 SURFACE_ShareUnlockSurface(psurfMask); 00346 00347 return bResult; 00348 } 00349 00350 PVOID 00351 NTAPI 00352 EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo) 00353 { 00354 BOOL bResult; 00355 00356 if (!pebo->pengbrush) 00357 { 00358 bResult = EBRUSHOBJ_bRealizeBrush(pebo, FALSE); 00359 if (!bResult) 00360 { 00361 if (pebo->pengbrush) 00362 EngDeleteSurface(pebo->pengbrush); 00363 pebo->pengbrush = NULL; 00364 } 00365 } 00366 00367 return pebo->pengbrush; 00368 } 00369 00370 SURFOBJ* 00371 NTAPI 00372 EBRUSHOBJ_psoPattern(EBRUSHOBJ *pebo) 00373 { 00374 PSURFACE psurfPattern; 00375 00376 psurfPattern = EBRUSHOBJ_pvGetEngBrush(pebo); 00377 00378 return psurfPattern ? &psurfPattern->SurfObj : NULL; 00379 } 00380 00381 00384 /* 00385 * @implemented 00386 */ 00387 PVOID APIENTRY 00388 BRUSHOBJ_pvAllocRbrush( 00389 IN BRUSHOBJ *pbo, 00390 IN ULONG cj) 00391 { 00392 pbo->pvRbrush = EngAllocMem(0, cj, GDITAG_RBRUSH); 00393 return pbo->pvRbrush; 00394 } 00395 00396 /* 00397 * @implemented 00398 */ 00399 PVOID APIENTRY 00400 BRUSHOBJ_pvGetRbrush( 00401 IN BRUSHOBJ *pbo) 00402 { 00403 EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); 00404 BOOL bResult; 00405 00406 if (!pbo->pvRbrush) 00407 { 00408 bResult = EBRUSHOBJ_bRealizeBrush(pebo, TRUE); 00409 if (!bResult) 00410 { 00411 if (pbo->pvRbrush) 00412 { 00413 EngFreeMem(pbo->pvRbrush); 00414 pbo->pvRbrush = NULL; 00415 } 00416 } 00417 } 00418 00419 return pbo->pvRbrush; 00420 } 00421 00422 /* 00423 * @implemented 00424 */ 00425 ULONG APIENTRY 00426 BRUSHOBJ_ulGetBrushColor( 00427 IN BRUSHOBJ *pbo) 00428 { 00429 EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); 00430 return pebo->ulRGBColor; 00431 } 00432 00433 /* EOF */ Generated on Sat May 26 2012 04:37:08 for ReactOS by
1.7.6.1
|