Fixed first seek on MEM mmio files.
[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->w.hBrush;
22     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
23
24     TRACE("hbrush = %08x\n", hbrush);
25     dc->w.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     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
64     BRUSHOBJ *brush = (BRUSHOBJ *)GDI_GetObjPtr( dc->w.hBrush, BRUSH_MAGIC );
65
66     if(!brush) {
67         ERR("Can't get BRUSHOBJ\n");
68         return FALSE;
69     }
70     
71     switch (brush->logbrush.lbStyle) {
72     case BS_SOLID:
73     case BS_HATCHED:
74         PSDRV_WriteSetColor(dc, &physDev->brush.color);
75         break;
76
77     case BS_NULL:
78         break;
79
80     default:
81         return FALSE;
82         break;
83
84     }
85     physDev->brush.set = TRUE;
86     return TRUE;
87 }
88
89
90 /**********************************************************************
91  *
92  *      PSDRV_Fill
93  *
94  */
95 static BOOL PSDRV_Fill(DC *dc, BOOL EO)
96 {
97     if(!EO)
98         return PSDRV_WriteFill(dc);
99     else
100       return PSDRV_WriteEOFill(dc);
101 }
102
103
104 /**********************************************************************
105  *
106  *      PSDRV_Clip
107  *
108  */
109 static BOOL PSDRV_Clip(DC *dc, BOOL EO)
110 {
111     if(!EO)
112         return PSDRV_WriteClip(dc);
113     else
114         return PSDRV_WriteEOClip(dc);
115 }
116
117 /**********************************************************************
118  *
119  *      PSDRV_Brush
120  *
121  */
122 BOOL PSDRV_Brush(DC *dc, BOOL EO)
123 {
124     BRUSHOBJ *brush = (BRUSHOBJ *)GDI_GetObjPtr( dc->w.hBrush, BRUSH_MAGIC );
125     PSDRV_PDEVICE *physDev = dc->physDev;
126
127     if(!brush) {
128         ERR("Can't get BRUSHOBJ\n");
129         return FALSE;
130     }
131
132     switch (brush->logbrush.lbStyle) {
133     case BS_SOLID:
134         PSDRV_SetBrush(dc);
135         PSDRV_WriteGSave(dc);
136         PSDRV_Fill(dc, EO);
137         PSDRV_WriteGRestore(dc);
138         return TRUE;
139         break;
140
141     case BS_HATCHED:
142         PSDRV_SetBrush(dc);
143
144         switch(brush->logbrush.lbHatch) {
145         case HS_VERTICAL:
146         case HS_CROSS:
147             PSDRV_WriteGSave(dc);
148             PSDRV_Clip(dc, EO);
149             PSDRV_WriteHatch(dc);
150             PSDRV_WriteStroke(dc);
151             PSDRV_WriteGRestore(dc);
152             if(brush->logbrush.lbHatch == HS_VERTICAL)
153                 break;
154             /* else fallthrough for HS_CROSS */
155
156         case HS_HORIZONTAL:
157             PSDRV_WriteGSave(dc);
158             PSDRV_Clip(dc, EO);
159             PSDRV_WriteRotate(dc, 90.0);
160             PSDRV_WriteHatch(dc);
161             PSDRV_WriteStroke(dc);
162             PSDRV_WriteGRestore(dc);
163             break;
164
165         case HS_FDIAGONAL:
166         case HS_DIAGCROSS:
167             PSDRV_WriteGSave(dc);
168             PSDRV_Clip(dc, EO);
169             PSDRV_WriteRotate(dc, -45.0);
170             PSDRV_WriteHatch(dc);
171             PSDRV_WriteStroke(dc);
172             PSDRV_WriteGRestore(dc);
173             if(brush->logbrush.lbHatch == HS_FDIAGONAL)
174                 break;
175             /* else fallthrough for HS_DIAGCROSS */
176             
177         case HS_BDIAGONAL:
178             PSDRV_WriteGSave(dc);
179             PSDRV_Clip(dc, EO);
180             PSDRV_WriteRotate(dc, 45.0);
181             PSDRV_WriteHatch(dc);
182             PSDRV_WriteStroke(dc);
183             PSDRV_WriteGRestore(dc);
184             break;
185
186         default:
187             ERR("Unknown hatch style\n");
188             return FALSE;
189         }
190         return TRUE;
191         break;
192
193     case BS_NULL:
194         return TRUE;
195         break;
196
197     case BS_PATTERN:
198         {
199             BITMAP bm;
200             BYTE *bits;
201             GetObjectA(brush->logbrush.lbHatch, sizeof(BITMAP), &bm);
202             TRACE("BS_PATTERN %dx%d %d bpp\n", bm.bmWidth, bm.bmHeight,
203                   bm.bmBitsPixel);
204             bits = HeapAlloc(PSDRV_Heap, 0, bm.bmWidthBytes * bm.bmHeight);
205             GetBitmapBits(brush->logbrush.lbHatch,
206                           bm.bmWidthBytes * bm.bmHeight, bits);
207
208             if(physDev->pi->ppd->LanguageLevel > 1) {
209                 PSDRV_WriteGSave(dc);
210                 PSDRV_WritePatternDict(dc, &bm, bits);
211                 PSDRV_Fill(dc, EO);
212                 PSDRV_WriteGRestore(dc);
213             } else {
214                 FIXME("Trying to set a pattern brush on a level 1 printer\n");
215             }
216             HeapFree(PSDRV_Heap, 0, bits);      
217             return TRUE;
218         }
219         break;
220
221
222
223     default:
224         return FALSE;
225         break;
226     }
227 }
228
229
230
231