2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Driver Brush Functions
5 * FILE: subsystem/win32/win32k/eng/engbrush.c
6 * PROGRAMER: Jason Filby
12 DBG_DEFAULT_CHANNEL(EngBrush
);
14 static const ULONG gaulHatchBrushes
[HS_DDI_MAX
][8] =
16 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
17 {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
18 {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
19 {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
20 {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
21 {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
24 HSURF gahsurfHatch
[HS_DDI_MAX
];
26 /** Internal functions ********************************************************/
36 /* Loop all hatch styles */
37 for (i
= 0; i
< HS_DDI_MAX
; i
++)
39 /* Create a default hatch bitmap */
40 gahsurfHatch
[i
] = (HSURF
)EngCreateBitmap(sizl
,
44 (PVOID
)gaulHatchBrushes
[i
]);
47 return STATUS_SUCCESS
;
52 EBRUSHOBJ_vInit(EBRUSHOBJ
*pebo
,
55 COLORREF crBackgroundClr
,
56 COLORREF crForegroundClr
,
62 pebo
->BrushObject
.flColorType
= 0;
63 pebo
->BrushObject
.pvRbrush
= NULL
;
64 pebo
->pbrush
= pbrush
;
65 pebo
->pengbrush
= NULL
;
66 pebo
->flattrs
= pbrush
->flAttrs
;
69 /* Initialize 1 bpp fore and back colors */
70 pebo
->crCurrentBack
= crBackgroundClr
;
71 pebo
->crCurrentText
= crForegroundClr
;
73 pebo
->psurfTrg
= psurf
;
74 /* We are initializing for a new memory DC */
76 pebo
->psurfTrg
= psurfDefaultBitmap
;
77 ASSERT(pebo
->psurfTrg
);
78 ASSERT(pebo
->psurfTrg
->ppal
);
80 /* Initialize palettes */
81 pebo
->ppalSurf
= pebo
->psurfTrg
->ppal
;
82 GDIOBJ_vReferenceObjectByPointer(&pebo
->ppalSurf
->BaseObject
);
83 pebo
->ppalDC
= ppalDC
;
85 pebo
->ppalDC
= gppalDefault
;
86 GDIOBJ_vReferenceObjectByPointer(&pebo
->ppalDC
->BaseObject
);
89 if (pbrush
->flAttrs
& BR_IS_NULL
)
91 /* NULL brushes don't need a color */
92 pebo
->BrushObject
.iSolidColor
= 0;
94 else if (pbrush
->flAttrs
& BR_IS_SOLID
)
96 /* Set the RGB color */
97 EBRUSHOBJ_vSetSolidRGBColor(pebo
, pbrush
->BrushAttr
.lbColor
);
101 /* This is a pattern brush that needs realization */
102 pebo
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
104 /* Use foreground color of hatch brushes */
105 if (pbrush
->flAttrs
& BR_IS_HATCH
)
106 pebo
->crCurrentText
= pbrush
->BrushAttr
.lbColor
;
112 EBRUSHOBJ_vInitFromDC(EBRUSHOBJ
*pebo
,
113 PBRUSH pbrush
, PDC pdc
)
115 EBRUSHOBJ_vInit(pebo
, pbrush
, pdc
->dclevel
.pSurface
,
116 pdc
->pdcattr
->crBackgroundClr
, pdc
->pdcattr
->crForegroundClr
,
122 EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ
*pebo
, COLORREF crColor
)
127 /* Never use with non-solid brushes */
128 ASSERT(pebo
->flattrs
& BR_IS_SOLID
);
130 /* Set the RGB color */
132 pebo
->crRealize
= crColor
;
133 pebo
->ulRGBColor
= crColor
;
135 /* Initialize an XLATEOBJ RGB -> surface */
136 EXLATEOBJ_vInitialize(&exlo
,
143 /* Translate the brush color to the target format */
144 iSolidColor
= XLATEOBJ_iXlate(&exlo
.xlo
, crColor
);
145 pebo
->BrushObject
.iSolidColor
= iSolidColor
;
147 /* Clean up the XLATEOBJ */
148 EXLATEOBJ_vCleanup(&exlo
);
153 EBRUSHOBJ_vCleanup(EBRUSHOBJ
*pebo
)
155 /* Check if there's a GDI realisation */
158 /* Unlock the bitmap again */
159 SURFACE_ShareUnlockSurface(pebo
->pengbrush
);
160 pebo
->pengbrush
= NULL
;
163 /* Check if there's a driver's realisation */
164 if (pebo
->BrushObject
.pvRbrush
)
166 /* Free allocated driver memory */
167 EngFreeMem(pebo
->BrushObject
.pvRbrush
);
168 pebo
->BrushObject
.pvRbrush
= NULL
;
171 if (pebo
->psoMask
!= NULL
)
173 SURFACE_ShareUnlockSurface(pebo
->psoMask
);
174 pebo
->psoMask
= NULL
;
177 /* Dereference the palettes */
178 PALETTE_ShareUnlockPalette(pebo
->ppalSurf
);
179 PALETTE_ShareUnlockPalette(pebo
->ppalDC
);
180 if (pebo
->ppalDIB
) PALETTE_ShareUnlockPalette(pebo
->ppalDIB
);
185 EBRUSHOBJ_vUpdateFromDC(
190 /* Cleanup the brush */
191 EBRUSHOBJ_vCleanup(pebo
);
194 EBRUSHOBJ_vInitFromDC(pebo
, pbrush
, pdc
);
198 * This function is not exported, because it makes no sense for
199 * The driver to punt back to this function */
213 PSURFACE psurfRealize
;
214 POINTL ptlSrc
= {0, 0};
218 /* Calculate width in bytes of the realized brush */
219 lWidth
= WIDTH_BYTES_ALIGN32(psoPattern
->sizlBitmap
.cx
,
220 BitsPerFormat(psoDst
->iBitmapFormat
));
222 /* Allocate a bitmap */
223 hbmpRealize
= EngCreateBitmap(psoPattern
->sizlBitmap
,
225 psoDst
->iBitmapFormat
,
233 /* Lock the bitmap */
234 psurfRealize
= SURFACE_ShareLockSurface(hbmpRealize
);
236 /* Already delete the pattern bitmap (will be kept until dereferenced) */
237 EngDeleteSurface((HSURF
)hbmpRealize
);
244 /* Copy the bits to the new format bitmap */
245 rclDest
.left
= rclDest
.top
= 0;
246 rclDest
.right
= psoPattern
->sizlBitmap
.cx
;
247 rclDest
.bottom
= psoPattern
->sizlBitmap
.cy
;
248 psoRealize
= &psurfRealize
->SurfObj
;
249 EngCopyBits(psoRealize
, psoPattern
, NULL
, pxlo
, &rclDest
, &ptlSrc
);
252 pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
253 pebo
->pengbrush
= (PVOID
)psurfRealize
;
260 FixupDIBBrushPalette(
261 _In_ PPALETTE ppalDIB
,
262 _In_ PPALETTE ppalDC
)
265 ULONG i
, iPalIndex
, crColor
;
267 /* Allocate a new palette */
268 ppalNew
= PALETTE_AllocPalette(PAL_INDEXED
,
276 ERR("Failed to allcate palette for brush\n");
280 /* Loop all colors */
281 for (i
= 0; i
< ppalDIB
->NumColors
; i
++)
283 /* Get the RGB color, which is the index into the DC palette */
284 iPalIndex
= PALETTE_ulGetRGBColorFromIndex(ppalDIB
, i
);
286 /* Roll over when index is too big */
287 iPalIndex
%= ppalDC
->NumColors
;
289 /* Set the indexed DC color as the new color */
290 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, iPalIndex
);
291 PALETTE_vSetRGBColorForIndex(ppalNew
, i
, crColor
);
294 /* Return the new palette */
300 EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ
*pebo
, BOOL bCallDriver
)
303 PFN_DrvRealizeBrush pfnRealizeBrush
= NULL
;
304 PSURFACE psurfPattern
;
308 PPALETTE ppalPattern
;
309 PBRUSH pbr
= pebo
->pbrush
;
313 /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
314 ASSERT(pebo
->psurfTrg
);
316 ppdev
= (PPDEVOBJ
)pebo
->psurfTrg
->SurfObj
.hdev
;
318 ppdev
= gppdevPrimary
;
322 /* Get the Drv function */
323 pfnRealizeBrush
= ppdev
->DriverFunctions
.RealizeBrush
;
324 if (pfnRealizeBrush
== NULL
)
326 ERR("No DrvRealizeBrush. Cannot realize brush\n");
331 psoMask
= EBRUSHOBJ_psoMask(pebo
);
335 /* Use the Eng function */
336 pfnRealizeBrush
= EngRealizeBrush
;
338 /* We don't handle the mask bitmap here. We do this only on demand */
342 /* Check if this is a hatch brush */
343 if (pbr
->flAttrs
& BR_IS_HATCH
)
345 /* Get the hatch brush pattern from the PDEV */
346 hbmPattern
= (HBITMAP
)ppdev
->ahsurf
[pbr
->iHatch
];
347 iHatch
= pbr
->iHatch
;
351 /* Use the brushes pattern */
352 hbmPattern
= pbr
->hbmPattern
;
356 psurfPattern
= SURFACE_ShareLockSurface(hbmPattern
);
357 ASSERT(psurfPattern
);
358 ASSERT(psurfPattern
->ppal
);
360 /* DIB brushes with DIB_PAL_COLORS usage need a new palette */
361 if (pbr
->flAttrs
& BR_IS_DIBPALCOLORS
)
363 /* Create a palette with the colors from the DC */
364 ppalPattern
= FixupDIBBrushPalette(psurfPattern
->ppal
, pebo
->ppalDC
);
365 if (ppalPattern
== NULL
)
367 ERR("FixupDIBBrushPalette() failed.\n");
371 pebo
->ppalDIB
= ppalPattern
;
375 /* The palette is already as it should be */
376 ppalPattern
= psurfPattern
->ppal
;
379 /* Initialize XLATEOBJ for the brush */
380 EXLATEOBJ_vInitialize(&exlo
,
382 pebo
->psurfTrg
->ppal
,
385 pebo
->crCurrentText
);
387 /* Create the realization */
388 bResult
= pfnRealizeBrush(&pebo
->BrushObject
,
389 &pebo
->psurfTrg
->SurfObj
,
390 &psurfPattern
->SurfObj
,
395 /* Cleanup the XLATEOBJ */
396 EXLATEOBJ_vCleanup(&exlo
);
399 SURFACE_ShareUnlockSurface(psurfPattern
);
406 EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ
*pebo
)
410 if (!pebo
->pengbrush
)
412 bResult
= EBRUSHOBJ_bRealizeBrush(pebo
, FALSE
);
416 EngDeleteSurface(pebo
->pengbrush
);
417 pebo
->pengbrush
= NULL
;
421 return pebo
->pengbrush
;
426 EBRUSHOBJ_psoPattern(EBRUSHOBJ
*pebo
)
428 PSURFACE psurfPattern
;
430 psurfPattern
= EBRUSHOBJ_pvGetEngBrush(pebo
);
432 return psurfPattern
? &psurfPattern
->SurfObj
: NULL
;
437 EBRUSHOBJ_psoMask(EBRUSHOBJ
*pebo
)
443 /* Check if we don't have a mask yet */
444 if (pebo
->psoMask
== NULL
)
446 /* Check if this is a hatch brush */
447 if (pebo
->flattrs
& BR_IS_HATCH
)
450 ppdev
= (PPDEVOBJ
)pebo
->psurfTrg
->SurfObj
.hdev
;
452 ppdev
= gppdevPrimary
;
454 /* Use the hatch bitmap as the mask */
455 hbmMask
= (HBITMAP
)ppdev
->ahsurf
[pebo
->pbrush
->iHatch
];
456 psurfMask
= SURFACE_ShareLockSurface(hbmMask
);
457 if (psurfMask
== NULL
)
459 ERR("Failed to lock hatch brush for PDEV %p, iHatch %lu\n",
460 ppdev
, pebo
->pbrush
->iHatch
);
464 NT_ASSERT(psurfMask
->SurfObj
.iBitmapFormat
== BMF_1BPP
);
465 pebo
->psoMask
= &psurfMask
->SurfObj
;
469 return pebo
->psoMask
;
472 /** Exported DDI functions ****************************************************/
478 BRUSHOBJ_pvAllocRbrush(
482 pbo
->pvRbrush
= EngAllocMem(0, cj
, GDITAG_RBRUSH
);
483 return pbo
->pvRbrush
;
490 BRUSHOBJ_pvGetRbrush(
493 EBRUSHOBJ
*pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
498 bResult
= EBRUSHOBJ_bRealizeBrush(pebo
, TRUE
);
503 EngFreeMem(pbo
->pvRbrush
);
504 pbo
->pvRbrush
= NULL
;
509 return pbo
->pvRbrush
;
516 BRUSHOBJ_ulGetBrushColor(
519 EBRUSHOBJ
*pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
520 return pebo
->ulRGBColor
;