Reimplemented DXGrab with improvements; it no longer depends on
[wine] / dlls / wineps / brush.c
1 /*
2  *      PostScript brush handling
3  *
4  * Copyright 1998  Huw D M Davies
5  *
6  */
7
8 #include "psdrv.h"
9 #include "brush.h"
10 #include "debugtools.h"
11 #include "gdi.h"
12 #include "winbase.h"
13
14 DEFAULT_DEBUG_CHANNEL(psdrv);
15
16 /***********************************************************************
17  *           PSDRV_BRUSH_SelectObject
18  */
19 HBRUSH PSDRV_BRUSH_SelectObject( DC * dc, HBRUSH hbrush, BRUSHOBJ * brush )
20 {
21     HBRUSH prevbrush = dc->hBrush;
22     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
23
24     TRACE("hbrush = %08x\n", hbrush);
25     dc->hBrush = hbrush;
26
27     switch(brush->logbrush.lbStyle) {
28
29     case BS_SOLID:
30         PSDRV_CreateColor(physDev, &physDev->brush.color, 
31                           brush->logbrush.lbColor);
32         break;
33
34     case BS_NULL:
35         break;
36
37     case BS_HATCHED:
38         PSDRV_CreateColor(physDev, &physDev->brush.color, 
39                           brush->logbrush.lbColor);
40         break;
41
42     case BS_PATTERN:
43         FIXME("Unsupported brush style %d\n", brush->logbrush.lbStyle);
44         break;
45
46     default:
47         FIXME("Unrecognized brush style %d\n", brush->logbrush.lbStyle);
48         break;
49     }
50
51     physDev->brush.set = FALSE;
52     return prevbrush;
53 }
54
55
56 /**********************************************************************
57  *
58  *      PSDRV_SetBrush
59  *
60  */
61 static BOOL PSDRV_SetBrush(DC *dc)
62 {
63     BOOL ret = TRUE;
64     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
65     BRUSHOBJ *brush = (BRUSHOBJ *)GDI_GetObjPtr( dc->hBrush, BRUSH_MAGIC );
66
67     if(!brush) {
68         ERR("Can't get BRUSHOBJ\n");
69         return FALSE;
70     }
71     
72     switch (brush->logbrush.lbStyle) {
73     case BS_SOLID:
74     case BS_HATCHED:
75         PSDRV_WriteSetColor(dc, &physDev->brush.color);
76         break;
77
78     case BS_NULL:
79         break;
80
81     default:
82         ret = FALSE;
83         break;
84
85     }
86     physDev->brush.set = TRUE;
87     GDI_ReleaseObj( dc->hBrush );
88     return TRUE;
89 }
90
91
92 /**********************************************************************
93  *
94  *      PSDRV_Fill
95  *
96  */
97 static BOOL PSDRV_Fill(DC *dc, BOOL EO)
98 {
99     if(!EO)
100         return PSDRV_WriteFill(dc);
101     else
102       return PSDRV_WriteEOFill(dc);
103 }
104
105
106 /**********************************************************************
107  *
108  *      PSDRV_Clip
109  *
110  */
111 static BOOL PSDRV_Clip(DC *dc, BOOL EO)
112 {
113     if(!EO)
114         return PSDRV_WriteClip(dc);
115     else
116         return PSDRV_WriteEOClip(dc);
117 }
118
119 /**********************************************************************
120  *
121  *      PSDRV_Brush
122  *
123  */
124 BOOL PSDRV_Brush(DC *dc, BOOL EO)
125 {
126     BOOL ret = TRUE;
127     BRUSHOBJ *brush = (BRUSHOBJ *)GDI_GetObjPtr( dc->hBrush, BRUSH_MAGIC );
128     PSDRV_PDEVICE *physDev = dc->physDev;
129
130     if(!brush) {
131         ERR("Can't get BRUSHOBJ\n");
132         return FALSE;
133     }
134
135     switch (brush->logbrush.lbStyle) {
136     case BS_SOLID:
137         PSDRV_SetBrush(dc);
138         PSDRV_WriteGSave(dc);
139         PSDRV_Fill(dc, EO);
140         PSDRV_WriteGRestore(dc);
141         break;
142
143     case BS_HATCHED:
144         PSDRV_SetBrush(dc);
145
146         switch(brush->logbrush.lbHatch) {
147         case HS_VERTICAL:
148         case HS_CROSS:
149             PSDRV_WriteGSave(dc);
150             PSDRV_Clip(dc, EO);
151             PSDRV_WriteHatch(dc);
152             PSDRV_WriteStroke(dc);
153             PSDRV_WriteGRestore(dc);
154             if(brush->logbrush.lbHatch == HS_VERTICAL)
155                 break;
156             /* else fallthrough for HS_CROSS */
157
158         case HS_HORIZONTAL:
159             PSDRV_WriteGSave(dc);
160             PSDRV_Clip(dc, EO);
161             PSDRV_WriteRotate(dc, 90.0);
162             PSDRV_WriteHatch(dc);
163             PSDRV_WriteStroke(dc);
164             PSDRV_WriteGRestore(dc);
165             break;
166
167         case HS_FDIAGONAL:
168         case HS_DIAGCROSS:
169             PSDRV_WriteGSave(dc);
170             PSDRV_Clip(dc, EO);
171             PSDRV_WriteRotate(dc, -45.0);
172             PSDRV_WriteHatch(dc);
173             PSDRV_WriteStroke(dc);
174             PSDRV_WriteGRestore(dc);
175             if(brush->logbrush.lbHatch == HS_FDIAGONAL)
176                 break;
177             /* else fallthrough for HS_DIAGCROSS */
178             
179         case HS_BDIAGONAL:
180             PSDRV_WriteGSave(dc);
181             PSDRV_Clip(dc, EO);
182             PSDRV_WriteRotate(dc, 45.0);
183             PSDRV_WriteHatch(dc);
184             PSDRV_WriteStroke(dc);
185             PSDRV_WriteGRestore(dc);
186             break;
187
188         default:
189             ERR("Unknown hatch style\n");
190             ret = FALSE;
191             break;
192         }
193         break;
194
195     case BS_NULL:
196         break;
197
198     case BS_PATTERN:
199         {
200             BITMAP bm;
201             BYTE *bits;
202             GetObjectA(brush->logbrush.lbHatch, sizeof(BITMAP), &bm);
203             TRACE("BS_PATTERN %dx%d %d bpp\n", bm.bmWidth, bm.bmHeight,
204                   bm.bmBitsPixel);
205             bits = HeapAlloc(PSDRV_Heap, 0, bm.bmWidthBytes * bm.bmHeight);
206             GetBitmapBits(brush->logbrush.lbHatch,
207                           bm.bmWidthBytes * bm.bmHeight, bits);
208
209             if(physDev->pi->ppd->LanguageLevel > 1) {
210                 PSDRV_WriteGSave(dc);
211                 PSDRV_WritePatternDict(dc, &bm, bits);
212                 PSDRV_Fill(dc, EO);
213                 PSDRV_WriteGRestore(dc);
214             } else {
215                 FIXME("Trying to set a pattern brush on a level 1 printer\n");
216                 ret = FALSE;
217             }
218             HeapFree(PSDRV_Heap, 0, bits);      
219         }
220         break;
221
222     default:
223         ret = FALSE;
224         break;
225     }
226
227     GDI_ReleaseObj( dc->hBrush );
228     return ret;
229 }
230
231
232
233