Correctly remember the first paint event, but delay item metrics
[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_SetBrush(physDev);
149         PSDRV_WriteGSave(physDev);
150         PSDRV_Fill(physDev, EO);
151         PSDRV_WriteGRestore(physDev);
152         break;
153
154     case BS_HATCHED:
155         PSDRV_SetBrush(physDev);
156
157         switch(logbrush.lbHatch) {
158         case HS_VERTICAL:
159         case HS_CROSS:
160             PSDRV_WriteGSave(physDev);
161             PSDRV_Clip(physDev, EO);
162             PSDRV_WriteHatch(physDev);
163             PSDRV_WriteStroke(physDev);
164             PSDRV_WriteGRestore(physDev);
165             if(logbrush.lbHatch == HS_VERTICAL)
166                 break;
167             /* else fallthrough for HS_CROSS */
168
169         case HS_HORIZONTAL:
170             PSDRV_WriteGSave(physDev);
171             PSDRV_Clip(physDev, EO);
172             PSDRV_WriteRotate(physDev, 90.0);
173             PSDRV_WriteHatch(physDev);
174             PSDRV_WriteStroke(physDev);
175             PSDRV_WriteGRestore(physDev);
176             break;
177
178         case HS_FDIAGONAL:
179         case HS_DIAGCROSS:
180             PSDRV_WriteGSave(physDev);
181             PSDRV_Clip(physDev, EO);
182             PSDRV_WriteRotate(physDev, -45.0);
183             PSDRV_WriteHatch(physDev);
184             PSDRV_WriteStroke(physDev);
185             PSDRV_WriteGRestore(physDev);
186             if(logbrush.lbHatch == HS_FDIAGONAL)
187                 break;
188             /* else fallthrough for HS_DIAGCROSS */
189
190         case HS_BDIAGONAL:
191             PSDRV_WriteGSave(physDev);
192             PSDRV_Clip(physDev, EO);
193             PSDRV_WriteRotate(physDev, 45.0);
194             PSDRV_WriteHatch(physDev);
195             PSDRV_WriteStroke(physDev);
196             PSDRV_WriteGRestore(physDev);
197             break;
198
199         default:
200             ERR("Unknown hatch style\n");
201             ret = FALSE;
202             break;
203         }
204         break;
205
206     case BS_NULL:
207         break;
208
209     case BS_PATTERN:
210         {
211             BITMAP bm;
212             BYTE *bits;
213             GetObjectA( (HBITMAP)logbrush.lbHatch, sizeof(BITMAP), &bm);
214             TRACE("BS_PATTERN %dx%d %d bpp\n", bm.bmWidth, bm.bmHeight,
215                   bm.bmBitsPixel);
216             bits = HeapAlloc(PSDRV_Heap, 0, bm.bmWidthBytes * bm.bmHeight);
217             GetBitmapBits( (HBITMAP)logbrush.lbHatch, bm.bmWidthBytes * bm.bmHeight, bits);
218
219             if(physDev->pi->ppd->LanguageLevel > 1) {
220                 PSDRV_WriteGSave(physDev);
221                 PSDRV_WritePatternDict(physDev, &bm, bits);
222                 PSDRV_Fill(physDev, EO);
223                 PSDRV_WriteGRestore(physDev);
224             } else {
225                 FIXME("Trying to set a pattern brush on a level 1 printer\n");
226                 ret = FALSE;
227             }
228             HeapFree(PSDRV_Heap, 0, bits);
229         }
230         break;
231
232     case BS_DIBPATTERN:
233         {
234             BITMAPINFO *bmi = GlobalLock16(logbrush.lbHatch);
235             UINT usage = logbrush.lbColor;
236             TRACE("size %ldx%ldx%d\n", bmi->bmiHeader.biWidth,
237                   bmi->bmiHeader.biHeight, bmi->bmiHeader.biBitCount);
238             if(physDev->pi->ppd->LanguageLevel > 1) {
239                 PSDRV_WriteGSave(physDev);
240                 ret = PSDRV_WriteDIBPatternDict(physDev, bmi, usage);
241                 PSDRV_Fill(physDev, EO);
242                 PSDRV_WriteGRestore(physDev);
243             } else {
244                 FIXME("Trying to set a pattern brush on a level 1 printer\n");
245                 ret = FALSE;
246             }
247             GlobalUnlock16(logbrush.lbHatch);
248         }
249         break;
250
251     default:
252         ret = FALSE;
253         break;
254     }
255     return ret;
256 }