Added regedit unit test, a couple minor changes to regedit.
[wine] / dlls / gdi / enhmfdrv / objects.c
1 /*
2  * Enhanced MetaFile objects
3  *
4  * Copyright 1999 Huw D M Davies
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 "enhmfdrv/enhmetafiledrv.h"
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
30
31 /***********************************************************************
32  *           EMFDRV_SelectBitmap
33  */
34 HBITMAP EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
35 {
36     return 0;
37 }
38
39
40 /***********************************************************************
41  *           EMFDRV_CreateBrushIndirect
42  */
43 DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
44 {
45     DWORD index = 0;
46     LOGBRUSH logbrush;
47
48     if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return 0;
49
50     switch (logbrush.lbStyle) {
51     case BS_SOLID:
52     case BS_HATCHED:
53     case BS_NULL:
54       {
55         EMRCREATEBRUSHINDIRECT emr;
56         emr.emr.iType = EMR_CREATEBRUSHINDIRECT;
57         emr.emr.nSize = sizeof(emr);
58         emr.ihBrush = index = EMFDRV_AddHandleDC( dev );
59         emr.lb = logbrush;
60
61         if(!EMFDRV_WriteRecord( dev, &emr.emr ))
62             index = 0;
63       }
64       break;
65     case BS_DIBPATTERN:
66       {
67         EMRCREATEDIBPATTERNBRUSHPT *emr;
68         DWORD bmSize, biSize, size;
69         BITMAPINFO *info = GlobalLock16(logbrush.lbHatch);
70
71         if (info->bmiHeader.biCompression)
72             bmSize = info->bmiHeader.biSizeImage;
73         else
74             bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
75                                           info->bmiHeader.biHeight,
76                                           info->bmiHeader.biBitCount);
77         biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush.lbColor));
78         size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize;
79         emr = HeapAlloc( GetProcessHeap(), 0, size );
80         if(!emr) break;
81         emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT;
82         emr->emr.nSize = size;
83         emr->ihBrush = index = EMFDRV_AddHandleDC( dev );
84         emr->iUsage = LOWORD(logbrush.lbColor);
85         emr->offBmi = sizeof(EMRCREATEDIBPATTERNBRUSHPT);
86         emr->cbBmi = biSize;
87         emr->offBits = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize;
88         memcpy((char *)emr + sizeof(EMRCREATEDIBPATTERNBRUSHPT), info,
89                biSize + bmSize );
90
91         if(!EMFDRV_WriteRecord( dev, &emr->emr ))
92             index = 0;
93         HeapFree( GetProcessHeap(), 0, emr );
94         GlobalUnlock16(logbrush.lbHatch);
95       }
96       break;
97
98     case BS_PATTERN:
99         FIXME("Unsupported style %x\n",
100               logbrush.lbStyle);
101         break;
102     default:
103         FIXME("Unknown style %x\n", logbrush.lbStyle);
104         break;
105     }
106     return index;
107 }
108
109
110 /***********************************************************************
111  *           EMFDRV_SelectBrush
112  */
113 HBRUSH EMFDRV_SelectBrush(PHYSDEV dev, HBRUSH hBrush )
114 {
115     EMRSELECTOBJECT emr;
116     DWORD index;
117     int i;
118
119     /* If the object is a stock brush object, do not need to create it.
120      * See definitions in  wingdi.h for range of stock brushes.
121      * We do however have to handle setting the higher order bit to
122      * designate that this is a stock object.
123      */
124     for (i = WHITE_BRUSH; i <= NULL_BRUSH; i++)
125     {
126         if (hBrush == GetStockObject(i))
127         {
128             index = i | 0x80000000;
129             goto found;
130         }
131     }
132     if (!(index = EMFDRV_CreateBrushIndirect(dev, hBrush ))) return 0;
133
134  found:
135     emr.emr.iType = EMR_SELECTOBJECT;
136     emr.emr.nSize = sizeof(emr);
137     emr.ihObject = index;
138     return EMFDRV_WriteRecord( dev, &emr.emr ) ? hBrush : 0;
139 }
140
141
142 /******************************************************************
143  *         EMFDRV_CreateFontIndirect
144  */
145 static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
146 {
147     DWORD index = 0;
148     EMREXTCREATEFONTINDIRECTW emr;
149     int i;
150
151     if (!GetObjectW( hFont, sizeof(emr.elfw.elfLogFont), &emr.elfw.elfLogFont )) return 0;
152
153     emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW;
154     emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
155     emr.ihFont = index = EMFDRV_AddHandleDC( dev );
156     emr.elfw.elfFullName[0] = '\0';
157     emr.elfw.elfStyle[0]    = '\0';
158     emr.elfw.elfVersion     = 0;
159     emr.elfw.elfStyleSize   = 0;
160     emr.elfw.elfMatch       = 0;
161     emr.elfw.elfReserved    = 0;
162     for(i = 0; i < ELF_VENDOR_SIZE; i++)
163         emr.elfw.elfVendorId[i] = 0;
164     emr.elfw.elfCulture                 = PAN_CULTURE_LATIN;
165     emr.elfw.elfPanose.bFamilyType      = PAN_NO_FIT;
166     emr.elfw.elfPanose.bSerifStyle      = PAN_NO_FIT;
167     emr.elfw.elfPanose.bWeight          = PAN_NO_FIT;
168     emr.elfw.elfPanose.bProportion      = PAN_NO_FIT;
169     emr.elfw.elfPanose.bContrast        = PAN_NO_FIT;
170     emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT;
171     emr.elfw.elfPanose.bArmStyle        = PAN_NO_FIT;
172     emr.elfw.elfPanose.bLetterform      = PAN_NO_FIT;
173     emr.elfw.elfPanose.bMidline         = PAN_NO_FIT;
174     emr.elfw.elfPanose.bXHeight         = PAN_NO_FIT;
175
176     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
177         index = 0;
178     return index;
179 }
180
181
182 /***********************************************************************
183  *           EMFDRV_SelectFont
184  */
185 HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont )
186 {
187     EMRSELECTOBJECT emr;
188     DWORD index;
189     int i;
190
191     /* If the object is a stock font object, do not need to create it.
192      * See definitions in  wingdi.h for range of stock fonts.
193      * We do however have to handle setting the higher order bit to
194      * designate that this is a stock object.
195      */
196
197     for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
198     {
199         if (i != DEFAULT_PALETTE && hFont == GetStockObject(i))
200         {
201             index = i | 0x80000000;
202             goto found;
203         }
204     }
205     if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return GDI_ERROR;
206  found:
207     emr.emr.iType = EMR_SELECTOBJECT;
208     emr.emr.nSize = sizeof(emr);
209     emr.ihObject = index;
210     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
211         return GDI_ERROR;
212     return 0;
213 }
214
215
216
217 /******************************************************************
218  *         EMFDRV_CreatePenIndirect
219  */
220 static HPEN EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen )
221 {
222     EMRCREATEPEN emr;
223     DWORD index = 0;
224
225     if (!GetObjectA( hPen, sizeof(emr.lopn), &emr.lopn )) return 0;
226
227     emr.emr.iType = EMR_CREATEPEN;
228     emr.emr.nSize = sizeof(emr);
229     emr.ihPen = index = EMFDRV_AddHandleDC( dev );
230
231     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
232         index = 0;
233     return index;
234 }
235
236 /******************************************************************
237  *         EMFDRV_SelectPen
238  */
239 HPEN EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen )
240 {
241     EMRSELECTOBJECT emr;
242     DWORD index;
243     int i;
244
245     /* If the object is a stock pen object, do not need to create it.
246      * See definitions in  wingdi.h for range of stock pens.
247      * We do however have to handle setting the higher order bit to
248      * designate that this is a stock object.
249      */
250
251     for (i = WHITE_PEN; i <= NULL_PEN; i++)
252     {
253         if (hPen == GetStockObject(i))
254         {
255             index = i | 0x80000000;
256             goto found;
257         }
258     }
259     if (!(index = EMFDRV_CreatePenIndirect(dev, hPen ))) return 0;
260  found:
261     emr.emr.iType = EMR_SELECTOBJECT;
262     emr.emr.nSize = sizeof(emr);
263     emr.ihObject = index;
264     return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPen : 0;
265 }