4 * Copyright 1993 Alexandre Julliard
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.
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.
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
27 #include "mfdrv/metafiledrv.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
33 /***********************************************************************
36 HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
42 /******************************************************************
43 * MFDRV_CreateBrushIndirect
46 INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
52 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
54 if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
56 switch(logbrush.lbStyle)
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));
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");
87 bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, 1);
89 size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
90 sizeof(RGBQUAD) + bmSize;
92 mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
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);
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);
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;
117 DWORD bmSize, biSize;
119 info = GlobalLock16((HGLOBAL16)logbrush.lbHatch);
120 if (info->bmiHeader.biCompression)
121 bmSize = info->bmiHeader.biSizeImage;
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);
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);
138 FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
141 index = MFDRV_AddHandleDC( dev );
142 if(!MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))
144 HeapFree(GetProcessHeap(), 0, mr);
150 /***********************************************************************
153 HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
158 index = MFDRV_CreateBrushIndirect( dev, hbrush );
159 if(index == -1) return 0;
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;
167 /******************************************************************
168 * MFDRV_CreateFontIndirect
171 static BOOL MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont)
174 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
175 METARECORD *mr = (METARECORD *)&buffer;
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;
182 mr->rdSize = sizeof(METARECORD) / 2;
183 mr->rdFunction = META_SELECTOBJECT;
185 if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE;
186 *(mr->rdParm) = index;
187 return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
191 /***********************************************************************
194 HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont )
198 if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 )) return HGDI_ERROR;
199 if (MFDRV_CreateFontIndirect(dev, hfont, &lf16)) return 0;
203 /******************************************************************
204 * MFDRV_CreatePenIndirect
206 static BOOL MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
209 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
210 METARECORD *mr = (METARECORD *)&buffer;
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;
217 mr->rdSize = sizeof(METARECORD) / 2;
218 mr->rdFunction = META_SELECTOBJECT;
220 if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE;
221 *(mr->rdParm) = index;
222 return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
226 /***********************************************************************
229 HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
233 if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen )) return 0;
234 if (MFDRV_CreatePenIndirect( dev, hpen, &logpen )) return hpen;
239 /******************************************************************
240 * MFDRV_CreatePalette
242 static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette)
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))))
254 HeapFree(GetProcessHeap(), 0, mr);
258 mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
259 mr->rdFunction = META_SELECTPALETTE;
261 if ((index = MFDRV_AddHandleDC( dev )) == -1) ret = FALSE;
264 *(mr->rdParm) = index;
265 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD));
267 HeapFree(GetProcessHeap(), 0, mr);
272 /***********************************************************************
273 * MFDRV_SelectPalette
275 HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground )
277 #define PALVERSION 0x0300
279 PLOGPALETTE logPalette;
280 WORD wNumEntries = 0;
281 BOOL creationSucceed;
284 GetObjectA(hPalette, sizeof(WORD), (LPSTR) &wNumEntries);
286 if (wNumEntries == 0) return 0;
288 sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY));
289 logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette );
291 if (logPalette == NULL) return 0;
293 logPalette->palVersion = PALVERSION;
294 logPalette->palNumEntries = wNumEntries;
296 GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry);
298 creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette );
300 HeapFree( GetProcessHeap(), 0, logPalette );
308 /***********************************************************************
309 * MFDRV_RealizePalette
311 UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy)
313 char buffer[sizeof(METARECORD) - sizeof(WORD)];
314 METARECORD *mr = (METARECORD *)&buffer;
316 mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD);
317 mr->rdFunction = META_REALIZEPALETTE;
319 if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0;
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. */