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
15 static const ULONG gaulHatchBrushes
[HS_DDI_MAX
][8] =
17 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
18 {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
19 {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
20 {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
21 {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
22 {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
25 HSURF gahsurfHatch
[HS_DDI_MAX
];
27 /** Internal functions ********************************************************/
37 /* Loop all hatch styles */
38 for (i
= 0; i
< HS_DDI_MAX
; i
++)
40 /* Create a default hatch bitmap */
41 gahsurfHatch
[i
] = (HSURF
)EngCreateBitmap(sizl
,
45 (PVOID
)gaulHatchBrushes
[i
]);
48 return STATUS_SUCCESS
;
53 EBRUSHOBJ_vInit(EBRUSHOBJ
*pebo
, PBRUSH pbrush
, PDC pdc
)
59 pebo
->BrushObject
.flColorType
= 0;
60 pebo
->BrushObject
.pvRbrush
= NULL
;
61 pebo
->pbrush
= pbrush
;
62 pebo
->pengbrush
= NULL
;
63 pebo
->flattrs
= pbrush
->flAttrs
;
65 /* Initialize 1 bpp fore and back colors */
66 pebo
->crCurrentBack
= pdc
->pdcattr
->crBackgroundClr
;
67 pebo
->crCurrentText
= pdc
->pdcattr
->crForegroundClr
;
69 pebo
->psurfTrg
= pdc
->dclevel
.pSurface
;
70 ASSERT(pebo
->psurfTrg
);
71 ASSERT(pebo
->psurfTrg
->ppal
);
73 pebo
->ppalSurf
= pebo
->psurfTrg
->ppal
;
74 GDIOBJ_vReferenceObjectByPointer(&pebo
->ppalSurf
->BaseObject
);
75 pebo
->ppalDC
= pdc
->dclevel
.ppal
;
76 GDIOBJ_vReferenceObjectByPointer(&pebo
->ppalDC
->BaseObject
);
78 if (pbrush
->flAttrs
& BR_IS_NULL
)
80 /* NULL brushes don't need a color */
81 pebo
->BrushObject
.iSolidColor
= 0;
83 else if (pbrush
->flAttrs
& BR_IS_SOLID
)
85 /* Set the RGB color */
86 EBRUSHOBJ_vSetSolidRGBColor(pebo
, pbrush
->BrushAttr
.lbColor
);
90 /* This is a pattern brush that needs realization */
91 pebo
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
93 /* Use foreground color of hatch brushes */
94 if (pbrush
->flAttrs
& BR_IS_HATCH
)
95 pebo
->crCurrentText
= pbrush
->BrushAttr
.lbColor
;
101 EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ
*pebo
, COLORREF crColor
)
106 /* Never use with non-solid brushes */
107 ASSERT(pebo
->flattrs
& BR_IS_SOLID
);
109 /* Set the RGB color */
110 pebo
->crRealize
= crColor
;
111 pebo
->ulRGBColor
= crColor
;
113 /* Initialize an XLATEOBJ RGB -> surface */
114 EXLATEOBJ_vInitialize(&exlo
,
121 /* Translate the brush color to the target format */
122 iSolidColor
= XLATEOBJ_iXlate(&exlo
.xlo
, crColor
);
123 pebo
->BrushObject
.iSolidColor
= iSolidColor
;
125 /* Clean up the XLATEOBJ */
126 EXLATEOBJ_vCleanup(&exlo
);
131 EBRUSHOBJ_vCleanup(EBRUSHOBJ
*pebo
)
133 /* Check if there's a GDI realisation */
136 /* Unlock the bitmap again */
137 SURFACE_ShareUnlockSurface(pebo
->pengbrush
);
138 pebo
->pengbrush
= NULL
;
141 /* Check if there's a driver's realisation */
142 if (pebo
->BrushObject
.pvRbrush
)
144 /* Free allocated driver memory */
145 EngFreeMem(pebo
->BrushObject
.pvRbrush
);
146 pebo
->BrushObject
.pvRbrush
= NULL
;
149 /* Dereference the palettes */
150 PALETTE_ShareUnlockPalette(pebo
->ppalSurf
);
151 PALETTE_ShareUnlockPalette(pebo
->ppalDC
);
152 if (pebo
->ppalDIB
) PALETTE_ShareUnlockPalette(pebo
->ppalDIB
);
157 EBRUSHOBJ_vUpdate(EBRUSHOBJ
*pebo
, PBRUSH pbrush
, PDC pdc
)
159 /* Cleanup the brush */
160 EBRUSHOBJ_vCleanup(pebo
);
163 EBRUSHOBJ_vInit(pebo
, pbrush
, pdc
);
167 * This function is not exported, because it makes no sense for
168 * The driver to punt back to this function */
182 PSURFACE psurfRealize
;
183 POINTL ptlSrc
= {0, 0};
187 /* Calculate width in bytes of the realized brush */
188 lWidth
= WIDTH_BYTES_ALIGN32(psoPattern
->sizlBitmap
.cx
,
189 BitsPerFormat(psoDst
->iBitmapFormat
));
191 /* Allocate a bitmap */
192 hbmpRealize
= EngCreateBitmap(psoPattern
->sizlBitmap
,
194 psoDst
->iBitmapFormat
,
202 /* Lock the bitmap */
203 psurfRealize
= SURFACE_ShareLockSurface(hbmpRealize
);
205 /* Already delete the pattern bitmap (will be kept until dereferenced) */
206 EngDeleteSurface((HSURF
)hbmpRealize
);
213 /* Copy the bits to the new format bitmap */
214 rclDest
.left
= rclDest
.top
= 0;
215 rclDest
.right
= psoPattern
->sizlBitmap
.cx
;
216 rclDest
.bottom
= psoPattern
->sizlBitmap
.cy
;
217 psoRealize
= &psurfRealize
->SurfObj
;
218 EngCopyBits(psoRealize
, psoPattern
, NULL
, pxlo
, &rclDest
, &ptlSrc
);
221 pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
222 pebo
->pengbrush
= (PVOID
)psurfRealize
;
229 FixupDIBBrushPalette(
230 _In_ PPALETTE ppalDIB
,
231 _In_ PPALETTE ppalDC
)
234 ULONG i
, iPalIndex
, crColor
;
236 /* Allocate a new palette */
237 ppalNew
= PALETTE_AllocPalette(PAL_INDEXED
,
244 /* Loop all colors */
245 for (i
= 0; i
< ppalDIB
->NumColors
; i
++)
247 /* Get the RGB color, which is the index into the DC palette */
248 iPalIndex
= PALETTE_ulGetRGBColorFromIndex(ppalDIB
, i
);
250 /* Roll over when index is too big */
251 iPalIndex
%= ppalDC
->NumColors
;
253 /* Set the indexed DC color as the new color */
254 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, iPalIndex
);
255 PALETTE_vSetRGBColorForIndex(ppalNew
, i
, crColor
);
258 /* Return the new palette */
264 EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ
*pebo
, BOOL bCallDriver
)
267 PFN_DrvRealizeBrush pfnRealzizeBrush
= NULL
;
268 PSURFACE psurfPattern
, psurfMask
;
271 PPALETTE ppalPattern
;
272 PBRUSH pbr
= pebo
->pbrush
;
276 /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
277 ASSERT(pebo
->psurfTrg
);
279 ppdev
= (PPDEVOBJ
)pebo
->psurfTrg
->SurfObj
.hdev
;
280 if (!ppdev
) ppdev
= gppdevPrimary
;
283 pfnRealzizeBrush
= ppdev
->DriverFunctions
.RealizeBrush
;
285 if (!pfnRealzizeBrush
)
286 pfnRealzizeBrush
= EngRealizeBrush
;
288 /* Check if this is a hatch brush */
289 if (pbr
->flAttrs
& BR_IS_HATCH
)
291 /* Get the hatch brush pattern from the PDEV */
292 hbmPattern
= (HBITMAP
)ppdev
->ahsurf
[pbr
->ulStyle
];
293 iHatch
= pbr
->ulStyle
;
297 /* Use the brushes pattern */
298 hbmPattern
= pbr
->hbmPattern
;
302 psurfPattern
= SURFACE_ShareLockSurface(hbmPattern
);
303 ASSERT(psurfPattern
);
304 ASSERT(psurfPattern
->ppal
);
306 /* FIXME: implement mask */
309 /* DIB brushes with DIB_PAL_COLORS usage need a new palette */
310 if (pbr
->flAttrs
& BR_IS_DIBPALCOLORS
)
313 ppalPattern
= FixupDIBBrushPalette(psurfPattern
->ppal
, pebo
->ppalDC
);
314 pebo
->ppalDIB
= ppalPattern
;
318 /* The palette is already as it should be */
319 ppalPattern
= psurfPattern
->ppal
;
322 /* Initialize XLATEOBJ for the brush */
323 EXLATEOBJ_vInitialize(&exlo
,
325 pebo
->psurfTrg
->ppal
,
328 pebo
->crCurrentText
);
330 /* Create the realization */
331 bResult
= pfnRealzizeBrush(&pebo
->BrushObject
,
332 &pebo
->psurfTrg
->SurfObj
,
333 &psurfPattern
->SurfObj
,
334 psurfMask
? &psurfMask
->SurfObj
: NULL
,
338 /* Cleanup the XLATEOBJ */
339 EXLATEOBJ_vCleanup(&exlo
);
341 /* Unlock surfaces */
343 SURFACE_ShareUnlockSurface(psurfPattern
);
345 SURFACE_ShareUnlockSurface(psurfMask
);
352 EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ
*pebo
)
356 if (!pebo
->pengbrush
)
358 bResult
= EBRUSHOBJ_bRealizeBrush(pebo
, FALSE
);
362 EngDeleteSurface(pebo
->pengbrush
);
363 pebo
->pengbrush
= NULL
;
367 return pebo
->pengbrush
;
372 EBRUSHOBJ_psoPattern(EBRUSHOBJ
*pebo
)
374 PSURFACE psurfPattern
;
376 psurfPattern
= EBRUSHOBJ_pvGetEngBrush(pebo
);
378 return psurfPattern
? &psurfPattern
->SurfObj
: NULL
;
382 /** Exported DDI functions ****************************************************/
388 BRUSHOBJ_pvAllocRbrush(
392 pbo
->pvRbrush
= EngAllocMem(0, cj
, GDITAG_RBRUSH
);
393 return pbo
->pvRbrush
;
400 BRUSHOBJ_pvGetRbrush(
403 EBRUSHOBJ
*pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
408 bResult
= EBRUSHOBJ_bRealizeBrush(pebo
, TRUE
);
413 EngFreeMem(pbo
->pvRbrush
);
414 pbo
->pvRbrush
= NULL
;
419 return pbo
->pvRbrush
;
426 BRUSHOBJ_ulGetBrushColor(
429 EBRUSHOBJ
*pebo
= CONTAINING_RECORD(pbo
, EBRUSHOBJ
, BrushObject
);
430 return pebo
->ulRGBColor
;