[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / subsystems / win32 / win32k / eng / engbrush.c
index 5b824fc..c61e0e4 100644 (file)
  *                    Timo Kreuzer
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
 /** Internal functions ********************************************************/
 
+VOID
+NTAPI
+EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
+{
+    ASSERT(pebo);
+    ASSERT(pbrush);
+    ASSERT(pdc);
+
+    pebo->BrushObject.flColorType = 0;
+    pebo->BrushObject.pvRbrush = NULL;
+    pebo->pbrush = pbrush;
+    pebo->pengbrush = NULL;
+    pebo->flattrs = pbrush->flAttrs;
+
+    /* Initialize 1 bpp fore and back colors */
+    pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr;
+    pebo->crCurrentText = pdc->pdcattr->crForegroundClr;
+
+    pebo->psurfTrg = pdc->dclevel.pSurface;
+    ASSERT(pebo->psurfTrg);
+    ASSERT(pebo->psurfTrg->ppal);
+
+    pebo->ppalSurf = pebo->psurfTrg->ppal;
+    GDIOBJ_IncrementShareCount(&pebo->ppalSurf->BaseObject);
+
+    if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
+    {
+        /* NULL brushes don't need a color */
+        pebo->BrushObject.iSolidColor = 0;
+    }
+    else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
+    {
+        /* Set the RGB color */
+        EBRUSHOBJ_vSetSolidBrushColor(pebo, pbrush->BrushAttr.lbColor);
+    }
+    else
+    {
+        /* This is a pattern brush that needs realization */
+        pebo->BrushObject.iSolidColor = 0xFFFFFFFF;
+
+        /* Use foreground color of hatch brushes */
+        if (pbrush->flAttrs & GDIBRUSH_IS_HATCH)
+            pebo->crCurrentText = pbrush->BrushAttr.lbColor;
+    }
+}
+
+VOID
+FASTCALL
+EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor)
+{
+    ULONG iSolidColor;
+    EXLATEOBJ exlo;
+
+    /* Never use with non-solid brushes */
+    ASSERT(pebo->flattrs & GDIBRUSH_IS_SOLID);
+
+    /* Set the RGB color */
+    pebo->crRealize = crColor;
+    pebo->ulRGBColor = crColor;
+
+    /* Initialize an XLATEOBJ RGB -> surface */
+    EXLATEOBJ_vInitialize(&exlo,
+                          &gpalRGB,
+                          pebo->ppalSurf,
+                          pebo->crCurrentBack,
+                          0,
+                          0);
+
+    /* Translate the brush color to the target format */
+    iSolidColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
+    pebo->BrushObject.iSolidColor = iSolidColor;
+
+    /* Clean up the XLATEOBJ */
+    EXLATEOBJ_vCleanup(&exlo);
+}
+
+VOID
+NTAPI
+EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
+{
+    /* Check if there's a GDI realisation */
+    if (pebo->pengbrush)
+    {
+        EngDeleteSurface(pebo->pengbrush);
+        pebo->pengbrush = NULL;
+    }
+
+    /* Check if there's a driver's realisation */
+    if (pebo->BrushObject.pvRbrush)
+    {
+        /* Free allocated driver memory */
+        EngFreeMem(pebo->BrushObject.pvRbrush);
+        pebo->BrushObject.pvRbrush = NULL;
+    }
+
+    PALETTE_ShareUnlockPalette(pebo->ppalSurf);
+}
+
+VOID
+NTAPI
+EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
+{
+    /* Cleanup the brush */
+    EBRUSHOBJ_vCleanup(pebo);
+
+    /* Reinitialize */
+    EBRUSHOBJ_vInit(pebo, pbrush, pdc);
+}
+
 /**
  * This function is not exported, because it makes no sense for
  * The driver to punt back to this function */
@@ -35,7 +144,7 @@ EngRealizeBrush(
     ULONG lWidth;
 
     /* Calculate width in bytes of the realized brush */
-    lWidth = DIB_GetDIBWidthBytes(psoPattern->sizlBitmap.cx,
+    lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx,
                                   BitsPerFormat(psoDst->iBitmapFormat));
 
     /* Allocate a bitmap */
@@ -58,7 +167,9 @@ EngRealizeBrush(
     }
 
     /* Copy the bits to the new format bitmap */
-    rclDest = (RECTL){0, 0, psoPattern->sizlBitmap.cx, psoPattern->sizlBitmap.cy};
+    rclDest.left = rclDest.top = 0;
+    rclDest.right = psoPattern->sizlBitmap.cx;
+    rclDest.bottom = psoPattern->sizlBitmap.cy;
     EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc);
 
     /* Unlock the bitmap again */
@@ -70,161 +181,63 @@ EngRealizeBrush(
     return TRUE;
 }
 
-VOID
-NTAPI
-EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
-{
-    ULONG iSolidColor;
-    XLATEOBJ *pxlo;
-    PSURFACE psurfTrg;
-
-    ASSERT(pebo);
-    ASSERT(pbrush);
-    ASSERT(pdc);
-
-    psurfTrg = pdc->dclevel.pSurface;
-
-    pebo->psurfTrg = psurfTrg;
-    pebo->BrushObject.flColorType = 0;
-    pebo->pbrush = pbrush;
-    pebo->flattrs = pbrush->flAttrs;
-    pebo->crCurrentText = pdc->pdcattr->crForegroundClr;
-    pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr;
-    pebo->BrushObject.pvRbrush = NULL;
-    pebo->pengbrush = NULL;
-
-    if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
-    {
-        pebo->BrushObject.iSolidColor = 0;
-    }
-    else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
-    {
-        /* Set the RGB color */
-        pebo->crRealize = pbrush->BrushAttr.lbColor;
-        pebo->ulRGBColor = pbrush->BrushAttr.lbColor;
-
-        /* Translate the brush color to the target format */
-        pxlo = IntCreateBrushXlate(pbrush, psurfTrg, pebo->crCurrentBack);
-        iSolidColor = XLATEOBJ_iXlate(pxlo, pbrush->BrushAttr.lbColor);
-        pebo->BrushObject.iSolidColor = iSolidColor;
-        if (pxlo)
-            EngDeleteXlate(pxlo);
-    }
-    else
-    {
-        /* This is a pattern brush that needs realization */
-        pebo->BrushObject.iSolidColor = 0xFFFFFFFF;
-    }
-}
-
-VOID
-FASTCALL
-EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo)
-{
-    ULONG iSolidColor;
-
-    /* Never use with non-solid brushes */
-    ASSERT(pebo->flattrs & GDIBRUSH_IS_SOLID);
-
-    /* Set the RGB color */
-    pebo->crRealize = crColor;
-    pebo->ulRGBColor = crColor;
-
-    /* Translate the brush color to the target format */
-    iSolidColor = XLATEOBJ_iXlate(pxlo, crColor);
-    pebo->BrushObject.iSolidColor = iSolidColor;
-
-    pebo->BrushObject.iSolidColor = iSolidColor;
-}
-
 BOOL
 NTAPI
-EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo)
+EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
 {
     BOOL bResult;
     PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
-    PSURFACE psurfTrg, psurfPattern, psurfMask;
+    PSURFACE psurfPattern, psurfMask;
     PPDEVOBJ ppdev = NULL;
-    XLATEOBJ *pxlo;
+    EXLATEOBJ exlo;
 
-    psurfTrg = pebo->psurfTrg; // FIXME: all EBRUSHOBJs need a surface
-    if (!psurfTrg)
-    {
-        DPRINT1("Pattern brush has no target surface!\n");
-        return FALSE;
-    }
+    /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
+    ASSERT(pebo->psurfTrg);
+
+    ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
 
-    ppdev = (PPDEVOBJ)psurfTrg->SurfObj.hdev; // FIXME: all SURFACEs need a PDEV
-    if (ppdev)
+    // FIXME: all SURFACEs need a PDEV
+    if (ppdev && bCallDriver)
         pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
+
     if (!pfnRealzizeBrush)
-    {
         pfnRealzizeBrush = EngRealizeBrush;
-    }
 
-    psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern);
-    if (!psurfPattern)
-    {
-        DPRINT1("No pattern, nothing to realize!\n");
-        return FALSE;
-    }
+    psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
+    ASSERT(psurfPattern);
+    ASSERT(psurfPattern->ppal);
 
     /* FIXME: implement mask */
     psurfMask = NULL;
 
-    /* Create xlateobj for the brush */
-    pxlo = IntCreateBrushXlate(pebo->pbrush, psurfTrg, pebo->crCurrentBack);
+    /* Initialize XLATEOBJ for the brush */
+    EXLATEOBJ_vInitialize(&exlo, 
+                          psurfPattern->ppal,
+                          pebo->psurfTrg->ppal,
+                          0,
+                          pebo->crCurrentBack,
+                          pebo->crCurrentText);
 
-    /* Perform the realization */
+    /* Create the realization */
     bResult = pfnRealzizeBrush(&pebo->BrushObject,
                                &pebo->psurfTrg->SurfObj,
                                &psurfPattern->SurfObj,
                                psurfMask ? &psurfMask->SurfObj : NULL,
-                               pxlo,
+                               &exlo.xlo,
                                -1); // FIXME: what about hatch brushes?
 
-    EngDeleteXlate(pxlo);
+    /* Cleanup the XLATEOBJ */
+    EXLATEOBJ_vCleanup(&exlo);
 
+    /* Unlock surfaces */
     if (psurfPattern)
-        SURFACE_UnlockSurface(psurfPattern);
-
+        SURFACE_ShareUnlockSurface(psurfPattern);
     if (psurfMask)
-        SURFACE_UnlockSurface(psurfMask);
+        SURFACE_ShareUnlockSurface(psurfMask);
 
     return bResult;
 }
 
-VOID
-NTAPI
-EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
-{
-    /* Check if there's a GDI realisation */
-    if (pebo->pengbrush)
-    {
-        EngDeleteSurface(pebo->pengbrush);
-        pebo->pengbrush = NULL;
-    }
-
-    /* Check if there's a driver's realisation */
-    if (pebo->BrushObject.pvRbrush)
-    {
-        /* Free allocated driver memory */
-        EngFreeMem(pebo->BrushObject.pvRbrush);
-        pebo->BrushObject.pvRbrush = NULL;
-    }
-}
-
-VOID
-NTAPI
-EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
-{
-    /* Cleanup the brush */
-    EBRUSHOBJ_vCleanup(pebo);
-
-    /* Reinitialize */
-    EBRUSHOBJ_vInit(pebo, pbrush, pdc);
-}
-
 PVOID
 NTAPI
 EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo)
@@ -233,7 +246,7 @@ EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo)
 
     if (!pebo->pengbrush)
     {
-        bResult = EBRUSHOBJ_bRealizeBrush(pebo);
+        bResult = EBRUSHOBJ_bRealizeBrush(pebo, FALSE);
         if (!bResult)
         {
             if (pebo->pengbrush)
@@ -256,7 +269,7 @@ BRUSHOBJ_pvAllocRbrush(
     IN BRUSHOBJ *pbo,
     IN ULONG cj)
 {
-    pbo->pvRbrush = EngAllocMem(0, cj, 'rbdG');
+    pbo->pvRbrush = EngAllocMem(0, cj, GDITAG_RBRUSH);
     return pbo->pvRbrush;
 }
 
@@ -272,12 +285,14 @@ BRUSHOBJ_pvGetRbrush(
 
     if (!pbo->pvRbrush)
     {
-        bResult = EBRUSHOBJ_bRealizeBrush(pebo);
+        bResult = EBRUSHOBJ_bRealizeBrush(pebo, TRUE);
         if (!bResult)
         {
             if (pbo->pvRbrush)
+            {
                 EngFreeMem(pbo->pvRbrush);
-            pbo->pvRbrush = NULL;
+                pbo->pvRbrush = NULL;
+            }
         }
     }