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