Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[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 "wine/winbase16.h"
25 #include "win16drv/win16drv.h"
26 #include "font.h"
27 #include "gdi.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(win16drv);
31
32
33 /***********************************************************************
34  *           WIN16DRV_GetTextExtentPoint
35  */
36 BOOL WIN16DRV_GetTextExtentPoint( PHYSDEV dev, LPCWSTR wstr, INT count,
37                                   LPSIZE size )
38 {
39     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
40     DC *dc = physDev->dc;
41     DWORD dwRet, len;
42     char *str;
43
44     TRACE("%04x %s %d %p\n", physDev->hdc, debugstr_wn(wstr, count), count, size);
45
46
47     len = WideCharToMultiByte( CP_ACP, 0, wstr, count, NULL, 0, NULL, NULL );
48     str = HeapAlloc( GetProcessHeap(), 0, len );
49     WideCharToMultiByte( CP_ACP, 0, wstr, count, str, len, NULL, NULL );
50
51     dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
52                               NULL, str, -len,  physDev->FontInfo,
53                               win16drv_SegPtr_DrawMode, 
54                               win16drv_SegPtr_TextXForm, NULL, NULL, 0);
55     size->cx = XDSTOLS(dc,LOWORD(dwRet));
56     size->cy = YDSTOLS(dc,HIWORD(dwRet));
57     TRACE("cx=%ld, cy=%ld\n", size->cx, size->cy );
58     HeapFree( GetProcessHeap(), 0, str );
59     return TRUE;
60 }
61
62
63 /***********************************************************************
64  *           WIN16DRV_GetTextMetrics
65  */
66 BOOL WIN16DRV_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
67 {
68     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
69
70     TRACE("%04x \n", physDev->hdc);
71
72     FONT_TextMetric16ToW( &physDev->tm, metrics );
73
74     TRACE(
75           "H %ld, A %ld, D %ld, Int %ld, Ext %ld, AW %ld, MW %ld, W %ld\n",
76            metrics->tmHeight,
77            metrics->tmAscent,
78            metrics->tmDescent,
79            metrics->tmInternalLeading,
80            metrics->tmExternalLeading,
81            metrics->tmAveCharWidth,
82            metrics->tmMaxCharWidth,
83            metrics->tmWeight);
84
85     return TRUE;
86 }
87
88 /***********************************************************************
89  *           WIN16DRV_SelectFont
90  */
91 HFONT WIN16DRV_SelectFont( PHYSDEV dev, HFONT hfont)
92 {
93     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
94     DC *dc = physDev->dc;
95     int nSize;
96
97     if (!GetObject16( hfont, sizeof(physDev->lf), &physDev->lf ))
98         return GDI_ERROR;
99
100     TRACE("WIN16DRV_FONT_SelectObject %s h=%d\n",
101           debugstr_a(physDev->lf.lfFaceName), physDev->lf.lfHeight);
102
103     if( physDev->FontInfo )
104     {
105         TRACE("UnRealizing FontInfo\n");
106         nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, -DRVOBJ_FONT,
107                                       physDev->FontInfo,
108                                       physDev->FontInfo, 0);
109     }
110
111     nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_FONT,
112                                   &physDev->lf, 0, 0); 
113
114     if( physDev->FontInfo && 
115         HeapSize( GetProcessHeap(), 0, physDev->FontInfo ) < nSize )
116     {
117         HeapFree( GetProcessHeap(), 0, physDev->FontInfo );
118         physDev->FontInfo = NULL;
119     }
120     
121     if( !physDev->FontInfo )
122         physDev->FontInfo = HeapAlloc( GetProcessHeap(), 0, nSize );
123
124
125     nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_FONT,
126                                  &physDev->lf, 
127                                  physDev->FontInfo, 
128                                  win16drv_SegPtr_TextXForm ); 
129
130 #define fi physDev->FontInfo    
131     physDev->tm.tmHeight           = YDSTOLS(dc, fi->dfPixHeight);
132     physDev->tm.tmAscent           = YDSTOLS(dc, fi->dfAscent);
133     physDev->tm.tmDescent          = physDev->tm.tmHeight -
134                                             physDev->tm.tmAscent; 
135     physDev->tm.tmInternalLeading  = YDSTOLS(dc, fi->dfInternalLeading);
136     physDev->tm.tmExternalLeading  = YDSTOLS(dc, fi->dfExternalLeading);
137     physDev->tm.tmAveCharWidth     = XDSTOLS(dc, fi->dfAvgWidth);
138     physDev->tm.tmMaxCharWidth     = XDSTOLS(dc, fi->dfMaxWidth);
139     physDev->tm.tmWeight           = fi->dfWeight;
140     physDev->tm.tmOverhang         = 0; /*FIXME*/
141     physDev->tm.tmDigitizedAspectX = fi->dfHorizRes;
142     physDev->tm.tmDigitizedAspectY = fi->dfVertRes;
143     physDev->tm.tmFirstChar        = fi->dfFirstChar;
144     physDev->tm.tmLastChar         = fi->dfLastChar;
145     physDev->tm.tmDefaultChar      = fi->dfDefaultChar;
146     physDev->tm.tmBreakChar        = fi->dfBreakChar;
147     physDev->tm.tmItalic           = fi->dfItalic;
148     physDev->tm.tmUnderlined       = fi->dfUnderline;
149     physDev->tm.tmStruckOut        = fi->dfStrikeOut;
150     physDev->tm.tmPitchAndFamily   = fi->dfPitchAndFamily;
151     physDev->tm.tmCharSet          = fi->dfCharSet;
152 #undef fi
153
154     TRACE("H %d, A %d, D %d, Int %d, Ext %d, AW %d, MW %d, W %d\n",
155            physDev->tm.tmHeight,
156            physDev->tm.tmAscent,
157            physDev->tm.tmDescent,
158            physDev->tm.tmInternalLeading,
159            physDev->tm.tmExternalLeading,
160            physDev->tm.tmAveCharWidth,
161            physDev->tm.tmMaxCharWidth,
162            physDev->tm.tmWeight);
163
164     return TRUE; /* We'll use a device font */
165 }
166
167 /***********************************************************************
168  *           WIN16DRV_GetCharWidth
169  */
170 BOOL WIN16DRV_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar,
171                             LPINT buffer )
172 {
173     int i;
174     WORD wRet;
175     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
176
177     TRACE("%d - %d into %p\n", firstChar, lastChar, buffer );
178
179     wRet = PRTDRV_GetCharWidth( physDev->segptrPDEVICE, buffer, firstChar, 
180                                 lastChar, physDev->FontInfo, 
181                                 win16drv_SegPtr_DrawMode, 
182                                 win16drv_SegPtr_TextXForm );
183     if( TRACE_ON(win16drv) ){
184         for(i = 0; i <= lastChar - firstChar; i++)
185             TRACE("Char %x: width %d\n", i + firstChar,
186                                          buffer[i]);
187     }
188
189     return wRet;
190 }
191
192 /***********************************************************************
193  *
194  *           WIN16DRV_EnumDeviceFonts
195  */
196
197 BOOL    WIN16DRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, 
198                                   DEVICEFONTENUMPROC proc, LPARAM lp )
199 {
200     WIN16DRV_PDEVICE *physDev;
201     WORD wRet;
202     WEPFC wepfc;
203     DC *dc;
204     char *FaceNameA = NULL;
205    /* EnumDFontCallback is GDI.158 */
206     FARPROC16 pfnCallback = GetProcAddress16( GetModuleHandle16("GDI"), (LPCSTR)158 );
207
208     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
209     physDev = (WIN16DRV_PDEVICE *)dc->physDev;
210     /* FIXME!! */
211     GDI_ReleaseObj( hdc );
212
213     wepfc.proc = proc;
214     wepfc.lp = lp;
215
216     if(plf->lfFaceName[0]) {
217         INT len;
218         len = WideCharToMultiByte(CP_ACP, 0, plf->lfFaceName, -1, NULL, 0,
219                                   NULL, NULL);
220         FaceNameA = HeapAlloc(GetProcessHeap(), 0, len);
221         WideCharToMultiByte(CP_ACP, 0, plf->lfFaceName, -1, FaceNameA, len,
222                             NULL, NULL);
223     }
224     wRet = PRTDRV_EnumDFonts(physDev->segptrPDEVICE, FaceNameA, pfnCallback,
225                              &wepfc );
226     if(FaceNameA) HeapFree(GetProcessHeap(), 0, FaceNameA);
227     return wRet;
228 }
229
230 /***********************************************************************
231  * EnumCallback (GDI.158)
232  * 
233  * This is the callback function used when EnumDFonts is called. 
234  * (The printer drivers uses it to pass info on available fonts).
235  *
236  * lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
237  * structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK).
238  *
239  */
240 WORD WINAPI EnumCallback16(LPENUMLOGFONT16 lpLogFont,
241                            LPNEWTEXTMETRIC16 lpTextMetrics,
242                            WORD wFontType, LONG lpClientData) 
243 {
244     ENUMLOGFONTEXW lfW;
245     ENUMLOGFONTEX16 lf16;
246
247     NEWTEXTMETRICEXW tmW;
248     NEWTEXTMETRICEX16 tm16;
249
250     TRACE("In EnumCallback16 plf=%p\n", lpLogFont);
251
252     /* we have a ENUMLOGFONT16 which is a subset of ENUMLOGFONTEX16,
253        so we copy it into one of these and then convert to ENUMLOGFONTEXW */
254
255     memset(&lf16, 0, sizeof(lf16));
256     memcpy(&lf16, lpLogFont, sizeof(*lpLogFont));
257     FONT_EnumLogFontEx16ToW(&lf16, &lfW);
258
259     /* and a similar idea for NEWTEXTMETRIC16 */
260     memset(&tm16, 0, sizeof(tm16));
261     memcpy(&tm16, lpTextMetrics, sizeof(*lpTextMetrics));
262     FONT_NewTextMetricEx16ToW(&tm16, &tmW);
263
264     return (*(((WEPFC *)lpClientData)->proc))( &lfW, &tmW, wFontType,
265                                                ((WEPFC *)lpClientData)->lp );
266 }
267