Fixed error handling in DGA_IDirectDraw2Impl_GetCaps().
[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 "bitmap.h"
10 #include "brush.h"
11 #include "font.h"
12 #include "enhmetafiledrv.h"
13 #include "pen.h"
14 #include "debug.h"
15 #include "heap.h"
16
17 DEFAULT_DEBUG_CHANNEL(enhmetafile)
18
19 /***********************************************************************
20  *           EMFDRV_BITMAP_SelectObject
21  */
22 static HBITMAP EMFDRV_BITMAP_SelectObject( DC * dc, HBITMAP hbitmap )
23 {
24     return 0;
25 }
26
27
28 /***********************************************************************
29  *           EMFDRV_CreateBrushIndirect
30  */
31 DWORD EMFDRV_CreateBrushIndirect( DC *dc, HBRUSH hBrush )
32 {
33     DWORD index = 0;
34     BRUSHOBJ *brushObj = (BRUSHOBJ *)GDI_GetObjPtr( hBrush, BRUSH_MAGIC );
35
36     switch (brushObj->logbrush.lbStyle) {
37     case BS_SOLID:
38     case BS_HATCHED:
39     case BS_NULL:
40       {
41         EMRCREATEBRUSHINDIRECT emr;
42         emr.emr.iType = EMR_CREATEBRUSHINDIRECT;
43         emr.emr.nSize = sizeof(emr);
44         emr.ihBrush = index = EMFDRV_AddHandleDC( dc );
45         emr.lb = brushObj->logbrush;
46
47         if(!EMFDRV_WriteRecord( dc, &emr.emr ))
48             index = 0;
49       }
50       break;
51     case BS_DIBPATTERN:
52       {
53         EMRCREATEDIBPATTERNBRUSHPT *emr;
54         DWORD bmSize, biSize, size;
55         BITMAPINFO *info = GlobalLock16(brushObj->logbrush.lbHatch);
56
57         if (info->bmiHeader.biCompression)
58             bmSize = info->bmiHeader.biSizeImage;
59         else
60             bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
61                                           info->bmiHeader.biHeight,
62                                           info->bmiHeader.biBitCount);
63         biSize = DIB_BitmapInfoSize(info, LOWORD(brushObj->logbrush.lbColor)); 
64         size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize;
65         emr = HeapAlloc( SystemHeap, 0, size );
66         if(!emr) break;;
67         emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT;
68         emr->emr.nSize = size;
69         emr->ihBrush = index = EMFDRV_AddHandleDC( dc );
70         emr->iUsage = LOWORD(brushObj->logbrush.lbColor);
71         emr->offBmi = sizeof(EMRCREATEDIBPATTERNBRUSHPT);
72         emr->cbBmi = biSize;
73         emr->offBits = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize;
74         memcpy((char *)emr + sizeof(EMRCREATEDIBPATTERNBRUSHPT), info,
75                biSize + bmSize ); 
76
77         if(!EMFDRV_WriteRecord( dc, &emr->emr ))
78             index = 0;
79         HeapFree( SystemHeap, 0, emr );
80         GlobalUnlock16(brushObj->logbrush.lbHatch);
81       }
82       break;
83
84     case BS_PATTERN:
85         FIXME(enhmetafile, "Unsupported style %x\n",
86               brushObj->logbrush.lbStyle);
87         break;
88     default:
89         FIXME(enhmetafile, "Unknown style %x\n", brushObj->logbrush.lbStyle);
90         return FALSE;
91     }
92     GDI_HEAP_UNLOCK( hBrush );
93     return index;
94 }
95
96
97 /***********************************************************************
98  *           EMFDRV_BRUSH_SelectObject
99  */
100 static HBRUSH EMFDRV_BRUSH_SelectObject(DC *dc, HBRUSH hBrush )
101 {
102     EMRSELECTOBJECT emr;
103     DWORD index;
104     HBRUSH hOldBrush;
105
106     index = EMFDRV_CreateBrushIndirect(dc, hBrush );
107     if(!index) return FALSE;
108     
109     emr.emr.iType = EMR_SELECTOBJECT;
110     emr.emr.nSize = sizeof(emr);
111     emr.ihObject = index;
112     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
113         return FALSE;
114
115     hOldBrush = dc->w.hBrush;
116     dc->w.hBrush = hBrush;
117     return hOldBrush;
118 }
119
120
121 /******************************************************************
122  *         EMFDRV_CreateFontIndirect
123  */
124 static BOOL EMFDRV_CreateFontIndirect(DC *dc, HFONT hFont )
125 {
126     DWORD index = 0;
127     FONTOBJ *fontObj = (FONTOBJ *)GDI_GetObjPtr( hFont, FONT_MAGIC );
128     EMREXTCREATEFONTINDIRECTW emr;
129     int i;
130     emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW;
131     emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
132     emr.ihFont = index = EMFDRV_AddHandleDC( dc );
133     FONT_LogFont16To32W( &(fontObj->logfont), &(emr.elfw.elfLogFont) );
134     emr.elfw.elfFullName[0] = '\0';
135     emr.elfw.elfStyle[0]    = '\0';
136     emr.elfw.elfVersion     = 0;
137     emr.elfw.elfStyleSize   = 0;
138     emr.elfw.elfMatch       = 0;
139     emr.elfw.elfReserved    = 0;
140     for(i = 0; i < ELF_VENDOR_SIZE; i++)
141         emr.elfw.elfVendorId[i] = 0;
142     emr.elfw.elfCulture                 = PAN_CULTURE_LATIN;
143     emr.elfw.elfPanose.bFamilyType      = PAN_NO_FIT;
144     emr.elfw.elfPanose.bSerifStyle      = PAN_NO_FIT;
145     emr.elfw.elfPanose.bWeight          = PAN_NO_FIT;
146     emr.elfw.elfPanose.bProportion      = PAN_NO_FIT;
147     emr.elfw.elfPanose.bContrast        = PAN_NO_FIT;
148     emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT;
149     emr.elfw.elfPanose.bArmStyle        = PAN_NO_FIT;
150     emr.elfw.elfPanose.bLetterform      = PAN_NO_FIT;
151     emr.elfw.elfPanose.bMidline         = PAN_NO_FIT;
152     emr.elfw.elfPanose.bXHeight         = PAN_NO_FIT;
153
154     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
155         index = 0;
156     GDI_HEAP_UNLOCK( hFont );
157     return index;
158 }
159
160
161 /***********************************************************************
162  *           EMFDRV_FONT_SelectObject
163  */
164 static HFONT EMFDRV_FONT_SelectObject( DC * dc, HFONT hFont )
165 {
166     EMRSELECTOBJECT emr;
167     DWORD index;
168     HFONT hOldFont;
169
170     index = EMFDRV_CreateFontIndirect(dc, hFont );
171     if(!index) return FALSE;
172
173     emr.emr.iType = EMR_SELECTOBJECT;
174     emr.emr.nSize = sizeof(emr);
175     emr.ihObject = index;
176     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
177         return FALSE;
178
179     hOldFont = dc->w.hFont;
180     dc->w.hFont = hFont;
181     return hOldFont;
182 }
183
184
185
186 /******************************************************************
187  *         EMFDRV_CreatePenIndirect
188  */
189 static HPEN EMFDRV_CreatePenIndirect(DC *dc, HPEN hPen )
190 {
191     EMRCREATEPEN emr;
192     PENOBJ *penObj = (PENOBJ *)GDI_GetObjPtr( hPen, PEN_MAGIC );
193     DWORD index = 0;
194
195     emr.emr.iType = EMR_CREATEPEN;
196     emr.emr.nSize = sizeof(emr);
197     emr.ihPen = index = EMFDRV_AddHandleDC( dc );
198     emr.lopn = penObj->logpen;
199
200     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
201         index = 0;
202     GDI_HEAP_UNLOCK( hPen );
203     return index;
204 }
205
206 /******************************************************************
207  *         EMFDRV_PEN_SelectObject
208  */
209 static HPEN EMFDRV_PEN_SelectObject(DC *dc, HPEN hPen )
210 {
211     EMRSELECTOBJECT emr;
212     DWORD index;
213     HFONT hOldPen;
214
215     index = EMFDRV_CreatePenIndirect(dc, hPen );
216     if(!index) return FALSE;
217     
218     emr.emr.iType = EMR_SELECTOBJECT;
219     emr.emr.nSize = sizeof(emr);
220     emr.ihObject = index;
221     if(!EMFDRV_WriteRecord( dc, &emr.emr ))
222         return FALSE;
223
224     hOldPen = dc->w.hPen;
225     dc->w.hPen = hPen;
226     return hOldPen; 
227 }
228
229
230 /***********************************************************************
231  *           EMFDRV_SelectObject
232  */
233 HGDIOBJ EMFDRV_SelectObject( DC *dc, HGDIOBJ handle )
234 {
235     GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
236     HGDIOBJ ret = 0;
237
238     if (!ptr) return 0;
239     TRACE(enhmetafile, "hdc=%04x %04x\n", dc->hSelf, handle );
240     
241     switch(ptr->wMagic)
242     {
243       case PEN_MAGIC:
244           ret = EMFDRV_PEN_SelectObject( dc, handle );
245           break;
246       case BRUSH_MAGIC:
247           ret = EMFDRV_BRUSH_SelectObject( dc, handle );
248           break;
249       case FONT_MAGIC:
250           ret = EMFDRV_FONT_SelectObject( dc, handle );
251           break;
252       case BITMAP_MAGIC:
253           ret = EMFDRV_BITMAP_SelectObject( dc, handle );
254           break;
255     }
256     GDI_HEAP_UNLOCK( handle );
257     return ret;
258 }
259
260