Fixed some problems found while compiling and linking Wine under
[wine] / dlls / gdi / mfdrv / objects.c
1 /*
2  * GDI objects
3  *
4  * Copyright 1993 Alexandre Julliard
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 <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "bitmap.h"
26 #include "wownt32.h"
27 #include "mfdrv/metafiledrv.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
31
32
33 /***********************************************************************
34  *           MFDRV_SelectBitmap
35  */
36 HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
37 {
38     return 0;
39 }
40
41
42 /******************************************************************
43  *         MFDRV_CreateBrushIndirect
44  */
45
46 INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
47 {
48     INT16 index = -1;
49     DWORD size;
50     METARECORD *mr;
51     LOGBRUSH logbrush;
52     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
53
54     if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
55
56     switch(logbrush.lbStyle)
57     {
58     case BS_SOLID:
59     case BS_NULL:
60     case BS_HATCHED:
61         {
62             LOGBRUSH16 lb16;
63
64             lb16.lbStyle = logbrush.lbStyle;
65             lb16.lbColor = logbrush.lbColor;
66             lb16.lbHatch = logbrush.lbHatch;
67             size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
68             mr = HeapAlloc( GetProcessHeap(), 0, size );
69             mr->rdSize = size / 2;
70             mr->rdFunction = META_CREATEBRUSHINDIRECT;
71         memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
72             break;
73         }
74     case BS_PATTERN:
75         {
76             BITMAP bm;
77             BYTE *bits;
78             BITMAPINFO *info;
79             DWORD bmSize;
80
81             GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
82             if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
83                 FIXME("Trying to store a colour pattern brush\n");
84                 goto done;
85             }
86
87             bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, 1);
88
89             size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
90               sizeof(RGBQUAD) + bmSize;
91
92             mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
93             if(!mr) goto done;
94             mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
95             mr->rdSize = size / 2;
96             mr->rdParm[0] = BS_PATTERN;
97             mr->rdParm[1] = DIB_RGB_COLORS;
98             info = (BITMAPINFO *)(mr->rdParm + 2);
99
100             info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
101             info->bmiHeader.biWidth = bm.bmWidth;
102             info->bmiHeader.biHeight = bm.bmHeight;
103             info->bmiHeader.biPlanes = 1;
104             info->bmiHeader.biBitCount = 1;
105             bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
106
107             GetDIBits(physDev->hdc, (HANDLE)logbrush.lbHatch, 0, bm.bmHeight,
108                       bits, info, DIB_RGB_COLORS);
109             *(DWORD *)info->bmiColors = 0;
110             *(DWORD *)(info->bmiColors + 1) = 0xffffff;
111             break;
112         }
113
114     case BS_DIBPATTERN:
115         {
116               BITMAPINFO *info;
117               DWORD bmSize, biSize;
118
119               info = GlobalLock16((HGLOBAL16)logbrush.lbHatch);
120               if (info->bmiHeader.biCompression)
121                   bmSize = info->bmiHeader.biSizeImage;
122               else
123                   bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
124                                                 info->bmiHeader.biHeight,
125                                                 info->bmiHeader.biBitCount);
126               biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush.lbColor));
127               size = sizeof(METARECORD) + biSize + bmSize + 2;
128               mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
129               if(!mr) goto done;
130               mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
131               mr->rdSize = size / 2;
132               *(mr->rdParm) = logbrush.lbStyle;
133               *(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
134               memcpy(mr->rdParm + 2, info, biSize + bmSize);
135               break;
136         }
137         default:
138             FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
139             return -1;
140     }
141     index = MFDRV_AddHandleDC( dev );
142     if(!MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))
143         index = -1;
144     HeapFree(GetProcessHeap(), 0, mr);
145 done:
146     return index;
147 }
148
149
150 /***********************************************************************
151  *           MFDRV_SelectBrush
152  */
153 HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
154 {
155     INT16 index;
156     METARECORD mr;
157
158     index = MFDRV_CreateBrushIndirect( dev, hbrush );
159     if(index == -1) return 0;
160
161     mr.rdSize = sizeof(mr) / 2;
162     mr.rdFunction = META_SELECTOBJECT;
163     mr.rdParm[0] = index;
164     return MFDRV_WriteRecord( dev, &mr, mr.rdSize * 2) ? hbrush : 0;
165 }
166
167 /******************************************************************
168  *         MFDRV_CreateFontIndirect
169  */
170
171 static BOOL MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont)
172 {
173     int index;
174     char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
175     METARECORD *mr = (METARECORD *)&buffer;
176
177     mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
178     mr->rdFunction = META_CREATEFONTINDIRECT;
179     memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
180     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return FALSE;
181
182     mr->rdSize = sizeof(METARECORD) / 2;
183     mr->rdFunction = META_SELECTOBJECT;
184
185     if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE;
186     *(mr->rdParm) = index;
187     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
188 }
189
190
191 /***********************************************************************
192  *           MFDRV_SelectFont
193  */
194 HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont )
195 {
196     LOGFONT16 lf16;
197
198     if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 )) return HGDI_ERROR;
199     if (MFDRV_CreateFontIndirect(dev, hfont, &lf16)) return 0;
200     return HGDI_ERROR;
201 }
202
203 /******************************************************************
204  *         MFDRV_CreatePenIndirect
205  */
206 static BOOL MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
207 {
208     int index;
209     char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
210     METARECORD *mr = (METARECORD *)&buffer;
211
212     mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
213     mr->rdFunction = META_CREATEPENINDIRECT;
214     memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
215     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return FALSE;
216
217     mr->rdSize = sizeof(METARECORD) / 2;
218     mr->rdFunction = META_SELECTOBJECT;
219
220     if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE;
221     *(mr->rdParm) = index;
222     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
223 }
224
225
226 /***********************************************************************
227  *           MFDRV_SelectPen
228  */
229 HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
230 {
231     LOGPEN16 logpen;
232
233     if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen )) return 0;
234     if (MFDRV_CreatePenIndirect( dev, hpen, &logpen )) return hpen;
235     return 0;
236 }
237
238
239 /******************************************************************
240  *         MFDRV_CreatePalette
241  */
242 static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette)
243 {
244     int index;
245     BOOL ret;
246     METARECORD *mr;
247
248     mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) );
249     mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD);
250     mr->rdFunction = META_CREATEPALETTE;
251     memcpy(&(mr->rdParm), logPalette, sizeofPalette);
252     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD))))
253     {
254         HeapFree(GetProcessHeap(), 0, mr);
255         return FALSE;
256     }
257
258     mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
259     mr->rdFunction = META_SELECTPALETTE;
260
261     if ((index = MFDRV_AddHandleDC( dev )) == -1) ret = FALSE;
262     else
263     {
264         *(mr->rdParm) = index;
265         ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD));
266     }
267     HeapFree(GetProcessHeap(), 0, mr);
268     return ret;
269 }
270
271
272 /***********************************************************************
273  *           MFDRV_SelectPalette
274  */
275 HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground )
276 {
277 #define PALVERSION 0x0300
278
279     PLOGPALETTE logPalette;
280     WORD        wNumEntries = 0;
281     BOOL        creationSucceed;
282     int         sizeofPalette;
283
284     GetObjectA(hPalette, sizeof(WORD), (LPSTR) &wNumEntries);
285
286     if (wNumEntries == 0) return 0;
287
288     sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY));
289     logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette );
290
291     if (logPalette == NULL) return 0;
292
293     logPalette->palVersion = PALVERSION;
294     logPalette->palNumEntries = wNumEntries;
295
296     GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry);
297
298     creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette );
299
300     HeapFree( GetProcessHeap(), 0, logPalette );
301
302     if (creationSucceed)
303         return hPalette;
304
305     return 0;
306 }
307
308 /***********************************************************************
309  *           MFDRV_RealizePalette
310  */
311 UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy)
312 {
313     char buffer[sizeof(METARECORD) - sizeof(WORD)];
314     METARECORD *mr = (METARECORD *)&buffer;
315
316     mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD);
317     mr->rdFunction = META_REALIZEPALETTE;
318
319     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0;
320
321     /* The return value is suppose to be the number of entries
322        in the logical palette mapped to the system palette or 0
323        if the function failed. Since it's not trivial here to
324        get that kind of information and since it's of little
325        use in the case of metafiles, we'll always return 1. */
326     return 1;
327 }