Allocate DC objects on the process heap, and removed WIN_DC_INFO
[wine] / graphics / enhmetafiledrv / objects.c
1 /*
2  * Enhanced MetaFile objects
3  *
4  * Copyright 1999 Huw D M Davies
5  */
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "bitmap.h"
12 #include "brush.h"
13 #include "font.h"
14 #include "enhmetafiledrv.h"
15 #include "pen.h"
16 #include "debugtools.h"
17 #include "heap.h"
18
19 DEFAULT_DEBUG_CHANNEL(enhmetafile)
20
21 /***********************************************************************
22  *           EMFDRV_BITMAP_SelectObject
23  */
24 static HBITMAP EMFDRV_BITMAP_SelectObject( DC * dc, HBITMAP hbitmap )
25 {
26     return 0;
27 }
28
29
30 /***********************************************************************
31  *           EMFDRV_CreateBrushIndirect
32  */
33 DWORD EMFDRV_CreateBrushIndirect( DC *dc, HBRUSH hBrush )
34 {
35     DWORD index = 0;
36     BRUSHOBJ *brushObj = (BRUSHOBJ *)GDI_GetObjPtr( hBrush, BRUSH_MAGIC );
37
38     switch (brushObj->logbrush.lbStyle) {
39     case BS_SOLID:
40     case BS_HATCHED:
41     case BS_NULL:
42       {
43         EMRCREATEBRUSHINDIRECT emr;
44         emr.emr.iType = EMR_CREATEBRUSHINDIRECT;
45         emr.emr.nSize = sizeof(emr);
46         emr.ihBrush = index = EMFDRV_AddHandleDC( dc );
47         emr.lb = brushObj->logbrush;
48
49         if(!EMFDRV_WriteRecord( dc, &emr.emr ))
50             index = 0;
51       }
52       break;
53     case BS_DIBPATTERN:
54       {
55         EMRCREATEDIBPATTERNBRUSHPT *emr;
56         DWORD bmSize, biSize, size;
57         BITMAPINFO *info = GlobalLock16(brushObj->logbrush.lbHatch);
58
59         if (info->bmiHeader.biCompression)
60             bmSize = info->bmiHeader.biSizeImage;
61         else
62             bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
63                                           info->bmiHeader.biHeight,
64                                           info->bmiHeader.biBitCount);
65         biSize = DIB_BitmapInfoSize(info, LOWORD(brushObj->logbrush.lbColor)); 
66         size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize;
67         emr = HeapAlloc( GetProcessHeap(), 0, size );
68         if(!emr) break;
69         emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT;
70         emr->emr.nSize = size;
71         emr->ihBrush = index = EMFDRV_AddHandleDC( dc );
72         emr->iUsage = LOWORD(brushObj->logbrush.lbColor);
73         emr->offBmi = sizeof(EMRCREATEDIBPATTERNBRUSHPT);
74         emr->cbBmi = biSize;
75         emr->offBits = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize;
76         memcpy((char *)emr + sizeof(EMRCREATEDIBPATTERNBRUSHPT), info,
77                biSize + bmSize ); 
78
79         if(!EMFDRV_WriteRecord( dc, &emr->emr ))
80             index = 0;
81         HeapFree( GetProcessHeap(), 0, emr );
82         GlobalUnlock16(brushObj->logbrush.lbHatch);
83       }
84       break;
85
86     case BS_PATTERN:
87         FIXME("Unsupported style %x\n",
88               brushObj->logbrush.lbStyle);
89         break;
90     default:
91         FIXME("Unknown style %x\n", brushObj->logbrush.lbStyle);
92         break;
93     }
94     GDI_ReleaseObj( hBrush );
95     return index;
96 }
97
98
99 /***********************************************************************
100  *           EMFDRV_BRUSH_SelectObject
101  */
102 static HBRUSH EMFDRV_BRUSH_SelectObject(DC *dc, HBRUSH hBrush )
103 {
104     EMRSELECTOBJECT emr;
105     DWORD index;
106     HBRUSH hOldBrush;
107     
108     /* If the object is a stock brush object, do not need to create it.
109      * See definitions in  wingdi.h for range of stock brushes.
110      * We do however have to handle setting the higher order bit to
111      * designate that this is a stock object.
112      */
113     if (hBrush >= FIRST_STOCK_HANDLE &&
114         hBrush <= FIRST_STOCK_HANDLE+HOLLOW_BRUSH )
115     {
116         DWORD brush_index = hBrush - FIRST_STOCK_HANDLE;
117         index = brush_index | 0x80000000;
118     }
119     else
120     {
121         index = EMFDRV_CreateBrushIndirect(dc, hBrush );
122     }
123     
124     if(!index) return FALSE;
125
126     emr.emr.iType = EMR_SELECTOBJECT;
127     emr.emr.nSize = sizeof(emr);
128     emr.ihObject = index;
129     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
130         return FALSE;
131
132     hOldBrush = dc->hBrush;
133     dc->hBrush = hBrush;
134     return hOldBrush;
135 }
136
137
138 /******************************************************************
139  *         EMFDRV_CreateFontIndirect
140  */
141 static BOOL EMFDRV_CreateFontIndirect(DC *dc, HFONT hFont )
142 {
143     DWORD index = 0;
144     FONTOBJ *fontObj = (FONTOBJ *)GDI_GetObjPtr( hFont, FONT_MAGIC );
145     EMREXTCREATEFONTINDIRECTW emr;
146     int i;
147     emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW;
148     emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
149     emr.ihFont = index = EMFDRV_AddHandleDC( dc );
150     FONT_LogFont16To32W( &(fontObj->logfont), &(emr.elfw.elfLogFont) );
151     emr.elfw.elfFullName[0] = '\0';
152     emr.elfw.elfStyle[0]    = '\0';
153     emr.elfw.elfVersion     = 0;
154     emr.elfw.elfStyleSize   = 0;
155     emr.elfw.elfMatch       = 0;
156     emr.elfw.elfReserved    = 0;
157     for(i = 0; i < ELF_VENDOR_SIZE; i++)
158         emr.elfw.elfVendorId[i] = 0;
159     emr.elfw.elfCulture                 = PAN_CULTURE_LATIN;
160     emr.elfw.elfPanose.bFamilyType      = PAN_NO_FIT;
161     emr.elfw.elfPanose.bSerifStyle      = PAN_NO_FIT;
162     emr.elfw.elfPanose.bWeight          = PAN_NO_FIT;
163     emr.elfw.elfPanose.bProportion      = PAN_NO_FIT;
164     emr.elfw.elfPanose.bContrast        = PAN_NO_FIT;
165     emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT;
166     emr.elfw.elfPanose.bArmStyle        = PAN_NO_FIT;
167     emr.elfw.elfPanose.bLetterform      = PAN_NO_FIT;
168     emr.elfw.elfPanose.bMidline         = PAN_NO_FIT;
169     emr.elfw.elfPanose.bXHeight         = PAN_NO_FIT;
170
171     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
172         index = 0;
173     GDI_ReleaseObj( hFont );
174     return index;
175 }
176
177
178 /***********************************************************************
179  *           EMFDRV_FONT_SelectObject
180  */
181 static HFONT EMFDRV_FONT_SelectObject( DC * dc, HFONT hFont )
182 {
183     EMRSELECTOBJECT emr;
184     DWORD index;
185     HFONT hOldFont;
186
187     /* If the object is a stock font object, do not need to create it.
188      * See definitions in  wingdi.h for range of stock fonts.
189      * We do however have to handle setting the higher order bit to
190      * designate that this is a stock object.
191      */
192
193     if (hFont >= STOCK_OEM_FIXED_FONT &&
194         hFont <= STOCK_DEFAULT_GUI_FONT &&
195         hFont != STOCK_DEFAULT_PALETTE)
196     {
197         DWORD font_index = hFont - FIRST_STOCK_HANDLE;
198         index = font_index | 0x80000000;
199     }
200     else
201     {
202         index = EMFDRV_CreateFontIndirect(dc, hFont );
203     }
204
205     if(!index) return FALSE;
206
207     emr.emr.iType = EMR_SELECTOBJECT;
208     emr.emr.nSize = sizeof(emr);
209     emr.ihObject = index;
210     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
211         return FALSE;
212
213     hOldFont = dc->hFont;
214     dc->hFont = hFont;
215     return hOldFont;
216 }
217
218
219
220 /******************************************************************
221  *         EMFDRV_CreatePenIndirect
222  */
223 static HPEN EMFDRV_CreatePenIndirect(DC *dc, HPEN hPen )
224 {
225     EMRCREATEPEN emr;
226     PENOBJ *penObj = (PENOBJ *)GDI_GetObjPtr( hPen, PEN_MAGIC );
227     DWORD index = 0;
228
229     emr.emr.iType = EMR_CREATEPEN;
230     emr.emr.nSize = sizeof(emr);
231     emr.ihPen = index = EMFDRV_AddHandleDC( dc );
232     emr.lopn = penObj->logpen;
233
234     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
235         index = 0;
236     GDI_ReleaseObj( hPen );
237     return index;
238 }
239
240 /******************************************************************
241  *         EMFDRV_PEN_SelectObject
242  */
243 static HPEN EMFDRV_PEN_SelectObject(DC *dc, HPEN hPen )
244 {
245     EMRSELECTOBJECT emr;
246     DWORD index;
247     HFONT hOldPen;
248
249     /* If the object is a stock pen object, do not need to create it.
250      * See definitions in  wingdi.h for range of stock pens.
251      * We do however have to handle setting the higher order bit to
252      * designate that this is a stock object.
253      */
254
255     if (hPen >= STOCK_WHITE_PEN &&
256         hPen <= STOCK_NULL_PEN )
257     {
258         DWORD pen_index = hPen - FIRST_STOCK_HANDLE; 
259         index = pen_index | 0x80000000;
260     }
261     else
262     {
263         index = EMFDRV_CreatePenIndirect(dc, hPen );
264     }
265  
266     if(!index) return FALSE;
267     
268     emr.emr.iType = EMR_SELECTOBJECT;
269     emr.emr.nSize = sizeof(emr);
270     emr.ihObject = index;
271     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
272         return FALSE;
273
274     hOldPen = dc->hPen;
275     dc->hPen = hPen;
276     return hOldPen; 
277 }
278
279
280 /***********************************************************************
281  *           EMFDRV_SelectObject
282  */
283 HGDIOBJ EMFDRV_SelectObject( DC *dc, HGDIOBJ handle )
284 {
285     GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
286     HGDIOBJ ret = 0;
287
288     if (!ptr) return 0;
289     TRACE("hdc=%04x %04x\n", dc->hSelf, handle );
290     
291     switch(GDIMAGIC(ptr->wMagic))
292     {
293       case PEN_MAGIC:
294           ret = EMFDRV_PEN_SelectObject( dc, handle );
295           break;
296       case BRUSH_MAGIC:
297           ret = EMFDRV_BRUSH_SelectObject( dc, handle );
298           break;
299       case FONT_MAGIC:
300           ret = EMFDRV_FONT_SelectObject( dc, handle );
301           break;
302       case BITMAP_MAGIC:
303           ret = EMFDRV_BITMAP_SelectObject( dc, handle );
304           break;
305     }
306     GDI_ReleaseObj( handle );
307     return ret;
308 }
309
310