[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / subsystems / win32 / win32k / eng / engbrush.c
index 715da96..c61e0e4 100644 (file)
 /*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
  * PURPOSE:           GDI Driver Brush Functions
- * FILE:              subsys/win32k/eng/brush.c
+ * FILE:              subsystem/win32/win32k/eng/engbrush.c
  * PROGRAMER:         Jason Filby
- * REVISION HISTORY:
- *                 3/7/1999: Created
+ *                    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 */
+BOOL
+APIENTRY
+EngRealizeBrush(
+    BRUSHOBJ *pbo,
+    SURFOBJ  *psoDst,
+    SURFOBJ  *psoPattern,
+    SURFOBJ  *psoMask,
+    XLATEOBJ *pxlo,
+    ULONG    iHatch)
+{
+    EBRUSHOBJ *pebo;
+    HBITMAP hbmpRealize;
+    SURFOBJ *psoRealize;
+    POINTL ptlSrc = {0, 0};
+    RECTL rclDest;
+    ULONG lWidth;
+
+    /* Calculate width in bytes of the realized brush */
+    lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx,
+                                  BitsPerFormat(psoDst->iBitmapFormat));
+
+    /* Allocate a bitmap */
+    hbmpRealize = EngCreateBitmap(psoPattern->sizlBitmap,
+                                  lWidth,
+                                  psoDst->iBitmapFormat,
+                                  BMF_NOZEROINIT,
+                                  NULL);
+    if (!hbmpRealize)
+    {
+        return FALSE;
+    }
+
+    /* Lock the bitmap */
+    psoRealize = EngLockSurface(hbmpRealize);
+    if (!psoRealize)
+    {
+        EngDeleteSurface(hbmpRealize);
+        return FALSE;
+    }
+
+    /* Copy the bits to the new format bitmap */
+    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 */
+    EngUnlockSurface(psoRealize);
+
+    pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
+    pebo->pengbrush = (PVOID)hbmpRealize;
+
+    return TRUE;
+}
+
+BOOL
+NTAPI
+EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
+{
+    BOOL bResult;
+    PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
+    PSURFACE psurfPattern, psurfMask;
+    PPDEVOBJ ppdev = NULL;
+    EXLATEOBJ exlo;
+
+    /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
+    ASSERT(pebo->psurfTrg);
+
+    ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
+
+    // FIXME: all SURFACEs need a PDEV
+    if (ppdev && bCallDriver)
+        pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
+
+    if (!pfnRealzizeBrush)
+        pfnRealzizeBrush = EngRealizeBrush;
+
+    psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
+    ASSERT(psurfPattern);
+    ASSERT(psurfPattern->ppal);
+
+    /* FIXME: implement mask */
+    psurfMask = NULL;
+
+    /* Initialize XLATEOBJ for the brush */
+    EXLATEOBJ_vInitialize(&exlo, 
+                          psurfPattern->ppal,
+                          pebo->psurfTrg->ppal,
+                          0,
+                          pebo->crCurrentBack,
+                          pebo->crCurrentText);
+
+    /* Create the realization */
+    bResult = pfnRealzizeBrush(&pebo->BrushObject,
+                               &pebo->psurfTrg->SurfObj,
+                               &psurfPattern->SurfObj,
+                               psurfMask ? &psurfMask->SurfObj : NULL,
+                               &exlo.xlo,
+                               -1); // FIXME: what about hatch brushes?
+
+    /* Cleanup the XLATEOBJ */
+    EXLATEOBJ_vCleanup(&exlo);
+
+    /* Unlock surfaces */
+    if (psurfPattern)
+        SURFACE_ShareUnlockSurface(psurfPattern);
+    if (psurfMask)
+        SURFACE_ShareUnlockSurface(psurfMask);
+
+    return bResult;
+}
+
+PVOID
+NTAPI
+EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo)
+{
+    BOOL bResult;
+
+    if (!pebo->pengbrush)
+    {
+        bResult = EBRUSHOBJ_bRealizeBrush(pebo, FALSE);
+        if (!bResult)
+        {
+            if (pebo->pengbrush)
+                EngDeleteSurface(pebo->pengbrush);
+            pebo->pengbrush = NULL;
+        }
+    }
+
+    return pebo->pengbrush;
+}
+
+
+/** Exported DDI functions ****************************************************/
+
 /*
  * @implemented
  */
-PVOID STDCALL
-BRUSHOBJ_pvAllocRbrush(IN BRUSHOBJ  *BrushObj,
-                      IN ULONG  ObjSize)
+PVOID APIENTRY
+BRUSHOBJ_pvAllocRbrush(
+    IN BRUSHOBJ *pbo,
+    IN ULONG cj)
 {
-  BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
-  return(BrushObj->pvRbrush);
+    pbo->pvRbrush = EngAllocMem(0, cj, GDITAG_RBRUSH);
+    return pbo->pvRbrush;
 }
 
 /*
  * @implemented
  */
-PVOID STDCALL
-BRUSHOBJ_pvGetRbrush(IN BRUSHOBJ  *BrushObj)
+PVOID APIENTRY
+BRUSHOBJ_pvGetRbrush(
+    IN BRUSHOBJ *pbo)
 {
-  return(BrushObj->pvRbrush);
+    EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
+    BOOL bResult;
+
+    if (!pbo->pvRbrush)
+    {
+        bResult = EBRUSHOBJ_bRealizeBrush(pebo, TRUE);
+        if (!bResult)
+        {
+            if (pbo->pvRbrush)
+            {
+                EngFreeMem(pbo->pvRbrush);
+                pbo->pvRbrush = NULL;
+            }
+        }
+    }
+
+    return pbo->pvRbrush;
 }
 
 /*
  * @implemented
  */
-ULONG STDCALL
-BRUSHOBJ_ulGetBrushColor(IN BRUSHOBJ *BrushObj)
+ULONG APIENTRY
+BRUSHOBJ_ulGetBrushColor(
+    IN BRUSHOBJ *pbo)
 {
-   return BrushObj->iSolidColor;
+    EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
+    return pebo->ulRGBColor;
 }
 
 /* EOF */