Initialize the NONCLIENTMETRICS with 0 (helps moorhuhn.exe).
[wine] / objects / font.c
1 /*
2  * GDI font objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *           1997 Alex Korobka
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include "wine/winestring.h"
11 #include "font.h"
12 #include "heap.h"
13 #include "metafile.h"
14 #include "options.h"
15 #include "debugtools.h"
16 #include "winerror.h"
17 #include "dc.h"
18
19 DEFAULT_DEBUG_CHANNEL(font)
20 DECLARE_DEBUG_CHANNEL(gdi)
21
22 #define ENUM_UNICODE    0x00000001
23
24 typedef struct
25 {
26   LPLOGFONT16           lpLogFontParam;
27   FONTENUMPROCEX16      lpEnumFunc;
28   LPARAM                lpData;
29
30   LPNEWTEXTMETRICEX16   lpTextMetric;
31   LPENUMLOGFONTEX16     lpLogFont;
32   SEGPTR                segTextMetric;
33   SEGPTR                segLogFont;
34 } fontEnum16;
35
36 typedef struct
37 {
38   LPLOGFONTW          lpLogFontParam;
39   FONTENUMPROCEXW     lpEnumFunc;
40   LPARAM                lpData;
41
42   LPNEWTEXTMETRICEXW  lpTextMetric;
43   LPENUMLOGFONTEXW    lpLogFont;
44   DWORD                 dwFlags;
45 } fontEnum32;
46  
47 /*
48  *  For TranslateCharsetInfo
49  */
50 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
51 #define MAXTCIINDEX 32
52 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
53   /* ANSI */
54   { ANSI_CHARSET, 1252, FS(0)},
55   { EASTEUROPE_CHARSET, 1250, FS(1)},
56   { RUSSIAN_CHARSET, 1251, FS(2)},
57   { GREEK_CHARSET, 1253, FS(3)},
58   { TURKISH_CHARSET, 1254, FS(4)},
59   { HEBREW_CHARSET, 1255, FS(5)},
60   { ARABIC_CHARSET, 1256, FS(6)},
61   { BALTIC_CHARSET, 1257, FS(7)},
62   /* reserved by ANSI */
63   { DEFAULT_CHARSET, 0, FS(0)},
64   { DEFAULT_CHARSET, 0, FS(0)},
65   { DEFAULT_CHARSET, 0, FS(0)},
66   { DEFAULT_CHARSET, 0, FS(0)},
67   { DEFAULT_CHARSET, 0, FS(0)},
68   { DEFAULT_CHARSET, 0, FS(0)},
69   { DEFAULT_CHARSET, 0, FS(0)},
70   { DEFAULT_CHARSET, 0, FS(0)},
71   /* ANSI and OEM */
72   { THAI_CHARSET,  874,  FS(16)},
73   { SHIFTJIS_CHARSET, 932, FS(17)},
74   { GB2312_CHARSET, 936, FS(18)},
75   { HANGEUL_CHARSET, 949, FS(19)},
76   { CHINESEBIG5_CHARSET, 950, FS(20)},
77   { JOHAB_CHARSET, 1361, FS(21)}, 
78   /* reserved for alternate ANSI and OEM */
79   { DEFAULT_CHARSET, 0, FS(0)},
80   { DEFAULT_CHARSET, 0, FS(0)},
81   { DEFAULT_CHARSET, 0, FS(0)},
82   { DEFAULT_CHARSET, 0, FS(0)},
83   { DEFAULT_CHARSET, 0, FS(0)},
84   { DEFAULT_CHARSET, 0, FS(0)},
85   { DEFAULT_CHARSET, 0, FS(0)},
86   { DEFAULT_CHARSET, 0, FS(0)},
87   /* reserved for system */
88   { DEFAULT_CHARSET, 0, FS(0)},
89   { DEFAULT_CHARSET, 0, FS(0)},
90 };
91
92 /***********************************************************************
93  *              LOGFONT conversion functions.
94  */
95 void FONT_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
96 {
97     font16->lfHeight = font32->lfHeight;
98     font16->lfWidth = font32->lfWidth;
99     font16->lfEscapement = font32->lfEscapement;
100     font16->lfOrientation = font32->lfOrientation;
101     font16->lfWeight = font32->lfWeight;
102     font16->lfItalic = font32->lfItalic;
103     font16->lfUnderline = font32->lfUnderline;
104     font16->lfStrikeOut = font32->lfStrikeOut;
105     font16->lfCharSet = font32->lfCharSet;
106     font16->lfOutPrecision = font32->lfOutPrecision;
107     font16->lfClipPrecision = font32->lfClipPrecision;
108     font16->lfQuality = font32->lfQuality;
109     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
110     lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
111 }
112
113 void FONT_LogFont32WTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
114 {
115     font16->lfHeight = font32->lfHeight;
116     font16->lfWidth = font32->lfWidth;
117     font16->lfEscapement = font32->lfEscapement;
118     font16->lfOrientation = font32->lfOrientation;
119     font16->lfWeight = font32->lfWeight;
120     font16->lfItalic = font32->lfItalic;
121     font16->lfUnderline = font32->lfUnderline;
122     font16->lfStrikeOut = font32->lfStrikeOut;
123     font16->lfCharSet = font32->lfCharSet;
124     font16->lfOutPrecision = font32->lfOutPrecision;
125     font16->lfClipPrecision = font32->lfClipPrecision;
126     font16->lfQuality = font32->lfQuality;
127     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
128     lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
129 }
130
131 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONTA font32 )
132 {
133     font32->lfHeight = font16->lfHeight;
134     font32->lfWidth = font16->lfWidth;
135     font32->lfEscapement = font16->lfEscapement;
136     font32->lfOrientation = font16->lfOrientation;
137     font32->lfWeight = font16->lfWeight;
138     font32->lfItalic = font16->lfItalic;
139     font32->lfUnderline = font16->lfUnderline;
140     font32->lfStrikeOut = font16->lfStrikeOut;
141     font32->lfCharSet = font16->lfCharSet;
142     font32->lfOutPrecision = font16->lfOutPrecision;
143     font32->lfClipPrecision = font16->lfClipPrecision;
144     font32->lfQuality = font16->lfQuality;
145     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
146     lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
147 }
148
149 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONTW font32 )
150 {
151     font32->lfHeight = font16->lfHeight;
152     font32->lfWidth = font16->lfWidth;
153     font32->lfEscapement = font16->lfEscapement;
154     font32->lfOrientation = font16->lfOrientation;
155     font32->lfWeight = font16->lfWeight;
156     font32->lfItalic = font16->lfItalic;
157     font32->lfUnderline = font16->lfUnderline;
158     font32->lfStrikeOut = font16->lfStrikeOut;
159     font32->lfCharSet = font16->lfCharSet;
160     font32->lfOutPrecision = font16->lfOutPrecision;
161     font32->lfClipPrecision = font16->lfClipPrecision;
162     font32->lfQuality = font16->lfQuality;
163     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
164     lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
165 }
166
167 void FONT_EnumLogFontEx16To32A( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXA font32 )
168 {
169     FONT_LogFont16To32A( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
170     lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
171     lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
172     lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
173 }
174
175 void FONT_EnumLogFontEx16To32W( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXW font32 )
176 {
177     FONT_LogFont16To32W( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
178     lstrcpynAtoW( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
179     lstrcpynAtoW( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
180     lstrcpynAtoW( font32->elfScript, font16->elfScript, LF_FACESIZE );
181 }
182
183 /***********************************************************************
184  *              TEXTMETRIC conversion functions.
185  */
186 void FONT_TextMetric32Ato16(const LPTEXTMETRICA ptm32, LPTEXTMETRIC16 ptm16 )
187 {
188     ptm16->tmHeight = ptm32->tmHeight;
189     ptm16->tmAscent = ptm32->tmAscent;
190     ptm16->tmDescent = ptm32->tmDescent;
191     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
192     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
193     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
194     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
195     ptm16->tmWeight = ptm32->tmWeight;
196     ptm16->tmOverhang = ptm32->tmOverhang;
197     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
198     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
199     ptm16->tmFirstChar = ptm32->tmFirstChar;
200     ptm16->tmLastChar = ptm32->tmLastChar;
201     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
202     ptm16->tmBreakChar = ptm32->tmBreakChar;
203     ptm16->tmItalic = ptm32->tmItalic;
204     ptm16->tmUnderlined = ptm32->tmUnderlined;
205     ptm16->tmStruckOut = ptm32->tmStruckOut;
206     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
207     ptm16->tmCharSet = ptm32->tmCharSet;
208 }
209
210 void FONT_TextMetric32Wto16(const LPTEXTMETRICW ptm32, LPTEXTMETRIC16 ptm16 )
211 {
212     ptm16->tmHeight = ptm32->tmHeight;
213     ptm16->tmAscent = ptm32->tmAscent;
214     ptm16->tmDescent = ptm32->tmDescent;
215     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
216     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
217     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
218     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
219     ptm16->tmWeight = ptm32->tmWeight;
220     ptm16->tmOverhang = ptm32->tmOverhang;
221     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
222     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
223     ptm16->tmFirstChar = ptm32->tmFirstChar;
224     ptm16->tmLastChar = ptm32->tmLastChar;
225     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
226     ptm16->tmBreakChar = ptm32->tmBreakChar;
227     ptm16->tmItalic = ptm32->tmItalic;
228     ptm16->tmUnderlined = ptm32->tmUnderlined;
229     ptm16->tmStruckOut = ptm32->tmStruckOut;
230     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
231     ptm16->tmCharSet = ptm32->tmCharSet;
232 }
233
234 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICA ptm32 )
235 {
236     ptm32->tmHeight = ptm16->tmHeight;
237     ptm32->tmAscent = ptm16->tmAscent;
238     ptm32->tmDescent = ptm16->tmDescent;
239     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
240     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
241     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
242     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
243     ptm32->tmWeight = ptm16->tmWeight;
244     ptm32->tmOverhang = ptm16->tmOverhang;
245     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
246     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
247     ptm32->tmFirstChar = ptm16->tmFirstChar;
248     ptm32->tmLastChar = ptm16->tmLastChar;
249     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
250     ptm32->tmBreakChar = ptm16->tmBreakChar;
251     ptm32->tmItalic = ptm16->tmItalic;
252     ptm32->tmUnderlined = ptm16->tmUnderlined;
253     ptm32->tmStruckOut = ptm16->tmStruckOut;
254     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
255     ptm32->tmCharSet = ptm16->tmCharSet;
256 }
257
258 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICW ptm32 )
259 {
260     ptm32->tmHeight = ptm16->tmHeight;
261     ptm32->tmAscent = ptm16->tmAscent;
262     ptm32->tmDescent = ptm16->tmDescent;
263     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
264     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
265     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
266     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
267     ptm32->tmWeight = ptm16->tmWeight;
268     ptm32->tmOverhang = ptm16->tmOverhang;
269     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
270     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
271     ptm32->tmFirstChar = ptm16->tmFirstChar;
272     ptm32->tmLastChar = ptm16->tmLastChar;
273     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
274     ptm32->tmBreakChar = ptm16->tmBreakChar;
275     ptm32->tmItalic = ptm16->tmItalic;
276     ptm32->tmUnderlined = ptm16->tmUnderlined;
277     ptm32->tmStruckOut = ptm16->tmStruckOut;
278     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
279     ptm32->tmCharSet = ptm16->tmCharSet;
280 }
281
282 void FONT_TextMetric32Ato32W(const LPTEXTMETRICA ptm32A, LPTEXTMETRICW ptm32W )
283 {
284     ptm32W->tmHeight = ptm32A->tmHeight;
285     ptm32W->tmAscent = ptm32A->tmAscent;
286     ptm32W->tmDescent = ptm32A->tmDescent;
287     ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
288     ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
289     ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
290     ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
291     ptm32W->tmWeight = ptm32A->tmWeight;
292     ptm32W->tmOverhang = ptm32A->tmOverhang;
293     ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
294     ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
295     ptm32W->tmFirstChar = ptm32A->tmFirstChar;
296     ptm32W->tmLastChar = ptm32A->tmLastChar;
297     ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
298     ptm32W->tmBreakChar = ptm32A->tmBreakChar;
299     ptm32W->tmItalic = ptm32A->tmItalic;
300     ptm32W->tmUnderlined = ptm32A->tmUnderlined;
301     ptm32W->tmStruckOut = ptm32A->tmStruckOut;
302     ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
303     ptm32W->tmCharSet = ptm32A->tmCharSet;
304 }
305
306 /***********************************************************************
307  *           CreateFontIndirect16   (GDI.57)
308  */
309 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
310 {
311     HFONT16 hFont = 0;
312
313     if (font)
314     {
315         hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
316         if( hFont )
317         {
318             FONTOBJ* fontPtr;
319             fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
320             memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
321
322             TRACE("(%i %i %i %i) '%s' %s %s => %04x\n",
323                   font->lfHeight, font->lfWidth, 
324                   font->lfEscapement, font->lfOrientation,
325                   font->lfFaceName ? font->lfFaceName : "NULL",
326                   font->lfWeight > 400 ? "Bold" : "",
327                   font->lfItalic ? "Italic" : "", hFont);
328
329             if (font->lfEscapement != font->lfOrientation) {
330               /* this should really depend on whether GM_ADVANCED is set */
331               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
332               WARN("orientation angle %f set to "
333                    "escapement angle %f for new font %04x\n", 
334                    font->lfOrientation/10., font->lfEscapement/10., hFont);
335             }
336             GDI_HEAP_UNLOCK( hFont );
337         }
338     }
339     else WARN("(NULL) => NULL\n");
340
341     return hFont;
342 }
343
344 /***********************************************************************
345  *           CreateFontIndirectA   (GDI32.44)
346  */
347 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *font )
348 {
349     LOGFONT16 font16;
350
351     FONT_LogFont32ATo16( font, &font16 );
352     return CreateFontIndirect16( &font16 );
353 }
354
355 /***********************************************************************
356  *           CreateFontIndirectW   (GDI32.45)
357  */
358 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *font )
359 {
360     LOGFONT16 font16;
361
362     FONT_LogFont32WTo16( font, &font16 );
363     return CreateFontIndirect16( &font16 );
364 }
365
366 /***********************************************************************
367  *           CreateFont16    (GDI.56)
368  */
369 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
370                             INT16 weight, BYTE italic, BYTE underline,
371                             BYTE strikeout, BYTE charset, BYTE outpres,
372                             BYTE clippres, BYTE quality, BYTE pitch,
373                             LPCSTR name )
374 {
375     LOGFONT16 logfont;
376
377     TRACE("('%s',%d,%d)\n", (name ? name : "(null)") , height, width);
378
379     logfont.lfHeight = height;
380     logfont.lfWidth = width;
381     logfont.lfEscapement = esc;
382     logfont.lfOrientation = orient;
383     logfont.lfWeight = weight;
384     logfont.lfItalic = italic;
385     logfont.lfUnderline = underline;
386     logfont.lfStrikeOut = strikeout;
387     logfont.lfCharSet = charset;
388     logfont.lfOutPrecision = outpres;
389     logfont.lfClipPrecision = clippres;
390     logfont.lfQuality = quality;
391     logfont.lfPitchAndFamily = pitch;
392    
393     if (name) 
394         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
395     else 
396         logfont.lfFaceName[0] = '\0';
397
398     return CreateFontIndirect16( &logfont );
399 }
400
401 /*************************************************************************
402  *           CreateFontA    (GDI32.43)
403  */
404 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
405                               INT orient, INT weight, DWORD italic,
406                               DWORD underline, DWORD strikeout, DWORD charset,
407                               DWORD outpres, DWORD clippres, DWORD quality,
408                               DWORD pitch, LPCSTR name )
409 {
410     return (HFONT)CreateFont16( height, width, esc, orient, weight, italic,
411                                   underline, strikeout, charset, outpres,
412                                   clippres, quality, pitch, name );
413 }
414
415 /*************************************************************************
416  *           CreateFontW    (GDI32.46)
417  */
418 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
419                               INT orient, INT weight, DWORD italic,
420                               DWORD underline, DWORD strikeout, DWORD charset,
421                               DWORD outpres, DWORD clippres, DWORD quality,
422                               DWORD pitch, LPCWSTR name )
423 {
424     LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
425     HFONT ret = (HFONT)CreateFont16( height, width, esc, orient, weight,
426                                          italic, underline, strikeout, charset,
427                                          outpres, clippres, quality, pitch,
428                                          namea );
429     if (namea) HeapFree( GetProcessHeap(), 0, namea );
430     return ret;
431 }
432
433
434 /***********************************************************************
435  *           FONT_GetObject16
436  */
437 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
438 {
439     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
440     memcpy( buffer, &font->logfont, count );
441     return count;
442 }
443
444 /***********************************************************************
445  *           FONT_GetObjectA
446  */
447 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
448 {
449     LOGFONTA fnt32;
450
451     FONT_LogFont16To32A( &font->logfont, &fnt32 );
452
453     if (count > sizeof(fnt32)) count = sizeof(fnt32);
454     memcpy( buffer, &fnt32, count );
455     return count;
456 }
457 /***********************************************************************
458  *           FONT_GetObjectW
459  */
460 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
461 {
462     LOGFONTW fnt32;
463
464     FONT_LogFont16To32W( &font->logfont, &fnt32 );
465
466     if (count > sizeof(fnt32)) count = sizeof(fnt32);
467     memcpy( buffer, &fnt32, count );
468     return count;
469 }
470
471
472 /***********************************************************************
473  *              FONT_EnumInstance16
474  *
475  * Called by the device driver layer to pass font info
476  * down to the application.
477  */
478 static INT FONT_EnumInstance16( LPENUMLOGFONTEX16 plf, 
479                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
480 {
481 #define pfe ((fontEnum16*)lp)
482     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
483         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
484     {
485         memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
486         memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
487
488         return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
489     }
490 #undef pfe
491     return 1;
492 }
493
494 /***********************************************************************
495  *              FONT_EnumInstance
496  */
497 static INT FONT_EnumInstance( LPENUMLOGFONTEX16 plf,
498                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
499 {
500     /* lfCharSet is at the same offset in both LOGFONT32A and LOGFONT32W */
501
502 #define pfe ((fontEnum32*)lp)
503     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
504         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
505     {
506         /* convert font metrics */
507
508         if( pfe->dwFlags & ENUM_UNICODE )
509         {
510             FONT_EnumLogFontEx16To32W( plf, pfe->lpLogFont );
511             FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICW)(pfe->lpTextMetric) );
512         
513             return pfe->lpEnumFunc( pfe->lpLogFont, pfe->lpTextMetric, fType, pfe->lpData );
514         }
515         else
516         {
517             ENUMLOGFONTEXA logfont;
518
519             FONT_EnumLogFontEx16To32A( plf, &logfont);
520             FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICA)pfe->lpTextMetric );
521
522             return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, 
523                                 pfe->lpTextMetric, fType, pfe->lpData );
524         }
525     }
526 #undef pfe
527     return 1;
528 }
529
530 /***********************************************************************
531  *              EnumFontFamiliesEx16    (GDI.613)
532  */
533 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
534                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
535                                    DWORD dwFlags)
536 {
537     INT16       retVal = 0;
538     DC*         dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
539
540     if( dc && dc->funcs->pEnumDeviceFonts )
541     {
542         LPNEWTEXTMETRICEX16     lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
543         if( lptm16 )
544         {
545             LPENUMLOGFONTEX16   lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
546             if( lplf16 )
547             {
548                 fontEnum16      fe16;
549
550                 fe16.lpLogFontParam = plf;
551                 fe16.lpEnumFunc = efproc;
552                 fe16.lpData = lParam;
553                 
554                 fe16.lpTextMetric = lptm16;
555                 fe16.lpLogFont = lplf16;
556                 fe16.segTextMetric = SEGPTR_GET(lptm16);
557                 fe16.segLogFont = SEGPTR_GET(lplf16);
558
559                 retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
560
561                 SEGPTR_FREE(lplf16);
562             }
563             SEGPTR_FREE(lptm16);
564         }
565     }
566     return retVal;
567 }
568
569 /***********************************************************************
570  *              FONT_EnumFontFamiliesEx
571  */
572 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc, 
573                                                    LPARAM lParam, DWORD dwUnicode)
574 {
575     DC*         dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
576
577     if( dc && dc->funcs->pEnumDeviceFonts )
578     {
579         LOGFONT16               lf16;
580         NEWTEXTMETRICEXW        tm32w;
581         ENUMLOGFONTEXW  lf32w;
582         fontEnum32              fe32;
583
584         fe32.lpLogFontParam = plf;
585         fe32.lpEnumFunc = efproc;
586         fe32.lpData = lParam;
587         
588         fe32.lpTextMetric = &tm32w;
589         fe32.lpLogFont = &lf32w;
590         fe32.dwFlags = dwUnicode;
591
592         /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
593
594         if( plf->lfFaceName[0] )
595         {
596             if( dwUnicode )
597                 lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
598             else
599                 lstrcpynA( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
600         }
601         else lf16.lfFaceName[0] = '\0';
602         lf16.lfCharSet = plf->lfCharSet;
603
604         return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
605     }
606     return 0;
607 }
608
609 /***********************************************************************
610  *              EnumFontFamiliesExW     (GDI32.82)
611  */
612 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
613                                     FONTENUMPROCEXW efproc, 
614                                     LPARAM lParam, DWORD dwFlags )
615 {
616     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
617 }
618
619 /***********************************************************************
620  *              EnumFontFamiliesExA     (GDI32.81)
621  */
622 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
623                                     FONTENUMPROCEXA efproc, 
624                                     LPARAM lParam, DWORD dwFlags)
625 {
626     return  FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)plf, 
627                                       (FONTENUMPROCEXW)efproc, lParam, 0);
628 }
629
630 /***********************************************************************
631  *              EnumFontFamilies16      (GDI.330)
632  */
633 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
634                                  FONTENUMPROC16 efproc, LPARAM lpData )
635 {
636     LOGFONT16   lf;
637
638     lf.lfCharSet = DEFAULT_CHARSET;
639     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
640     else lf.lfFaceName[0] = '\0';
641
642     return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
643 }
644
645 /***********************************************************************
646  *              EnumFontFamiliesA       (GDI32.80)
647  */
648 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
649                                   FONTENUMPROCA efproc, LPARAM lpData )
650 {
651     LOGFONTA    lf;
652
653     lf.lfCharSet = DEFAULT_CHARSET;
654     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
655     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
656
657     return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)&lf, 
658                                            (FONTENUMPROCEXW)efproc, lpData, 0 );
659 }
660
661 /***********************************************************************
662  *              EnumFontFamiliesW       (GDI32.83)
663  */
664 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
665                                   FONTENUMPROCW efproc, LPARAM lpData )
666 {
667     LOGFONTW  lf;
668
669     lf.lfCharSet = DEFAULT_CHARSET;
670     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
671     else lf.lfFaceName[0] = 0;
672
673     return FONT_EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROCEXW)efproc, 
674                                                 lpData, ENUM_UNICODE );
675 }
676
677 /***********************************************************************
678  *              EnumFonts16             (GDI.70)
679  */
680 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
681                           LPARAM lpData )
682 {
683     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
684 }
685
686 /***********************************************************************
687  *              EnumFontsA              (GDI32.84)
688  */
689 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
690                            LPARAM lpData )
691 {
692     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
693 }
694
695 /***********************************************************************
696  *              EnumFontsW              (GDI32.85)
697  */
698 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
699                            LPARAM lpData )
700 {
701     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
702 }
703
704
705 /***********************************************************************
706  *           GetTextCharacterExtra16    (GDI.89)
707  */
708 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
709 {
710     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
711     if (!dc) return 0;
712     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
713                  / dc->vportExtX );
714 }
715
716
717 /***********************************************************************
718  *           GetTextCharacterExtra    (GDI32.225)
719  */
720 INT WINAPI GetTextCharacterExtra( HDC hdc )
721 {
722     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
723     if (!dc) return 0;
724     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
725                  / dc->vportExtX );
726 }
727
728
729 /***********************************************************************
730  *           SetTextCharacterExtra16    (GDI.8)
731  */
732 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
733 {
734     return (INT16)SetTextCharacterExtra( hdc, extra );
735 }
736
737
738 /***********************************************************************
739  *           SetTextCharacterExtra    (GDI32.337)
740  */
741 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
742 {
743     INT prev;
744     DC * dc = DC_GetDCPtr( hdc );
745     if (!dc) return 0;
746     if (dc->funcs->pSetTextCharacterExtra)
747         return dc->funcs->pSetTextCharacterExtra( dc, extra );
748     extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
749     prev = dc->w.charExtra;
750     dc->w.charExtra = abs(extra);
751     return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
752 }
753
754
755 /***********************************************************************
756  *           SetTextJustification16    (GDI.10)
757  */
758 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
759 {
760     return SetTextJustification( hdc, extra, breaks );
761 }
762
763
764 /***********************************************************************
765  *           SetTextJustification    (GDI32.339)
766  */
767 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
768 {
769     DC * dc = DC_GetDCPtr( hdc );
770     if (!dc) return 0;
771     if (dc->funcs->pSetTextJustification)
772         return dc->funcs->pSetTextJustification( dc, extra, breaks );
773
774     extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
775     if (!extra) breaks = 0;
776     dc->w.breakTotalExtra = extra;
777     dc->w.breakCount = breaks;
778     if (breaks)
779     {
780         dc->w.breakExtra = extra / breaks;
781         dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
782     }
783     else
784     {
785         dc->w.breakExtra = 0;
786         dc->w.breakRem   = 0;
787     }
788     return 1;
789 }
790
791
792 /***********************************************************************
793  *           GetTextFace16    (GDI.92)
794  */
795 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
796 {
797         return GetTextFaceA(hdc,count,name);
798 }
799
800 /***********************************************************************
801  *           GetTextFaceA    (GDI32.234)
802  */
803 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
804 {
805     FONTOBJ *font;
806
807     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
808     if (!dc) return 0;
809     if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
810         return 0;
811     if (name) 
812         lstrcpynA( name, font->logfont.lfFaceName, count );
813     GDI_HEAP_UNLOCK( dc->w.hFont );
814     if (name)
815         return strlen(name);
816     else
817         return strlen(font->logfont.lfFaceName) + 1;
818 }
819
820 /***********************************************************************
821  *           GetTextFaceW    (GDI32.235)
822  */
823 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
824 {
825     LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
826     INT res = GetTextFaceA(hdc,count,nameA);
827     lstrcpyAtoW( name, nameA );
828     HeapFree( GetProcessHeap(), 0, nameA );
829     return res;
830 }
831
832
833 /***********************************************************************
834  *           GetTextExtent16    (GDI.91)
835  */
836 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
837 {
838     SIZE16 size;
839     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
840     return MAKELONG( size.cx, size.cy );
841 }
842
843
844 /***********************************************************************
845  *           GetTextExtentPoint16    (GDI.471)
846  *
847  * FIXME: Should this have a bug for compatibility?
848  * Original Windows versions of GetTextExtentPoint{A,W} have documented
849  * bugs (-> MSDN KB q147647.txt).
850  */
851 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
852                                     LPSIZE16 size )
853 {
854     SIZE size32;
855     BOOL ret;
856     TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count,
857           size);
858     ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
859     CONV_SIZE32TO16( &size32, size );
860     return (BOOL16)ret;
861 }
862
863
864 /***********************************************************************
865  *           GetTextExtentPoint32A    (GDI32.230)
866  */
867 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
868                                      LPSIZE size )
869 {
870     LPWSTR p;
871     BOOL ret;
872
873   /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
874    * We allocate one more than we need so that lstrcpynWtoA can write a
875    * trailing 0 if it wants.
876    */
877
878     p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
879     lstrcpynAtoW(p, str, count+1);
880     ret = GetTextExtentPoint32W( hdc, p, count, size );
881     HeapFree( GetProcessHeap(), 0, p );
882     return ret;
883 }
884
885
886 /***********************************************************************
887  * GetTextExtentPoint32W [GDI32.231]  Computes width/height for a string
888  *
889  * Computes width and height of the specified string.
890  *
891  * RETURNS
892  *    Success: TRUE
893  *    Failure: FALSE
894  */
895 BOOL WINAPI GetTextExtentPoint32W(
896     HDC hdc,     /* [in]  Handle of device context */
897     LPCWSTR str,   /* [in]  Address of text string */
898     INT count,   /* [in]  Number of characters in string */
899     LPSIZE size) /* [out] Address of structure for string size */
900 {
901     DC * dc = DC_GetDCPtr( hdc );
902     if (!dc || !dc->funcs->pGetTextExtentPoint ||
903         !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
904         return FALSE;
905
906     TRACE("(%08x %s %d %p): returning %d,%d\n",
907           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
908     return TRUE;
909 }
910
911
912 /***********************************************************************
913  *           GetTextExtentPointA    (GDI32.232)
914  */
915 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
916                                           LPSIZE size )
917 {
918     TRACE("not bug compatible.\n");
919     return GetTextExtentPoint32A( hdc, str, count, size );
920 }
921
922 /***********************************************************************
923  *           GetTextExtentPointW   (GDI32.233)
924  */
925 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
926                                           LPSIZE size )
927 {
928     TRACE("not bug compatible.\n");
929     return GetTextExtentPoint32W( hdc, str, count, size );
930 }
931
932
933 /***********************************************************************
934  *           GetTextExtentExPointA    (GDI32.228)
935  */
936 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
937                                    INT maxExt, LPINT lpnFit,
938                                    LPINT alpDx, LPSIZE size )
939 {
940     LPWSTR p;
941     BOOL ret;
942
943   /* Docs say str should be 0 terminated here, but we'll use count just in case
944    */ 
945
946     p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
947     lstrcpynAtoW(p, str, count+1);
948     ret = GetTextExtentExPointW( hdc, p, count, maxExt, lpnFit, alpDx, size);
949     HeapFree( GetProcessHeap(), 0, p );
950     return ret;
951 }
952
953
954 /***********************************************************************
955  *           GetTextExtentExPointW    (GDI32.229)
956  */
957
958 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
959                                    INT maxExt, LPINT lpnFit,
960                                    LPINT alpDx, LPSIZE size )
961 {
962     int index, nFit, extent;
963     SIZE tSize;
964     DC * dc = DC_GetDCPtr( hdc );
965
966     if (!dc || !dc->funcs->pGetTextExtentPoint) return FALSE;
967
968     size->cx = size->cy = nFit = extent = 0;
969     for(index = 0; index < count; index++)
970     {
971         if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
972         if( extent+tSize.cx < maxExt )
973         {
974             extent+=tSize.cx;
975             nFit++;
976             str++;
977             if( alpDx ) alpDx[index] = extent;
978             if( tSize.cy > size->cy ) size->cy = tSize.cy;
979         }
980         else break;
981     }
982     size->cx = extent;
983     *lpnFit = nFit;
984
985     TRACE("(%08x %s %d) returning %d %d %d\n",
986           hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
987     return TRUE;
988 }
989
990 /***********************************************************************
991  *           GetTextMetrics16    (GDI.93)
992  */
993 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
994 {
995     TEXTMETRICA tm32;
996
997     if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
998     FONT_TextMetric32Ato16( &tm32, metrics );
999     return TRUE;
1000 }
1001
1002
1003 /***********************************************************************
1004  *           GetTextMetricsA    (GDI32.236)
1005  */
1006 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1007 {
1008     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1009     if (!dc)
1010     {
1011         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1012             return FALSE;
1013     }
1014
1015     if (!dc->funcs->pGetTextMetrics ||
1016         !dc->funcs->pGetTextMetrics( dc, metrics ))
1017         return FALSE;
1018
1019     /* device layer returns values in device units
1020      * therefore we have to convert them to logical */
1021
1022 #define WDPTOLP(x) ((x<0)?                                      \
1023                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
1024                 (abs((x)*dc->wndExtX/dc->vportExtX)))
1025 #define HDPTOLP(y) ((y<0)?                                      \
1026                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
1027                 (abs((y)*dc->wndExtY/dc->vportExtY)))
1028         
1029     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1030     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1031     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1032     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1033     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1034     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1035     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1036     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1037
1038     TRACE("text metrics:\n"
1039           "    Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1040           "    Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1041           "    UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1042           "    StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1043           "    PitchAndFamily = %02x\n"
1044           "    --------------------\n"
1045           "    InternalLeading = %li\n"
1046           "    Ascent = %li\n"
1047           "    Descent = %li\n"
1048           "    Height = %li\n",
1049           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1050           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1051           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1052           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1053           metrics->tmPitchAndFamily,
1054           metrics->tmInternalLeading,
1055           metrics->tmAscent,
1056           metrics->tmDescent,
1057           metrics->tmHeight );
1058     return TRUE;
1059 }
1060
1061
1062 /***********************************************************************
1063  *           GetTextMetricsW    (GDI32.237)
1064  */
1065 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1066 {
1067     TEXTMETRICA tm;
1068     if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1069     FONT_TextMetric32Ato32W( &tm, metrics );
1070     return TRUE;
1071 }
1072
1073
1074 /***********************************************************************
1075  * GetOutlineTextMetrics16 [GDI.308]  Gets metrics for TrueType fonts.
1076  *
1077  * NOTES
1078  *    lpOTM should be LPOUTLINETEXTMETRIC
1079  *
1080  * RETURNS
1081  *    Success: Non-zero or size of required buffer
1082  *    Failure: 0
1083  */
1084 UINT16 WINAPI GetOutlineTextMetrics16(
1085     HDC16 hdc,    /* [in]  Handle of device context */
1086     UINT16 cbData, /* [in]  Size of metric data array */
1087     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1088 {
1089     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1090     return 0;
1091 }
1092
1093
1094 /***********************************************************************
1095  * GetOutlineTextMetricsA [GDI.207]  Gets metrics for TrueType fonts.
1096  *
1097  *
1098  * RETURNS
1099  *    Success: Non-zero or size of required buffer
1100  *    Failure: 0
1101  */
1102 UINT WINAPI GetOutlineTextMetricsA(
1103     HDC hdc,    /* [in]  Handle of device context */
1104     UINT cbData, /* [in]  Size of metric data array */
1105     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1106 {
1107
1108
1109     UINT rtn = FALSE;
1110     LPTEXTMETRICA lptxtMetr;
1111
1112
1113
1114     if (lpOTM == 0)
1115     {
1116         
1117         lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1118         rtn = sizeof(OUTLINETEXTMETRICA);
1119         cbData = rtn;
1120     } else
1121     {
1122         cbData = sizeof(*lpOTM);
1123         rtn = cbData;
1124     };
1125
1126     lpOTM->otmSize = cbData;
1127
1128     lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1129     
1130     if (!GetTextMetricsA(hdc,lptxtMetr))
1131     {
1132         return 0;
1133     } else
1134     {
1135        memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1136     };
1137
1138     HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1139     
1140     lpOTM->otmFilter = 0;
1141
1142     lpOTM->otmPanoseNumber.bFamilyType  = 0;
1143     lpOTM->otmPanoseNumber.bSerifStyle  = 0;
1144     lpOTM->otmPanoseNumber.bWeight      = 0;
1145     lpOTM->otmPanoseNumber.bProportion  = 0;
1146     lpOTM->otmPanoseNumber.bContrast    = 0;
1147     lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1148     lpOTM->otmPanoseNumber.bArmStyle    = 0;
1149     lpOTM->otmPanoseNumber.bLetterform  = 0;
1150     lpOTM->otmPanoseNumber.bMidline     = 0;
1151     lpOTM->otmPanoseNumber.bXHeight     = 0;
1152
1153     lpOTM->otmfsSelection     = 0;
1154     lpOTM->otmfsType          = 0;
1155
1156     /*
1157      Further fill of the structure not implemented,
1158      Needs real values for the structure members
1159      */
1160     
1161     return rtn;
1162 }
1163
1164 /***********************************************************************
1165  *           GetOutlineTextMetricsW [GDI32.208]
1166  */
1167 UINT WINAPI GetOutlineTextMetricsW(
1168     HDC hdc,    /* [in]  Handle of device context */
1169     UINT cbData, /* [in]  Size of metric data array */
1170     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1171 {
1172     FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1173     return 0; 
1174 }
1175
1176 /***********************************************************************
1177  *           GetCharWidth16    (GDI.350)
1178  */
1179 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1180                               LPINT16 buffer )
1181 {
1182     BOOL        retVal = FALSE;
1183
1184     if( firstChar != lastChar )
1185     {
1186         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1187                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1188         if( buf32 )
1189         {
1190             LPINT       obuf32 = buf32;
1191             int         i;
1192
1193             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1194             if (retVal)
1195             {
1196                 for (i = firstChar; i <= lastChar; i++)
1197                     *buffer++ = *buf32++;
1198             }
1199             HeapFree(GetProcessHeap(), 0, obuf32);
1200         }
1201     }
1202     else /* happens quite often to warrant a special treatment */
1203     {
1204         INT chWidth;
1205         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1206        *buffer = chWidth;
1207     }
1208     return retVal;
1209 }
1210
1211
1212 /***********************************************************************
1213  *           GetCharWidth32A    (GDI32.155)
1214  */
1215 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1216                                LPINT buffer )
1217 {
1218     UINT i, extra;
1219     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1220     if (!dc)
1221     {
1222         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1223             return FALSE;
1224     }
1225
1226     if (!dc->funcs->pGetCharWidth ||
1227         !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1228         return FALSE;
1229
1230     /* convert device units to logical */
1231
1232     extra = dc->vportExtX >> 1;
1233     for( i = firstChar; i <= lastChar; i++, buffer++ )
1234          *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1235
1236     return TRUE;
1237 }
1238
1239
1240 /***********************************************************************
1241  *           GetCharWidth32W    (GDI32.158)
1242  */
1243 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1244                                LPINT buffer )
1245 {
1246     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1247 }
1248
1249
1250
1251 /* FIXME: all following APIs *******************************************
1252  *
1253  *
1254  *           SetMapperFlags16    (GDI.349)
1255  */
1256 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1257 {
1258     return SetMapperFlags( hDC, dwFlag );
1259 }
1260
1261
1262 /***********************************************************************
1263  *           SetMapperFlags    (GDI32.322)
1264  */
1265 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1266 {
1267     DC *dc = DC_GetDCPtr( hDC );
1268     DWORD ret = 0; 
1269     if(!dc) return 0;
1270     if(dc->funcs->pSetMapperFlags)
1271         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1272     else
1273         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1274     GDI_HEAP_UNLOCK( hDC );
1275     return ret;
1276 }
1277
1278 /***********************************************************************
1279  *          GetAspectRatioFilterEx16  (GDI.486)
1280  */
1281 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1282 {
1283   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1284   return FALSE;
1285 }
1286
1287 /***********************************************************************
1288  *          GetAspectRatioFilterEx  (GDI32.142)
1289  */
1290 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1291 {
1292   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1293   return FALSE;
1294 }
1295
1296 /***********************************************************************
1297  *           GetCharABCWidths16   (GDI.307)
1298  */
1299 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1300                                   LPABC16 abc )
1301 {
1302     ABC abc32;
1303     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1304     abc->abcA = abc32.abcA;
1305     abc->abcB = abc32.abcB;
1306     abc->abcC = abc32.abcC;
1307     return TRUE;
1308 }
1309
1310
1311 /***********************************************************************
1312  *           GetCharABCWidthsA   (GDI32.149)
1313  */
1314 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1315                                   LPABC abc )
1316 {
1317     return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1318 }
1319
1320
1321 /******************************************************************************
1322  * GetCharABCWidthsW [GDI32.152]  Retrieves widths of characters in range
1323  *
1324  * PARAMS
1325  *    hdc       [I] Handle of device context
1326  *    firstChar [I] First character in range to query
1327  *    lastChar  [I] Last character in range to query
1328  *    abc       [O] Address of character-width structure
1329  *
1330  * NOTES
1331  *    Only works with TrueType fonts
1332  *
1333  * RETURNS
1334  *    Success: TRUE
1335  *    Failure: FALSE
1336  */
1337 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1338                                    LPABC abc )
1339 {
1340     /* No TrueType fonts in Wine so far */
1341     FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1342     return FALSE;
1343 }
1344
1345
1346 /***********************************************************************
1347  *           GetGlyphOutline16    (GDI.309)
1348  */
1349 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1350                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1351                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1352 {
1353     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1354           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1355     return (DWORD)-1; /* failure */
1356 }
1357
1358
1359 /***********************************************************************
1360  *           GetGlyphOutlineA    (GDI32.186)
1361  */
1362 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1363                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1364                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1365 {
1366     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1367           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1368     return (DWORD)-1; /* failure */
1369 }
1370
1371 /***********************************************************************
1372  *           GetGlyphOutlineW    (GDI32.187)
1373  */
1374 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1375                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1376                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1377 {
1378     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1379           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1380     return (DWORD)-1; /* failure */
1381 }
1382
1383 /***********************************************************************
1384  *           CreateScalableFontResource16   (GDI.310)
1385  */
1386 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1387                                             LPCSTR lpszResourceFile,
1388                                             LPCSTR fontFile, LPCSTR path )
1389 {
1390     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1391                                           fontFile, path );
1392 }
1393
1394 /***********************************************************************
1395  *           CreateScalableFontResourceA   (GDI32.62)
1396  */
1397 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1398                                              LPCSTR lpszResourceFile,
1399                                              LPCSTR lpszFontFile,
1400                                              LPCSTR lpszCurrentPath )
1401 {
1402     /* fHidden=1 - only visible for the calling app, read-only, not
1403      * enumbered with EnumFonts/EnumFontFamilies
1404      * lpszCurrentPath can be NULL
1405      */
1406     FIXME("(%ld,%s,%s,%s): stub\n",
1407           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1408     return FALSE; /* create failed */
1409 }
1410
1411 /***********************************************************************
1412  *           CreateScalableFontResourceW   (GDI32.63)
1413  */
1414 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1415                                              LPCWSTR lpszResourceFile,
1416                                              LPCWSTR lpszFontFile,
1417                                              LPCWSTR lpszCurrentPath )
1418 {
1419     FIXME("(%ld,%p,%p,%p): stub\n",
1420           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1421     return FALSE; /* create failed */
1422 }
1423
1424
1425 /*************************************************************************
1426  *             GetRasterizerCaps16   (GDI.313)
1427  */
1428 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1429 {
1430     return GetRasterizerCaps( lprs, cbNumBytes );
1431 }
1432
1433
1434 /*************************************************************************
1435  *             GetRasterizerCaps   (GDI32.216)
1436  */
1437 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1438 {
1439   lprs->nSize = sizeof(RASTERIZER_STATUS);
1440   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1441   lprs->nLanguageID = 0;
1442   return TRUE;
1443 }
1444
1445
1446 /*************************************************************************
1447  *             GetKerningPairs16   (GDI.332)
1448  */
1449 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1450                                 LPKERNINGPAIR16 lpKerningPairs )
1451 {
1452     /* At this time kerning is ignored (set to 0) */
1453     int i;
1454     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1455     for (i = 0; i < cPairs; i++) 
1456         lpKerningPairs[i].iKernAmount = 0;
1457     return 0;
1458 }
1459
1460
1461
1462 /*************************************************************************
1463  *             GetKerningPairsA   (GDI32.192)
1464  */
1465 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1466                                  LPKERNINGPAIR lpKerningPairs )
1467 {
1468     int i;
1469     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1470     for (i = 0; i < cPairs; i++) 
1471         lpKerningPairs[i].iKernAmount = 0;
1472     return 0;
1473 }
1474
1475
1476 /*************************************************************************
1477  *             GetKerningPairsW   (GDI32.193)
1478  */
1479 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1480                                  LPKERNINGPAIR lpKerningPairs )
1481 {
1482     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1483 }
1484
1485 /*************************************************************************
1486  * TranslateCharsetInfo [GDI32.382]
1487  *
1488  * Fills a CHARSETINFO structure for a character set, code page, or
1489  * font. This allows making the correspondance between different labelings
1490  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1491  * of the same encoding.
1492  *
1493  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1494  * only one codepage should be set in *lpSrc.
1495  *
1496  * RETURNS
1497  *   TRUE on success, FALSE on failure.
1498  *
1499  */
1500 BOOL WINAPI TranslateCharsetInfo(
1501   LPDWORD lpSrc, /*
1502        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1503        if flags == TCI_SRCCHARSET: a character set value
1504        if flags == TCI_SRCCODEPAGE: a code page value
1505                  */
1506   LPCHARSETINFO lpCs, /* structure to receive charset information */
1507   DWORD flags /* determines interpretation of lpSrc */
1508 ) {
1509     int index = 0;
1510     switch (flags) {
1511     case TCI_SRCFONTSIG:
1512         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1513       break;
1514     case TCI_SRCCODEPAGE:
1515       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1516       break;
1517     case TCI_SRCCHARSET:
1518       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1519       break;
1520     default:
1521       return FALSE;
1522     }
1523     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1524     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1525     return TRUE;
1526 }
1527
1528 /*************************************************************************
1529  *             GetFontLanguageInfo   (GDI32.182)
1530  */
1531 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1532         /* return value 0 is correct for most cases anyway */
1533         FIXME("(%x):stub!\n", hdc);
1534         return 0;
1535 }
1536
1537 /*************************************************************************
1538  *             GetFontLanguageInfo   (GDI.616)
1539  */
1540 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1541         /* return value 0 is correct for most cases anyway */
1542         FIXME("(%x):stub!\n",hdc);
1543         return 0;
1544 }
1545
1546 /*************************************************************************
1547  * GetFontData [GDI32.181] Retrieve data for TrueType font
1548  *
1549  * RETURNS
1550  *
1551  * success: Number of bytes returned 
1552  * failure: GDI_ERROR
1553  *
1554  * NOTES
1555  *
1556  * Calls SetLastError()  
1557  *
1558  * BUGS
1559  *
1560  * Unimplemented
1561  */
1562 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1563     LPVOID buffer, DWORD length)
1564 {
1565     FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1566     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1567     return GDI_ERROR;
1568 }
1569
1570 /*************************************************************************
1571  * GetFontData16 [GDI.311]
1572  *
1573  */
1574 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1575                             LPVOID lpvBuffer, DWORD cbData)
1576 {
1577     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1578 }
1579
1580 /*************************************************************************
1581  * GetCharacterPlacementA [GDI32.160]
1582  *
1583  * NOTES:
1584  *  the web browser control of ie4 calls this with dwFlags=0
1585  */
1586 DWORD WINAPI
1587 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1588                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1589                          DWORD dwFlags)
1590 {
1591     DWORD ret=0;
1592     SIZE size;
1593
1594     TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1595           debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1596
1597     TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1598           "lpOutString=%p lpGlyphs=%p\n",
1599           lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1600           lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1601
1602     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
1603     if(lpResults->lpOrder)      FIXME("reordering not implemented\n");
1604     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1605     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1606     if(lpResults->lpGlyphs)     FIXME("glyphs not implemented\n");
1607
1608     /* copy will do if the GCP_REORDER flag is not set */
1609     if(lpResults->lpOutString)
1610     {
1611       lstrcpynA(lpResults->lpOutString, lpString, uCount);
1612     }
1613
1614     if (lpResults->lpDx)
1615     {
1616       int i, c;
1617       for (i=0; i<uCount;i++)
1618       { 
1619         if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1620           lpResults->lpDx[i]= c;
1621       }
1622     }
1623
1624     if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1625       ret = MAKELONG(size.cx, size.cy);
1626
1627     return ret;
1628 }
1629
1630 /*************************************************************************
1631  * GetCharacterPlacementW [GDI32.161]
1632  */
1633 DWORD WINAPI
1634 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1635                          INT nMaxExtent, GCP_RESULTSW *lpResults,
1636                          DWORD dwFlags)
1637 {
1638     /* return value 0 is correct for most cases anyway */
1639     FIXME(":stub!\n");
1640     return 0;
1641 }
1642
1643 /*************************************************************************
1644  *      GetCharABCWidthsFloatA [GDI32.150]
1645  */
1646 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1647                                         LPABCFLOAT lpABCF)
1648 {
1649        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1650        return 0;
1651 }
1652
1653 /*************************************************************************
1654  *      GetCharABCWidthsFloatW [GDI32.151]
1655  */
1656 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1657                                         UINT iLastChar, LPABCFLOAT lpABCF)
1658 {
1659        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1660        return 0;
1661 }
1662
1663 /*************************************************************************
1664  *      GetCharWidthFloatA [GDI32.156]
1665  */
1666 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1667                                     UINT iLastChar, PFLOAT pxBuffer)
1668 {
1669        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1670        return 0;
1671 }
1672
1673 /*************************************************************************
1674  *      GetCharWidthFloatW [GDI32.157]
1675  */
1676 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1677                                     UINT iLastChar, PFLOAT pxBuffer)
1678 {
1679        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1680        return 0;
1681 }
1682