gdi32: Pass a brush_pattern structure to the SelectBrush entry point.
[wine] / dlls / wineps.drv / brush.c
1 /*
2  *      PostScript brush handling
3  *
4  * Copyright 1998  Huw D M Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "psdrv.h"
22 #include "wine/debug.h"
23 #include "winbase.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
26
27 /***********************************************************************
28  *           SelectBrush   (WINEPS.@)
29  */
30 HBRUSH PSDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern )
31 {
32     PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
33     LOGBRUSH logbrush;
34
35     if (!GetObjectA( hbrush, sizeof(logbrush), &logbrush )) return 0;
36
37     TRACE("hbrush = %p\n", hbrush);
38
39     if (hbrush == GetStockObject( DC_BRUSH ))
40         logbrush.lbColor = GetDCBrushColor( dev->hdc );
41
42     switch(logbrush.lbStyle) {
43
44     case BS_SOLID:
45         PSDRV_CreateColor(dev, &physDev->brush.color, logbrush.lbColor);
46         break;
47
48     case BS_NULL:
49         break;
50
51     case BS_HATCHED:
52         PSDRV_CreateColor(dev, &physDev->brush.color, logbrush.lbColor);
53         break;
54
55     case BS_PATTERN:
56     case BS_DIBPATTERN:
57         physDev->brush.pattern = *pattern;
58         break;
59
60     default:
61         FIXME("Unrecognized brush style %d\n", logbrush.lbStyle);
62         break;
63     }
64
65     physDev->brush.set = FALSE;
66     return hbrush;
67 }
68
69
70 /***********************************************************************
71  *           SetDCBrushColor (WINEPS.@)
72  */
73 COLORREF PSDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
74 {
75     PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
76
77     if (GetCurrentObject( dev->hdc, OBJ_BRUSH ) == GetStockObject( DC_BRUSH ))
78     {
79         PSDRV_CreateColor( dev, &physDev->brush.color, color );
80         physDev->brush.set = FALSE;
81     }
82     return color;
83 }
84
85
86 /**********************************************************************
87  *
88  *      PSDRV_SetBrush
89  *
90  */
91 static BOOL PSDRV_SetBrush( PHYSDEV dev )
92 {
93     PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
94     LOGBRUSH logbrush;
95     BOOL ret = TRUE;
96
97     if (!GetObjectA( GetCurrentObject(dev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
98     {
99         ERR("Can't get BRUSHOBJ\n");
100         return FALSE;
101     }
102
103     switch (logbrush.lbStyle) {
104     case BS_SOLID:
105     case BS_HATCHED:
106         PSDRV_WriteSetColor(dev, &physDev->brush.color);
107         break;
108
109     case BS_NULL:
110         break;
111
112     default:
113         ret = FALSE;
114         break;
115
116     }
117     physDev->brush.set = TRUE;
118     return ret;
119 }
120
121
122 /**********************************************************************
123  *
124  *      PSDRV_Fill
125  *
126  */
127 static BOOL PSDRV_Fill(PHYSDEV dev, BOOL EO)
128 {
129     if(!EO)
130         return PSDRV_WriteFill(dev);
131     else
132         return PSDRV_WriteEOFill(dev);
133 }
134
135
136 /**********************************************************************
137  *
138  *      PSDRV_Clip
139  *
140  */
141 static BOOL PSDRV_Clip(PHYSDEV dev, BOOL EO)
142 {
143     if(!EO)
144         return PSDRV_WriteClip(dev);
145     else
146         return PSDRV_WriteEOClip(dev);
147 }
148
149 /**********************************************************************
150  *
151  *      PSDRV_Brush
152  *
153  */
154 BOOL PSDRV_Brush(PHYSDEV dev, BOOL EO)
155 {
156     PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
157     LOGBRUSH logbrush;
158     BOOL ret = TRUE;
159
160     if(physDev->pathdepth)
161         return FALSE;
162
163     if (!GetObjectA( GetCurrentObject(dev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
164     {
165         ERR("Can't get BRUSHOBJ\n");
166         return FALSE;
167     }
168
169     switch (logbrush.lbStyle) {
170     case BS_SOLID:
171         PSDRV_WriteGSave(dev);
172         PSDRV_SetBrush(dev);
173         PSDRV_Fill(dev, EO);
174         PSDRV_WriteGRestore(dev);
175         break;
176
177     case BS_HATCHED:
178         PSDRV_WriteGSave(dev);
179         PSDRV_SetBrush(dev);
180
181         switch(logbrush.lbHatch) {
182         case HS_VERTICAL:
183         case HS_CROSS:
184             PSDRV_WriteGSave(dev);
185             PSDRV_Clip(dev, EO);
186             PSDRV_WriteHatch(dev);
187             PSDRV_WriteStroke(dev);
188             PSDRV_WriteGRestore(dev);
189             if(logbrush.lbHatch == HS_VERTICAL)
190                 break;
191             /* else fallthrough for HS_CROSS */
192
193         case HS_HORIZONTAL:
194             PSDRV_WriteGSave(dev);
195             PSDRV_Clip(dev, EO);
196             PSDRV_WriteRotate(dev, 90.0);
197             PSDRV_WriteHatch(dev);
198             PSDRV_WriteStroke(dev);
199             PSDRV_WriteGRestore(dev);
200             break;
201
202         case HS_FDIAGONAL:
203         case HS_DIAGCROSS:
204             PSDRV_WriteGSave(dev);
205             PSDRV_Clip(dev, EO);
206             PSDRV_WriteRotate(dev, -45.0);
207             PSDRV_WriteHatch(dev);
208             PSDRV_WriteStroke(dev);
209             PSDRV_WriteGRestore(dev);
210             if(logbrush.lbHatch == HS_FDIAGONAL)
211                 break;
212             /* else fallthrough for HS_DIAGCROSS */
213
214         case HS_BDIAGONAL:
215             PSDRV_WriteGSave(dev);
216             PSDRV_Clip(dev, EO);
217             PSDRV_WriteRotate(dev, 45.0);
218             PSDRV_WriteHatch(dev);
219             PSDRV_WriteStroke(dev);
220             PSDRV_WriteGRestore(dev);
221             break;
222
223         default:
224             ERR("Unknown hatch style\n");
225             ret = FALSE;
226             break;
227         }
228         PSDRV_WriteGRestore(dev);
229         break;
230
231     case BS_NULL:
232         break;
233
234     case BS_PATTERN:
235     case BS_DIBPATTERN:
236         if(physDev->pi->ppd->LanguageLevel > 1) {
237             PSDRV_WriteGSave(dev);
238             ret = PSDRV_WriteDIBPatternDict(dev, physDev->brush.pattern.info,
239                                             physDev->brush.pattern.bits.ptr, physDev->brush.pattern.usage );
240             PSDRV_Fill(dev, EO);
241             PSDRV_WriteGRestore(dev);
242         } else {
243             FIXME("Trying to set a pattern brush on a level 1 printer\n");
244             ret = FALSE;
245         }
246         break;
247
248     default:
249         ret = FALSE;
250         break;
251     }
252     return ret;
253 }