Fixed file handle leak.
[wine] / dlls / wineps / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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( PSDRV_PDEVICE *physDev, HBRUSH hbrush )
31 {
32     LOGBRUSH logbrush;
33
34     if (!GetObjectA( hbrush, sizeof(logbrush), &logbrush )) return 0;
35
36     TRACE("hbrush = %p\n", hbrush);
37
38     switch(logbrush.lbStyle) {
39
40     case BS_SOLID:
41         PSDRV_CreateColor(physDev, &physDev->brush.color, logbrush.lbColor);
42         break;
43
44     case BS_NULL:
45         break;
46
47     case BS_HATCHED:
48         PSDRV_CreateColor(physDev, &physDev->brush.color, logbrush.lbColor);
49         break;
50
51     case BS_PATTERN:
52     case BS_DIBPATTERN:
53         break;
54
55     default:
56         FIXME("Unrecognized brush style %d\n", logbrush.lbStyle);
57         break;
58     }
59
60     physDev->brush.set = FALSE;
61     return hbrush;
62 }
63
64
65 /**********************************************************************
66  *
67  *      PSDRV_SetBrush
68  *
69  */
70 static BOOL PSDRV_SetBrush(PSDRV_PDEVICE *physDev)
71 {
72     LOGBRUSH logbrush;
73     BOOL ret = TRUE;
74
75     if (!GetObjectA( GetCurrentObject(physDev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
76     {
77         ERR("Can't get BRUSHOBJ\n");
78         return FALSE;
79     }
80
81     switch (logbrush.lbStyle) {
82     case BS_SOLID:
83     case BS_HATCHED:
84         PSDRV_WriteSetColor(physDev, &physDev->brush.color);
85         break;
86
87     case BS_NULL:
88         break;
89
90     default:
91         ret = FALSE;
92         break;
93
94     }
95     physDev->brush.set = TRUE;
96     return TRUE;
97 }
98
99
100 /**********************************************************************
101  *
102  *      PSDRV_Fill
103  *
104  */
105 static BOOL PSDRV_Fill(PSDRV_PDEVICE *physDev, BOOL EO)
106 {
107     if(!EO)
108         return PSDRV_WriteFill(physDev);
109     else
110         return PSDRV_WriteEOFill(physDev);
111 }
112
113
114 /**********************************************************************
115  *
116  *      PSDRV_Clip
117  *
118  */
119 static BOOL PSDRV_Clip(PSDRV_PDEVICE *physDev, BOOL EO)
120 {
121     if(!EO)
122         return PSDRV_WriteClip(physDev);
123     else
124         return PSDRV_WriteEOClip(physDev);
125 }
126
127 /**********************************************************************
128  *
129  *      PSDRV_Brush
130  *
131  */
132 BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO)
133 {
134     LOGBRUSH logbrush;
135     BOOL ret = TRUE;
136
137     if(physDev->pathdepth)
138         return FALSE;
139
140     if (!GetObjectA( GetCurrentObject(physDev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
141     {
142         ERR("Can't get BRUSHOBJ\n");
143         return FALSE;
144     }
145
146     switch (logbrush.lbStyle) {
147     case BS_SOLID:
148         PSDRV_WriteGSave(physDev);
149         PSDRV_SetBrush(physDev);
150         PSDRV_Fill(physDev, EO);
151         PSDRV_WriteGRestore(physDev);
152         break;
153
154     case BS_HATCHED:
155         PSDRV_WriteGSave(physDev);
156         PSDRV_SetBrush(physDev);
157
158         switch(logbrush.lbHatch) {
159         case HS_VERTICAL:
160         case HS_CROSS:
161             PSDRV_WriteGSave(physDev);
162             PSDRV_Clip(physDev, EO);
163             PSDRV_WriteHatch(physDev);
164             PSDRV_WriteStroke(physDev);
165             PSDRV_WriteGRestore(physDev);
166             if(logbrush.lbHatch == HS_VERTICAL)
167                 break;
168             /* else fallthrough for HS_CROSS */
169
170         case HS_HORIZONTAL:
171             PSDRV_WriteGSave(physDev);
172             PSDRV_Clip(physDev, EO);
173             PSDRV_WriteRotate(physDev, 90.0);
174             PSDRV_WriteHatch(physDev);
175             PSDRV_WriteStroke(physDev);
176             PSDRV_WriteGRestore(physDev);
177             break;
178
179         case HS_FDIAGONAL:
180         case HS_DIAGCROSS:
181             PSDRV_WriteGSave(physDev);
182             PSDRV_Clip(physDev, EO);
183             PSDRV_WriteRotate(physDev, -45.0);
184             PSDRV_WriteHatch(physDev);
185             PSDRV_WriteStroke(physDev);
186             PSDRV_WriteGRestore(physDev);
187             if(logbrush.lbHatch == HS_FDIAGONAL)
188                 break;
189             /* else fallthrough for HS_DIAGCROSS */
190
191         case HS_BDIAGONAL:
192             PSDRV_WriteGSave(physDev);
193             PSDRV_Clip(physDev, EO);
194             PSDRV_WriteRotate(physDev, 45.0);
195             PSDRV_WriteHatch(physDev);
196             PSDRV_WriteStroke(physDev);
197             PSDRV_WriteGRestore(physDev);
198             break;
199
200         default:
201             ERR("Unknown hatch style\n");
202             ret = FALSE;
203             break;
204         }
205         PSDRV_WriteGRestore(physDev);
206         break;
207
208     case BS_NULL:
209         break;
210
211     case BS_PATTERN:
212         {
213             BITMAP bm;
214             BYTE *bits;
215             GetObjectA( (HBITMAP)logbrush.lbHatch, sizeof(BITMAP), &bm);
216             TRACE("BS_PATTERN %dx%d %d bpp\n", bm.bmWidth, bm.bmHeight,
217                   bm.bmBitsPixel);
218             bits = HeapAlloc(PSDRV_Heap, 0, bm.bmWidthBytes * bm.bmHeight);
219             GetBitmapBits( (HBITMAP)logbrush.lbHatch, bm.bmWidthBytes * bm.bmHeight, bits);
220
221             if(physDev->pi->ppd->LanguageLevel > 1) {
222                 PSDRV_WriteGSave(physDev);
223                 PSDRV_WritePatternDict(physDev, &bm, bits);
224                 PSDRV_Fill(physDev, EO);
225                 PSDRV_WriteGRestore(physDev);
226             } else {
227                 FIXME("Trying to set a pattern brush on a level 1 printer\n");
228                 ret = FALSE;
229             }
230             HeapFree(PSDRV_Heap, 0, bits);
231         }
232         break;
233
234     case BS_DIBPATTERN:
235         {
236             BITMAPINFO *bmi = GlobalLock16(logbrush.lbHatch);
237             UINT usage = logbrush.lbColor;
238             TRACE("size %ldx%ldx%d\n", bmi->bmiHeader.biWidth,
239                   bmi->bmiHeader.biHeight, bmi->bmiHeader.biBitCount);
240             if(physDev->pi->ppd->LanguageLevel > 1) {
241                 PSDRV_WriteGSave(physDev);
242                 ret = PSDRV_WriteDIBPatternDict(physDev, bmi, usage);
243                 PSDRV_Fill(physDev, EO);
244                 PSDRV_WriteGRestore(physDev);
245             } else {
246                 FIXME("Trying to set a pattern brush on a level 1 printer\n");
247                 ret = FALSE;
248             }
249             GlobalUnlock16(logbrush.lbHatch);
250         }
251         break;
252
253     default:
254         ret = FALSE;
255         break;
256     }
257     return ret;
258 }