Implement simple ExtTextOut for enhmfdrv.
[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         emr->cbBits = bmSize;
89         memcpy((char *)emr + sizeof(EMRCREATEDIBPATTERNBRUSHPT), info,
90                biSize + bmSize );
91
92         if(!EMFDRV_WriteRecord( dev, &emr->emr ))
93             index = 0;
94         HeapFree( GetProcessHeap(), 0, emr );
95         GlobalUnlock16(logbrush.lbHatch);
96       }
97       break;
98
99     case BS_PATTERN:
100         FIXME("Unsupported style %x\n",
101               logbrush.lbStyle);
102         break;
103     default:
104         FIXME("Unknown style %x\n", logbrush.lbStyle);
105         break;
106     }
107     return index;
108 }
109
110
111 /***********************************************************************
112  *           EMFDRV_SelectBrush
113  */
114 HBRUSH EMFDRV_SelectBrush(PHYSDEV dev, HBRUSH hBrush )
115 {
116     EMRSELECTOBJECT emr;
117     DWORD index;
118     int i;
119
120     /* If the object is a stock brush object, do not need to create it.
121      * See definitions in  wingdi.h for range of stock brushes.
122      * We do however have to handle setting the higher order bit to
123      * designate that this is a stock object.
124      */
125     for (i = WHITE_BRUSH; i <= NULL_BRUSH; i++)
126     {
127         if (hBrush == GetStockObject(i))
128         {
129             index = i | 0x80000000;
130             goto found;
131         }
132     }
133     if (!(index = EMFDRV_CreateBrushIndirect(dev, hBrush ))) return 0;
134
135  found:
136     emr.emr.iType = EMR_SELECTOBJECT;
137     emr.emr.nSize = sizeof(emr);
138     emr.ihObject = index;
139     return EMFDRV_WriteRecord( dev, &emr.emr ) ? hBrush : 0;
140 }
141
142
143 /******************************************************************
144  *         EMFDRV_CreateFontIndirect
145  */
146 static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
147 {
148     DWORD index = 0;
149     EMREXTCREATEFONTINDIRECTW emr;
150     int i;
151
152     if (!GetObjectW( hFont, sizeof(emr.elfw.elfLogFont), &emr.elfw.elfLogFont )) return 0;
153
154     emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW;
155     emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
156     emr.ihFont = index = EMFDRV_AddHandleDC( dev );
157     emr.elfw.elfFullName[0] = '\0';
158     emr.elfw.elfStyle[0]    = '\0';
159     emr.elfw.elfVersion     = 0;
160     emr.elfw.elfStyleSize   = 0;
161     emr.elfw.elfMatch       = 0;
162     emr.elfw.elfReserved    = 0;
163     for(i = 0; i < ELF_VENDOR_SIZE; i++)
164         emr.elfw.elfVendorId[i] = 0;
165     emr.elfw.elfCulture                 = PAN_CULTURE_LATIN;
166     emr.elfw.elfPanose.bFamilyType      = PAN_NO_FIT;
167     emr.elfw.elfPanose.bSerifStyle      = PAN_NO_FIT;
168     emr.elfw.elfPanose.bWeight          = PAN_NO_FIT;
169     emr.elfw.elfPanose.bProportion      = PAN_NO_FIT;
170     emr.elfw.elfPanose.bContrast        = PAN_NO_FIT;
171     emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT;
172     emr.elfw.elfPanose.bArmStyle        = PAN_NO_FIT;
173     emr.elfw.elfPanose.bLetterform      = PAN_NO_FIT;
174     emr.elfw.elfPanose.bMidline         = PAN_NO_FIT;
175     emr.elfw.elfPanose.bXHeight         = PAN_NO_FIT;
176
177     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
178         index = 0;
179     return index;
180 }
181
182
183 /***********************************************************************
184  *           EMFDRV_SelectFont
185  */
186 HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont )
187 {
188     EMRSELECTOBJECT emr;
189     DWORD index;
190     int i;
191
192     /* If the object is a stock font object, do not need to create it.
193      * See definitions in  wingdi.h for range of stock fonts.
194      * We do however have to handle setting the higher order bit to
195      * designate that this is a stock object.
196      */
197
198     for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
199     {
200         if (i != DEFAULT_PALETTE && hFont == GetStockObject(i))
201         {
202             index = i | 0x80000000;
203             goto found;
204         }
205     }
206     if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return HGDI_ERROR;
207  found:
208     emr.emr.iType = EMR_SELECTOBJECT;
209     emr.emr.nSize = sizeof(emr);
210     emr.ihObject = index;
211     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
212         return HGDI_ERROR;
213     return 0;
214 }
215
216
217
218 /******************************************************************
219  *         EMFDRV_CreatePenIndirect
220  */
221 static HPEN EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen )
222 {
223     EMRCREATEPEN emr;
224     DWORD index = 0;
225
226     if (!GetObjectA( hPen, sizeof(emr.lopn), &emr.lopn )) return 0;
227
228     emr.emr.iType = EMR_CREATEPEN;
229     emr.emr.nSize = sizeof(emr);
230     emr.ihPen = index = EMFDRV_AddHandleDC( dev );
231
232     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
233         index = 0;
234     return index;
235 }
236
237 /******************************************************************
238  *         EMFDRV_SelectPen
239  */
240 HPEN EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen )
241 {
242     EMRSELECTOBJECT emr;
243     DWORD index;
244     int i;
245
246     /* If the object is a stock pen object, do not need to create it.
247      * See definitions in  wingdi.h for range of stock pens.
248      * We do however have to handle setting the higher order bit to
249      * designate that this is a stock object.
250      */
251
252     for (i = WHITE_PEN; i <= NULL_PEN; i++)
253     {
254         if (hPen == GetStockObject(i))
255         {
256             index = i | 0x80000000;
257             goto found;
258         }
259     }
260     if (!(index = EMFDRV_CreatePenIndirect(dev, hPen ))) return 0;
261  found:
262     emr.emr.iType = EMR_SELECTOBJECT;
263     emr.emr.nSize = sizeof(emr);
264     emr.ihObject = index;
265     return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPen : 0;
266 }