Don't call a NE DLL's DllEntryPoint twice during one single
[wine/multimedia.git] / graphics / metafiledrv / objects.c
blob2756d2a6272ca3efa6ed3d26a476a74db10d46c1
1 /*
2 * GDI objects
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
11 #include "bitmap.h"
12 #include "brush.h"
13 #include "font.h"
14 #include "metafiledrv.h"
15 #include "pen.h"
16 #include "debugtools.h"
17 #include "heap.h"
19 DEFAULT_DEBUG_CHANNEL(metafile);
20 DECLARE_DEBUG_CHANNEL(gdi);
22 /***********************************************************************
23 * MFDRV_BITMAP_SelectObject
25 static HBITMAP16 MFDRV_BITMAP_SelectObject( DC * dc, HBITMAP16 hbitmap,
26 BITMAPOBJ * bmp )
28 return 0;
32 /******************************************************************
33 * MFDRV_CreateBrushIndirect
36 INT16 MFDRV_CreateBrushIndirect(DC *dc, HBRUSH hBrush )
38 INT16 index = -1;
39 DWORD size;
40 METARECORD *mr;
41 BRUSHOBJ *brushObj = (BRUSHOBJ *)GDI_GetObjPtr( hBrush, BRUSH_MAGIC );
42 if(!brushObj) return -1;
44 switch(brushObj->logbrush.lbStyle) {
45 case BS_SOLID:
46 case BS_NULL:
47 case BS_HATCHED:
49 LOGBRUSH16 lb16;
51 lb16.lbStyle = brushObj->logbrush.lbStyle;
52 lb16.lbColor = brushObj->logbrush.lbColor;
53 lb16.lbHatch = brushObj->logbrush.lbHatch;
54 size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
55 mr = HeapAlloc( GetProcessHeap(), 0, size );
56 mr->rdSize = size / 2;
57 mr->rdFunction = META_CREATEBRUSHINDIRECT;
58 memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH));
59 break;
61 case BS_PATTERN:
63 BITMAP bm;
64 BYTE *bits;
65 BITMAPINFO *info;
66 DWORD bmSize;
68 GetObjectA(brushObj->logbrush.lbHatch, sizeof(bm), &bm);
69 if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
70 FIXME("Trying to store a colour pattern brush\n");
71 goto done;
74 bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, 1);
76 size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
77 sizeof(RGBQUAD) + bmSize;
79 mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
80 if(!mr) goto done;
81 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
82 mr->rdSize = size / 2;
83 mr->rdParm[0] = BS_PATTERN;
84 mr->rdParm[1] = DIB_RGB_COLORS;
85 info = (BITMAPINFO *)(mr->rdParm + 2);
87 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
88 info->bmiHeader.biWidth = bm.bmWidth;
89 info->bmiHeader.biHeight = bm.bmHeight;
90 info->bmiHeader.biPlanes = 1;
91 info->bmiHeader.biBitCount = 1;
92 bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
94 GetDIBits(dc->hSelf, brushObj->logbrush.lbHatch, 0, bm.bmHeight,
95 bits, info, DIB_RGB_COLORS);
96 *(DWORD *)info->bmiColors = 0;
97 *(DWORD *)(info->bmiColors + 1) = 0xffffff;
98 break;
101 case BS_DIBPATTERN:
103 BITMAPINFO *info;
104 DWORD bmSize, biSize;
106 info = GlobalLock16((HGLOBAL16)brushObj->logbrush.lbHatch);
107 if (info->bmiHeader.biCompression)
108 bmSize = info->bmiHeader.biSizeImage;
109 else
110 bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
111 info->bmiHeader.biHeight,
112 info->bmiHeader.biBitCount);
113 biSize = DIB_BitmapInfoSize(info,
114 LOWORD(brushObj->logbrush.lbColor));
115 size = sizeof(METARECORD) + biSize + bmSize + 2;
116 mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
117 if(!mr) goto done;
118 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
119 mr->rdSize = size / 2;
120 *(mr->rdParm) = brushObj->logbrush.lbStyle;
121 *(mr->rdParm + 1) = LOWORD(brushObj->logbrush.lbColor);
122 memcpy(mr->rdParm + 2, info, biSize + bmSize);
123 break;
125 default:
126 FIXME("Unkonwn brush style %x\n", brushObj->logbrush.lbStyle);
127 return -1;
129 index = MFDRV_AddHandleDC( dc );
130 if(!MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))
131 index = -1;
132 HeapFree(GetProcessHeap(), 0, mr);
133 done:
134 GDI_ReleaseObj( hBrush );
135 return index;
139 /***********************************************************************
140 * MFDRV_BRUSH_SelectObject
142 static HBRUSH MFDRV_BRUSH_SelectObject( DC *dc, HBRUSH hbrush,
143 BRUSHOBJ * brush )
145 INT16 index;
146 METARECORD mr;
148 index = MFDRV_CreateBrushIndirect( dc, hbrush );
149 if(index == -1) return 0;
151 mr.rdSize = sizeof(mr) / 2;
152 mr.rdFunction = META_SELECTOBJECT;
153 mr.rdParm[0] = index;
154 return MFDRV_WriteRecord( dc, &mr, mr.rdSize * 2);
157 /******************************************************************
158 * MFDRV_CreateFontIndirect
161 static BOOL MFDRV_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
163 int index;
164 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
165 METARECORD *mr = (METARECORD *)&buffer;
167 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
168 mr->rdFunction = META_CREATEFONTINDIRECT;
169 memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
170 if (!(MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
172 mr->rdSize = sizeof(METARECORD) / 2;
173 mr->rdFunction = META_SELECTOBJECT;
175 if ((index = MFDRV_AddHandleDC( dc )) == -1) return FALSE;
176 *(mr->rdParm) = index;
177 return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
181 /***********************************************************************
182 * MFDRV_FONT_SelectObject
184 static HFONT16 MFDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
185 FONTOBJ * font )
187 HFONT16 prevHandle = dc->hFont;
188 if (MFDRV_CreateFontIndirect(dc, hfont, &(font->logfont)))
189 return prevHandle;
190 return 0;
193 /******************************************************************
194 * MFDRV_CreatePenIndirect
196 static BOOL MFDRV_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
198 int index;
199 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
200 METARECORD *mr = (METARECORD *)&buffer;
202 mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
203 mr->rdFunction = META_CREATEPENINDIRECT;
204 memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
205 if (!(MFDRV_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
207 mr->rdSize = sizeof(METARECORD) / 2;
208 mr->rdFunction = META_SELECTOBJECT;
210 if ((index = MFDRV_AddHandleDC( dc )) == -1) return FALSE;
211 *(mr->rdParm) = index;
212 return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
216 /***********************************************************************
217 * MFDRV_PEN_SelectObject
219 static HPEN MFDRV_PEN_SelectObject( DC * dc, HPEN hpen, PENOBJ * pen )
221 LOGPEN16 logpen;
222 HPEN prevHandle = dc->hPen;
224 logpen.lopnStyle = pen->logpen.lopnStyle;
225 logpen.lopnWidth.x = pen->logpen.lopnWidth.x;
226 logpen.lopnWidth.y = pen->logpen.lopnWidth.y;
227 logpen.lopnColor = pen->logpen.lopnColor;
229 if (MFDRV_CreatePenIndirect( dc, hpen, &logpen )) return prevHandle;
231 return 0;
235 /***********************************************************************
236 * MFDRV_SelectObject
238 HGDIOBJ MFDRV_SelectObject( DC *dc, HGDIOBJ handle )
240 GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
241 HGDIOBJ ret = 0;
243 if (!ptr) return 0;
244 TRACE_(gdi)("hdc=%04x %04x\n", dc->hSelf, handle );
246 switch(GDIMAGIC(ptr->wMagic))
248 case PEN_MAGIC:
249 ret = MFDRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
250 break;
251 case BRUSH_MAGIC:
252 ret = MFDRV_BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
253 break;
254 case BITMAP_MAGIC:
255 ret = MFDRV_BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
256 break;
257 case FONT_MAGIC:
258 ret = MFDRV_FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );
259 break;
260 case REGION_MAGIC:
261 ret = (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
262 break;
264 GDI_ReleaseObj( handle );
265 return ret;