fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / gdi / win16drv / font.c
1 /*
2  * Windows driver font functions
3  *
4  * Copyright 1996 John Harvey
5  *           1998 Huw Davies
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <string.h>
23 #include "winnls.h"
24 #include "wownt32.h"
25 #include "wine/winbase16.h"
26 #include "win16drv/win16drv.h"
27 #include "gdi.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(win16drv);
31
32
33 static void WIN16DRV_NewTextMetric16ToW(const NEWTEXTMETRIC16 *ptm16, LPNEWTEXTMETRICW ptmW )
34 {
35     ptmW->tmHeight = ptm16->tmHeight;
36     ptmW->tmAscent = ptm16->tmAscent;
37     ptmW->tmDescent = ptm16->tmDescent;
38     ptmW->tmInternalLeading = ptm16->tmInternalLeading;
39     ptmW->tmExternalLeading = ptm16->tmExternalLeading;
40     ptmW->tmAveCharWidth = ptm16->tmAveCharWidth;
41     ptmW->tmMaxCharWidth = ptm16->tmMaxCharWidth;
42     ptmW->tmWeight = ptm16->tmWeight;
43     ptmW->tmOverhang = ptm16->tmOverhang;
44     ptmW->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
45     ptmW->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
46     ptmW->tmFirstChar = ptm16->tmFirstChar;
47     ptmW->tmLastChar = ptm16->tmLastChar;
48     ptmW->tmDefaultChar = ptm16->tmDefaultChar;
49     ptmW->tmBreakChar = ptm16->tmBreakChar;
50     ptmW->tmItalic = ptm16->tmItalic;
51     ptmW->tmUnderlined = ptm16->tmUnderlined;
52     ptmW->tmStruckOut = ptm16->tmStruckOut;
53     ptmW->tmPitchAndFamily = ptm16->tmPitchAndFamily;
54     ptmW->tmCharSet = ptm16->tmCharSet;
55     ptmW->ntmFlags = ptm16->ntmFlags;
56     ptmW->ntmSizeEM = ptm16->ntmSizeEM;
57     ptmW->ntmCellHeight = ptm16->ntmCellHeight;
58     ptmW->ntmAvgWidth = ptm16->ntmAvgWidth;
59 }
60
61
62 static void WIN16DRV_EnumLogFont16ToW( const ENUMLOGFONT16 *font16, LPENUMLOGFONTW font32 )
63 {
64     font32->elfLogFont.lfHeight = font16->elfLogFont.lfHeight;
65     font32->elfLogFont.lfWidth = font16->elfLogFont.lfWidth;
66     font32->elfLogFont.lfEscapement = font16->elfLogFont.lfEscapement;
67     font32->elfLogFont.lfOrientation = font16->elfLogFont.lfOrientation;
68     font32->elfLogFont.lfWeight = font16->elfLogFont.lfWeight;
69     font32->elfLogFont.lfItalic = font16->elfLogFont.lfItalic;
70     font32->elfLogFont.lfUnderline = font16->elfLogFont.lfUnderline;
71     font32->elfLogFont.lfStrikeOut = font16->elfLogFont.lfStrikeOut;
72     font32->elfLogFont.lfCharSet = font16->elfLogFont.lfCharSet;
73     font32->elfLogFont.lfOutPrecision = font16->elfLogFont.lfOutPrecision;
74     font32->elfLogFont.lfClipPrecision = font16->elfLogFont.lfClipPrecision;
75     font32->elfLogFont.lfQuality = font16->elfLogFont.lfQuality;
76     font32->elfLogFont.lfPitchAndFamily = font16->elfLogFont.lfPitchAndFamily;
77     MultiByteToWideChar( CP_ACP, 0, font16->elfLogFont.lfFaceName, -1,
78                          font32->elfLogFont.lfFaceName, LF_FACESIZE );
79     font32->elfLogFont.lfFaceName[LF_FACESIZE-1] = 0;
80     MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
81     font32->elfFullName[LF_FULLFACESIZE-1] = 0;
82     MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
83     font32->elfStyle[LF_FACESIZE-1] = 0;
84 }
85
86
87 /***********************************************************************
88  *           WIN16DRV_GetTextExtentPoint
89  */
90 BOOL WIN16DRV_GetTextExtentPoint( PHYSDEV dev, LPCWSTR wstr, INT count,
91                                   LPSIZE size )
92 {
93     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
94     DC *dc = physDev->dc;
95     DWORD dwRet, len;
96     char *str;
97
98     TRACE("%p %s %d %p\n", physDev->hdc, debugstr_wn(wstr, count), count, size);
99
100
101     len = WideCharToMultiByte( CP_ACP, 0, wstr, count, NULL, 0, NULL, NULL );
102     str = HeapAlloc( GetProcessHeap(), 0, len );
103     WideCharToMultiByte( CP_ACP, 0, wstr, count, str, len, NULL, NULL );
104
105     dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0,
106                               NULL, str, -len,  physDev->FontInfo,
107                               win16drv_SegPtr_DrawMode,
108                               win16drv_SegPtr_TextXForm, NULL, NULL, 0);
109     size->cx = XDSTOLS(dc,LOWORD(dwRet));
110     size->cy = YDSTOLS(dc,HIWORD(dwRet));
111     TRACE("cx=%ld, cy=%ld\n", size->cx, size->cy );
112     HeapFree( GetProcessHeap(), 0, str );
113     return TRUE;
114 }
115
116
117 /***********************************************************************
118  *           WIN16DRV_GetTextMetrics
119  */
120 BOOL WIN16DRV_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
121 {
122     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
123
124     TRACE("%p \n", physDev->hdc);
125
126     *metrics = physDev->tm;
127
128     TRACE(
129           "H %ld, A %ld, D %ld, Int %ld, Ext %ld, AW %ld, MW %ld, W %ld\n",
130            metrics->tmHeight,
131            metrics->tmAscent,
132            metrics->tmDescent,
133            metrics->tmInternalLeading,
134            metrics->tmExternalLeading,
135            metrics->tmAveCharWidth,
136            metrics->tmMaxCharWidth,
137            metrics->tmWeight);
138
139     return TRUE;
140 }
141
142 /***********************************************************************
143  *           WIN16DRV_SelectFont
144  */
145 HFONT WIN16DRV_SelectFont( PHYSDEV dev, HFONT hfont)
146 {
147     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
148     DC *dc = physDev->dc;
149     int nSize;
150
151     if (!GetObject16( HFONT_16(hfont), sizeof(physDev->lf), &physDev->lf ))
152         return HGDI_ERROR;
153
154     TRACE("WIN16DRV_FONT_SelectObject %s h=%d\n",
155           debugstr_a(physDev->lf.lfFaceName), physDev->lf.lfHeight);
156
157     if( physDev->FontInfo )
158     {
159         TRACE("UnRealizing FontInfo\n");
160         nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, -DRVOBJ_FONT,
161                                       physDev->FontInfo,
162                                       physDev->FontInfo, 0);
163     }
164
165     nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_FONT,
166                                   &physDev->lf, 0, 0);
167
168     if( physDev->FontInfo &&
169         HeapSize( GetProcessHeap(), 0, physDev->FontInfo ) < nSize )
170     {
171         HeapFree( GetProcessHeap(), 0, physDev->FontInfo );
172         physDev->FontInfo = NULL;
173     }
174
175     if( !physDev->FontInfo )
176         physDev->FontInfo = HeapAlloc( GetProcessHeap(), 0, nSize );
177
178
179     nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_FONT,
180                                  &physDev->lf,
181                                  physDev->FontInfo,
182                                  win16drv_SegPtr_TextXForm );
183
184 #define fi physDev->FontInfo
185     physDev->tm.tmHeight           = YDSTOLS(dc, fi->dfPixHeight);
186     physDev->tm.tmAscent           = YDSTOLS(dc, fi->dfAscent);
187     physDev->tm.tmDescent          = physDev->tm.tmHeight - physDev->tm.tmAscent;
188     physDev->tm.tmInternalLeading  = YDSTOLS(dc, fi->dfInternalLeading);
189     physDev->tm.tmExternalLeading  = YDSTOLS(dc, fi->dfExternalLeading);
190     physDev->tm.tmAveCharWidth     = XDSTOLS(dc, fi->dfAvgWidth);
191     physDev->tm.tmMaxCharWidth     = XDSTOLS(dc, fi->dfMaxWidth);
192     physDev->tm.tmWeight           = fi->dfWeight;
193     physDev->tm.tmOverhang         = 0; /*FIXME*/
194     physDev->tm.tmDigitizedAspectX = fi->dfHorizRes;
195     physDev->tm.tmDigitizedAspectY = fi->dfVertRes;
196     physDev->tm.tmFirstChar        = fi->dfFirstChar;
197     physDev->tm.tmLastChar         = fi->dfLastChar;
198     physDev->tm.tmDefaultChar      = fi->dfDefaultChar;
199     physDev->tm.tmBreakChar        = fi->dfBreakChar;
200     physDev->tm.tmItalic           = fi->dfItalic;
201     physDev->tm.tmUnderlined       = fi->dfUnderline;
202     physDev->tm.tmStruckOut        = fi->dfStrikeOut;
203     physDev->tm.tmPitchAndFamily   = fi->dfPitchAndFamily;
204     physDev->tm.tmCharSet          = fi->dfCharSet;
205 #undef fi
206
207     TRACE("H %ld, A %ld, D %ld, Int %ld, Ext %ld, AW %ld, MW %ld, W %ld\n",
208            physDev->tm.tmHeight,
209            physDev->tm.tmAscent,
210            physDev->tm.tmDescent,
211            physDev->tm.tmInternalLeading,
212            physDev->tm.tmExternalLeading,
213            physDev->tm.tmAveCharWidth,
214            physDev->tm.tmMaxCharWidth,
215            physDev->tm.tmWeight);
216
217     return (HFONT)1; /* We'll use a device font */
218 }
219
220 /***********************************************************************
221  *           WIN16DRV_GetCharWidth
222  */
223 BOOL WIN16DRV_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar,
224                             LPINT buffer )
225 {
226     int i;
227     WORD wRet;
228     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
229
230     TRACE("%d - %d into %p\n", firstChar, lastChar, buffer );
231
232     wRet = PRTDRV_GetCharWidth( physDev->segptrPDEVICE, buffer, firstChar,
233                                 lastChar, physDev->FontInfo,
234                                 win16drv_SegPtr_DrawMode,
235                                 win16drv_SegPtr_TextXForm );
236     if( TRACE_ON(win16drv) ){
237         for(i = 0; i <= lastChar - firstChar; i++)
238             TRACE("Char %x: width %d\n", i + firstChar,
239                                          buffer[i]);
240     }
241
242     return wRet;
243 }
244
245 /***********************************************************************
246  *
247  *           WIN16DRV_EnumDeviceFonts
248  */
249
250 BOOL WIN16DRV_EnumDeviceFonts( PHYSDEV dev, LPLOGFONTW plf,
251                                DEVICEFONTENUMPROC proc, LPARAM lp )
252 {
253     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
254     WORD wRet;
255     WEPFC wepfc;
256     char *FaceNameA = NULL;
257    /* EnumDFontCallback is GDI.158 */
258     FARPROC16 pfnCallback = GetProcAddress16( GetModuleHandle16("GDI"), (LPCSTR)158 );
259
260     wepfc.proc = proc;
261     wepfc.lp = lp;
262
263     if(plf->lfFaceName[0]) {
264         INT len;
265         len = WideCharToMultiByte(CP_ACP, 0, plf->lfFaceName, -1, NULL, 0,
266                                   NULL, NULL);
267         FaceNameA = HeapAlloc(GetProcessHeap(), 0, len);
268         WideCharToMultiByte(CP_ACP, 0, plf->lfFaceName, -1, FaceNameA, len,
269                             NULL, NULL);
270     }
271     wRet = PRTDRV_EnumDFonts(physDev->segptrPDEVICE, FaceNameA, pfnCallback,
272                              &wepfc );
273     if(FaceNameA) HeapFree(GetProcessHeap(), 0, FaceNameA);
274     return wRet;
275 }
276
277 /***********************************************************************
278  * EnumCallback (GDI.158)
279  *
280  * This is the callback function used when EnumDFonts is called.
281  * (The printer drivers uses it to pass info on available fonts).
282  *
283  * lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
284  * structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK).
285  *
286  */
287 WORD WINAPI EnumCallback16(LPENUMLOGFONT16 lpLogFont,
288                            LPNEWTEXTMETRIC16 lpTextMetrics,
289                            WORD wFontType, LONG lpClientData)
290 {
291     ENUMLOGFONTEXW lfW;
292     NEWTEXTMETRICEXW tmW;
293
294     TRACE("In EnumCallback16 plf=%p\n", lpLogFont);
295
296     memset(&lfW, 0, sizeof(lfW));
297     WIN16DRV_EnumLogFont16ToW(lpLogFont, (ENUMLOGFONTW *)&lfW);
298
299     memset(&tmW, 0, sizeof(tmW));
300     WIN16DRV_NewTextMetric16ToW(lpTextMetrics, (NEWTEXTMETRICW *)&tmW);
301
302     return (*(((WEPFC *)lpClientData)->proc))( &lfW, &tmW, wFontType,
303                                                ((WEPFC *)lpClientData)->lp );
304 }