4 * Copyright 1993, 1994 Alexandre Julliard
7 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
17 #define NB_HATCH_STYLES 6
19 static const char HatchBrushes
[NB_HATCH_STYLES
][8] =
21 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HS_HORIZONTAL */
22 { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HS_VERTICAL */
23 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HS_FDIAGONAL */
24 { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HS_BDIAGONAL */
25 { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HS_CROSS */
26 { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 } /* HS_DIAGCROSS */
29 /* Levels of each primary for dithering */
30 #define PRIMARY_LEVELS 3
31 #define TOTAL_LEVELS (PRIMARY_LEVELS*PRIMARY_LEVELS*PRIMARY_LEVELS)
33 /* Dithering matrix size */
35 #define MATRIX_SIZE_2 (MATRIX_SIZE*MATRIX_SIZE)
37 /* Total number of possible levels for a dithered primary color */
38 #define DITHER_LEVELS (MATRIX_SIZE_2 * (PRIMARY_LEVELS-1) + 1)
40 /* Dithering matrix */
41 static const int dither_matrix
[MATRIX_SIZE_2
] =
43 0, 32, 8, 40, 2, 34, 10, 42,
44 48, 16, 56, 24, 50, 18, 58, 26,
45 12, 44, 4, 36, 14, 46, 6, 38,
46 60, 28, 52, 20, 62, 30, 54, 22,
47 3, 35, 11, 43, 1, 33, 9, 41,
48 51, 19, 59, 27, 49, 17, 57, 25,
49 15, 47, 7, 39, 13, 45, 5, 37,
50 63, 31, 55, 23, 61, 29, 53, 21
53 /* Mapping between (R,G,B) triples and EGA colors */
54 static const int EGAmapping
[TOTAL_LEVELS
] =
56 0, /* 000000 -> 000000 */
57 4, /* 00007f -> 000080 */
58 12, /* 0000ff -> 0000ff */
59 2, /* 007f00 -> 008000 */
60 6, /* 007f7f -> 008080 */
61 6, /* 007fff -> 008080 */
62 10, /* 00ff00 -> 00ff00 */
63 6, /* 00ff7f -> 008080 */
64 14, /* 00ffff -> 00ffff */
65 1, /* 7f0000 -> 800000 */
66 5, /* 7f007f -> 800080 */
67 5, /* 7f00ff -> 800080 */
68 3, /* 7f7f00 -> 808000 */
69 8, /* 7f7f7f -> 808080 */
70 7, /* 7f7fff -> c0c0c0 */
71 3, /* 7fff00 -> 808000 */
72 7, /* 7fff7f -> c0c0c0 */
73 7, /* 7fffff -> c0c0c0 */
74 9, /* ff0000 -> ff0000 */
75 5, /* ff007f -> 800080 */
76 13, /* ff00ff -> ff00ff */
77 3, /* ff7f00 -> 808000 */
78 7, /* ff7f7f -> c0c0c0 */
79 7, /* ff7fff -> c0c0c0 */
80 11, /* ffff00 -> ffff00 */
81 7, /* ffff7f -> c0c0c0 */
82 15 /* ffffff -> ffffff */
85 #define PIXEL_VALUE(r,g,b) \
86 COLOR_mapEGAPixel[EGAmapping[((r)*PRIMARY_LEVELS+(g))*PRIMARY_LEVELS+(b)]]
88 /* X image for building dithered pixmap */
89 static XImage
*ditherImage
= NULL
;
92 /***********************************************************************
95 * Create the X image used for dithering.
97 BOOL32
BRUSH_Init(void)
99 XCREATEIMAGE( ditherImage
, MATRIX_SIZE
, MATRIX_SIZE
, screenDepth
);
100 return (ditherImage
!= NULL
);
104 /***********************************************************************
107 Pixmap
BRUSH_DitherColor( DC
*dc
, COLORREF color
)
109 static COLORREF prevColor
= 0xffffffff;
113 if (color
!= prevColor
)
115 int r
= GetRValue( color
) * DITHER_LEVELS
;
116 int g
= GetGValue( color
) * DITHER_LEVELS
;
117 int b
= GetBValue( color
) * DITHER_LEVELS
;
118 const int *pmatrix
= dither_matrix
;
120 for (y
= 0; y
< MATRIX_SIZE
; y
++)
122 for (x
= 0; x
< MATRIX_SIZE
; x
++)
124 int d
= *pmatrix
++ * 256;
125 int dr
= ((r
+ d
) / MATRIX_SIZE_2
) / 256;
126 int dg
= ((g
+ d
) / MATRIX_SIZE_2
) / 256;
127 int db
= ((b
+ d
) / MATRIX_SIZE_2
) / 256;
128 XPutPixel( ditherImage
, x
, y
, PIXEL_VALUE(dr
,dg
,db
) );
134 pixmap
= XCreatePixmap( display
, rootWindow
,
135 MATRIX_SIZE
, MATRIX_SIZE
, screenDepth
);
136 XPutImage( display
, pixmap
, BITMAP_colorGC
, ditherImage
, 0, 0,
137 0, 0, MATRIX_SIZE
, MATRIX_SIZE
);
142 /***********************************************************************
143 * CreateBrushIndirect16 (GDI.50)
145 HBRUSH16
CreateBrushIndirect16( const LOGBRUSH16
* brush
)
148 HBRUSH16 hbrush
= GDI_AllocObject( sizeof(BRUSHOBJ
), BRUSH_MAGIC
);
149 if (!hbrush
) return 0;
150 brushPtr
= (BRUSHOBJ
*) GDI_HEAP_LIN_ADDR( hbrush
);
151 brushPtr
->logbrush
.lbStyle
= brush
->lbStyle
;
152 brushPtr
->logbrush
.lbColor
= brush
->lbColor
;
153 brushPtr
->logbrush
.lbHatch
= brush
->lbHatch
;
158 /***********************************************************************
159 * CreateBrushIndirect32 (GDI32.27)
161 HBRUSH32
CreateBrushIndirect32( const LOGBRUSH32
* brush
)
164 HBRUSH32 hbrush
= GDI_AllocObject( sizeof(BRUSHOBJ
), BRUSH_MAGIC
);
165 if (!hbrush
) return 0;
166 brushPtr
= (BRUSHOBJ
*) GDI_HEAP_LIN_ADDR( hbrush
);
167 brushPtr
->logbrush
.lbStyle
= brush
->lbStyle
;
168 brushPtr
->logbrush
.lbColor
= brush
->lbColor
;
169 brushPtr
->logbrush
.lbHatch
= brush
->lbHatch
;
174 /***********************************************************************
175 * CreateHatchBrush16 (GDI.58)
177 HBRUSH16
CreateHatchBrush16( INT16 style
, COLORREF color
)
179 LOGBRUSH32 logbrush
= { BS_HATCHED
, color
, style
};
180 dprintf_gdi(stddeb
, "CreateHatchBrush16: %d %06lx\n", style
, color
);
181 if ((style
< 0) || (style
>= NB_HATCH_STYLES
)) return 0;
182 return CreateBrushIndirect32( &logbrush
);
186 /***********************************************************************
187 * CreateHatchBrush32 (GDI32.48)
189 HBRUSH32
CreateHatchBrush32( INT32 style
, COLORREF color
)
191 LOGBRUSH32 logbrush
= { BS_HATCHED
, color
, style
};
192 dprintf_gdi(stddeb
, "CreateHatchBrush32: %d %06lx\n", style
, color
);
193 if ((style
< 0) || (style
>= NB_HATCH_STYLES
)) return 0;
194 return CreateBrushIndirect32( &logbrush
);
198 /***********************************************************************
199 * CreatePatternBrush16 (GDI.60)
201 HBRUSH16
CreatePatternBrush16( HBITMAP16 hbitmap
)
203 return (HBRUSH16
)CreatePatternBrush32( hbitmap
);
207 /***********************************************************************
208 * CreatePatternBrush32 (GDI32.54)
210 HBRUSH32
CreatePatternBrush32( HBITMAP32 hbitmap
)
212 LOGBRUSH32 logbrush
= { BS_PATTERN
, 0, 0 };
213 BITMAPOBJ
*bmp
, *newbmp
;
215 dprintf_gdi(stddeb
, "CreatePatternBrush: %04x\n", hbitmap
);
217 /* Make a copy of the bitmap */
219 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
)))
221 logbrush
.lbHatch
= (INT32
)CreateBitmapIndirect16( &bmp
->bitmap
);
222 newbmp
= (BITMAPOBJ
*) GDI_GetObjPtr( (HGDIOBJ32
)logbrush
.lbHatch
,
224 if (!newbmp
) return 0;
225 XCopyArea( display
, bmp
->pixmap
, newbmp
->pixmap
, BITMAP_GC(bmp
),
226 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
, 0, 0 );
227 return CreateBrushIndirect32( &logbrush
);
231 /***********************************************************************
232 * CreateDIBPatternBrush16 (GDI.445)
234 HBRUSH16
CreateDIBPatternBrush16( HGLOBAL16 hbitmap
, UINT16 coloruse
)
236 LOGBRUSH32 logbrush
= { BS_DIBPATTERN
, coloruse
, 0 };
237 BITMAPINFO
*info
, *newInfo
;
240 dprintf_gdi(stddeb
, "CreateDIBPatternBrush: %04x\n", hbitmap
);
242 /* Make a copy of the bitmap */
244 if (!(info
= (BITMAPINFO
*)GlobalLock16( hbitmap
))) return 0;
246 if (info
->bmiHeader
.biCompression
)
247 size
= info
->bmiHeader
.biSizeImage
;
249 size
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
+ 31) / 32
250 * 8 * info
->bmiHeader
.biHeight
;
251 size
+= DIB_BitmapInfoSize( info
, coloruse
);
253 if (!(logbrush
.lbHatch
= (INT16
)GlobalAlloc16( GMEM_MOVEABLE
, size
)))
255 GlobalUnlock16( hbitmap
);
258 newInfo
= (BITMAPINFO
*) GlobalLock16( (HGLOBAL16
)logbrush
.lbHatch
);
259 memcpy( newInfo
, info
, size
);
260 GlobalUnlock16( (HGLOBAL16
)logbrush
.lbHatch
);
261 GlobalUnlock16( hbitmap
);
262 return CreateBrushIndirect32( &logbrush
);
266 /***********************************************************************
267 * CreateDIBPatternBrush32 (GDI32.34)
269 HBRUSH32
CreateDIBPatternBrush32( HGLOBAL32 hbitmap
, UINT32 coloruse
)
271 LOGBRUSH32 logbrush
= { BS_DIBPATTERN
, coloruse
, 0 };
272 BITMAPINFO
*info
, *newInfo
;
275 dprintf_gdi(stddeb
, "CreateDIBPatternBrush: %04x\n", hbitmap
);
277 /* Make a copy of the bitmap */
279 if (!(info
= (BITMAPINFO
*)GlobalLock32( hbitmap
))) return 0;
281 if (info
->bmiHeader
.biCompression
)
282 size
= info
->bmiHeader
.biSizeImage
;
284 size
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
+ 31) / 32
285 * 8 * info
->bmiHeader
.biHeight
;
286 size
+= DIB_BitmapInfoSize( info
, coloruse
);
288 if (!(logbrush
.lbHatch
= (INT32
)GlobalAlloc16( GMEM_MOVEABLE
, size
)))
290 GlobalUnlock16( hbitmap
);
293 newInfo
= (BITMAPINFO
*) GlobalLock16( (HGLOBAL16
)logbrush
.lbHatch
);
294 memcpy( newInfo
, info
, size
);
295 GlobalUnlock16( (HGLOBAL16
)logbrush
.lbHatch
);
296 GlobalUnlock16( hbitmap
);
297 return CreateBrushIndirect32( &logbrush
);
301 /***********************************************************************
302 * CreateSolidBrush (GDI.66)
304 HBRUSH16
CreateSolidBrush16( COLORREF color
)
306 LOGBRUSH32 logbrush
= { BS_SOLID
, color
, 0 };
307 dprintf_gdi(stddeb
, "CreateSolidBrush16: %06lx\n", color
);
308 return CreateBrushIndirect32( &logbrush
);
312 /***********************************************************************
313 * CreateSolidBrush32 (GDI32.64)
315 HBRUSH32
CreateSolidBrush32( COLORREF color
)
317 LOGBRUSH32 logbrush
= { BS_SOLID
, color
, 0 };
318 dprintf_gdi(stddeb
, "CreateSolidBrush32: %06lx\n", color
);
319 return CreateBrushIndirect32( &logbrush
);
323 /***********************************************************************
324 * SetBrushOrg (GDI.148)
326 DWORD
SetBrushOrg( HDC16 hdc
, INT16 x
, INT16 y
)
329 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
330 if (!dc
) return FALSE
;
331 retval
= dc
->w
.brushOrgX
| (dc
->w
.brushOrgY
<< 16);
338 /***********************************************************************
339 * SetBrushOrgEx (GDI32.308)
341 BOOL32
SetBrushOrgEx( HDC32 hdc
, INT32 x
, INT32 y
, LPPOINT32 oldorg
)
343 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
345 if (!dc
) return FALSE
;
348 oldorg
->x
= dc
->w
.brushOrgX
;
349 oldorg
->y
= dc
->w
.brushOrgY
;
357 /***********************************************************************
358 * GetSysColorBrush16 (USER.281)
360 HBRUSH16
GetSysColorBrush16( INT16 index
)
362 fprintf( stderr
, "Unimplemented stub: GetSysColorBrush16(%d)\n", index
);
363 return GetStockObject32(LTGRAY_BRUSH
);
367 /***********************************************************************
368 * GetSysColorBrush32 (USER32.289)
370 HBRUSH32
GetSysColorBrush32( INT32 index
)
372 fprintf( stderr
, "Unimplemented stub: GetSysColorBrush32(%d)\n", index
);
373 return GetStockObject32(LTGRAY_BRUSH
);
377 /***********************************************************************
380 BOOL32
BRUSH_DeleteObject( HBRUSH16 hbrush
, BRUSHOBJ
* brush
)
382 switch(brush
->logbrush
.lbStyle
)
385 DeleteObject32( (HGDIOBJ32
)brush
->logbrush
.lbHatch
);
388 GlobalFree16( (HGLOBAL16
)brush
->logbrush
.lbHatch
);
391 return GDI_FreeObject( hbrush
);
395 /***********************************************************************
398 INT16
BRUSH_GetObject16( BRUSHOBJ
* brush
, INT16 count
, LPSTR buffer
)
402 logbrush
.lbStyle
= brush
->logbrush
.lbStyle
;
403 logbrush
.lbColor
= brush
->logbrush
.lbColor
;
404 logbrush
.lbHatch
= brush
->logbrush
.lbHatch
;
405 if (count
> sizeof(logbrush
)) count
= sizeof(logbrush
);
406 memcpy( buffer
, &logbrush
, count
);
411 /***********************************************************************
414 INT32
BRUSH_GetObject32( BRUSHOBJ
* brush
, INT32 count
, LPSTR buffer
)
416 if (count
> sizeof(brush
->logbrush
)) count
= sizeof(brush
->logbrush
);
417 memcpy( buffer
, &brush
->logbrush
, count
);
422 /***********************************************************************
423 * BRUSH_SelectSolidBrush
425 static void BRUSH_SelectSolidBrush( DC
*dc
, COLORREF color
)
427 if ((dc
->w
.bitsPerPixel
> 1) && (screenDepth
<= 8) && !COLOR_IsSolid( color
))
430 dc
->u
.x
.brush
.pixmap
= BRUSH_DitherColor( dc
, color
);
431 dc
->u
.x
.brush
.fillStyle
= FillTiled
;
432 dc
->u
.x
.brush
.pixel
= 0;
437 dc
->u
.x
.brush
.pixel
= COLOR_ToPhysical( dc
, color
);
438 dc
->u
.x
.brush
.fillStyle
= FillSolid
;
443 /***********************************************************************
444 * BRUSH_SelectPatternBrush
446 static BOOL32
BRUSH_SelectPatternBrush( DC
* dc
, HBITMAP32 hbitmap
)
448 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
449 if (!bmp
) return FALSE
;
450 dc
->u
.x
.brush
.pixmap
= XCreatePixmap( display
, rootWindow
,
451 8, 8, bmp
->bitmap
.bmBitsPixel
);
452 XCopyArea( display
, bmp
->pixmap
, dc
->u
.x
.brush
.pixmap
,
453 BITMAP_GC(bmp
), 0, 0, 8, 8, 0, 0 );
455 if (bmp
->bitmap
.bmBitsPixel
> 1)
457 dc
->u
.x
.brush
.fillStyle
= FillTiled
;
458 dc
->u
.x
.brush
.pixel
= 0; /* Ignored */
462 dc
->u
.x
.brush
.fillStyle
= FillOpaqueStippled
;
463 dc
->u
.x
.brush
.pixel
= -1; /* Special case (see DC_SetupGCForBrush) */
470 /***********************************************************************
473 HBRUSH32
BRUSH_SelectObject( DC
* dc
, HBRUSH32 hbrush
, BRUSHOBJ
* brush
)
476 BITMAPINFO
* bmpInfo
;
477 HBRUSH16 prevHandle
= dc
->w
.hBrush
;
479 dprintf_gdi(stddeb
, "Brush_SelectObject: hdc=%04x hbrush=%04x\n",
481 if (dc
->header
.wMagic
== METAFILE_DC_MAGIC
)
483 LOGBRUSH16 logbrush
= { brush
->logbrush
.lbStyle
,
484 brush
->logbrush
.lbColor
,
485 brush
->logbrush
.lbHatch
};
486 switch (brush
->logbrush
.lbStyle
)
491 if (!MF_CreateBrushIndirect( dc
, hbrush
, &logbrush
)) return 0;
495 if (!MF_CreatePatternBrush( dc
, hbrush
, &logbrush
)) return 0;
498 return 1; /* FIXME? */
501 dc
->w
.hBrush
= hbrush
;
503 if (dc
->u
.x
.brush
.pixmap
)
505 XFreePixmap( display
, dc
->u
.x
.brush
.pixmap
);
506 dc
->u
.x
.brush
.pixmap
= 0;
508 dc
->u
.x
.brush
.style
= brush
->logbrush
.lbStyle
;
510 switch(brush
->logbrush
.lbStyle
)
513 dprintf_gdi( stddeb
,"BS_NULL\n" );
517 dprintf_gdi( stddeb
,"BS_SOLID\n" );
518 BRUSH_SelectSolidBrush( dc
, brush
->logbrush
.lbColor
);
522 dprintf_gdi( stddeb
, "BS_HATCHED\n" );
523 dc
->u
.x
.brush
.pixel
= COLOR_ToPhysical( dc
, brush
->logbrush
.lbColor
);
524 dc
->u
.x
.brush
.pixmap
= XCreateBitmapFromData( display
, rootWindow
,
525 HatchBrushes
[brush
->logbrush
.lbHatch
], 8, 8 );
526 dc
->u
.x
.brush
.fillStyle
= FillStippled
;
530 dprintf_gdi( stddeb
, "BS_PATTERN\n");
531 BRUSH_SelectPatternBrush( dc
, (HBRUSH16
)brush
->logbrush
.lbHatch
);
535 dprintf_gdi( stddeb
, "BS_DIBPATTERN\n");
536 if ((bmpInfo
= (BITMAPINFO
*) GlobalLock16( (HGLOBAL16
)brush
->logbrush
.lbHatch
)))
538 int size
= DIB_BitmapInfoSize( bmpInfo
, brush
->logbrush
.lbColor
);
539 hBitmap
= CreateDIBitmap32( dc
->hSelf
, &bmpInfo
->bmiHeader
,
540 CBM_INIT
, ((char *)bmpInfo
) + size
,
542 (WORD
)brush
->logbrush
.lbColor
);
543 BRUSH_SelectPatternBrush( dc
, hBitmap
);
544 DeleteObject16( hBitmap
);
545 GlobalUnlock16( (HGLOBAL16
)brush
->logbrush
.lbHatch
);