ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

engbrush.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.