Some -DSTRICT fixes.
[wine] / objects / font.c
1 /*
2  * GDI font objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *           1997 Alex Korobka
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 "config.h"
23 #include "wine/port.h"
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include "winerror.h"
29 #include "winnls.h"
30 #include "wownt32.h"
31 #include "wine/unicode.h"
32 #include "font.h"
33 #include "wine/debug.h"
34 #include "gdi.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(font);
37 WINE_DECLARE_DEBUG_CHANNEL(gdi);
38
39 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
40 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
43 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
44
45 static const struct gdi_obj_funcs font_funcs =
46 {
47     FONT_SelectObject,  /* pSelectObject */
48     FONT_GetObject16,   /* pGetObject16 */
49     FONT_GetObjectA,    /* pGetObjectA */
50     FONT_GetObjectW,    /* pGetObjectW */
51     NULL,               /* pUnrealizeObject */
52     FONT_DeleteObject   /* pDeleteObject */
53 };
54
55 #define ENUM_UNICODE    0x00000001
56 #define ENUM_CALLED     0x00000002
57
58 typedef struct
59 {
60     GDIOBJHDR   header;
61     LOGFONTW    logfont;
62 } FONTOBJ;
63
64 typedef struct
65 {
66   LPLOGFONT16           lpLogFontParam;
67   FONTENUMPROC16        lpEnumFunc;
68   LPARAM                lpData;
69
70   LPNEWTEXTMETRICEX16   lpTextMetric;
71   LPENUMLOGFONTEX16     lpLogFont;
72   SEGPTR                segTextMetric;
73   SEGPTR                segLogFont;
74   HDC                   hdc;
75   DC                   *dc;
76   PHYSDEV               physDev;
77 } fontEnum16;
78
79 typedef struct
80 {
81   LPLOGFONTW          lpLogFontParam;
82   FONTENUMPROCW       lpEnumFunc;
83   LPARAM              lpData;
84   DWORD               dwFlags;
85   HDC                 hdc;
86   DC                 *dc;
87   PHYSDEV             physDev;
88 } fontEnum32;
89
90 /*
91  *  For TranslateCharsetInfo
92  */
93 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
94 #define MAXTCIINDEX 32
95 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
96   /* ANSI */
97   { ANSI_CHARSET, 1252, FS(0)},
98   { EASTEUROPE_CHARSET, 1250, FS(1)},
99   { RUSSIAN_CHARSET, 1251, FS(2)},
100   { GREEK_CHARSET, 1253, FS(3)},
101   { TURKISH_CHARSET, 1254, FS(4)},
102   { HEBREW_CHARSET, 1255, FS(5)},
103   { ARABIC_CHARSET, 1256, FS(6)},
104   { BALTIC_CHARSET, 1257, FS(7)},
105   { VIETNAMESE_CHARSET, 1258, FS(8)},
106   /* reserved by ANSI */
107   { DEFAULT_CHARSET, 0, FS(0)},
108   { DEFAULT_CHARSET, 0, FS(0)},
109   { DEFAULT_CHARSET, 0, FS(0)},
110   { DEFAULT_CHARSET, 0, FS(0)},
111   { DEFAULT_CHARSET, 0, FS(0)},
112   { DEFAULT_CHARSET, 0, FS(0)},
113   { DEFAULT_CHARSET, 0, FS(0)},
114   /* ANSI and OEM */
115   { THAI_CHARSET,  874,  FS(16)},
116   { SHIFTJIS_CHARSET, 932, FS(17)},
117   { GB2312_CHARSET, 936, FS(18)},
118   { HANGEUL_CHARSET, 949, FS(19)},
119   { CHINESEBIG5_CHARSET, 950, FS(20)},
120   { JOHAB_CHARSET, 1361, FS(21)},
121   /* reserved for alternate ANSI and OEM */
122   { DEFAULT_CHARSET, 0, FS(0)},
123   { DEFAULT_CHARSET, 0, FS(0)},
124   { DEFAULT_CHARSET, 0, FS(0)},
125   { DEFAULT_CHARSET, 0, FS(0)},
126   { DEFAULT_CHARSET, 0, FS(0)},
127   { DEFAULT_CHARSET, 0, FS(0)},
128   { DEFAULT_CHARSET, 0, FS(0)},
129   { DEFAULT_CHARSET, 0, FS(0)},
130   /* reserved for system */
131   { DEFAULT_CHARSET, 0, FS(0)},
132   { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
133 };
134
135 /* ### start build ### */
136 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROC16,LONG,LONG,WORD,LONG);
137 /* ### stop build ### */
138
139 /***********************************************************************
140  *              LOGFONT conversion functions.
141  */
142 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
143 {
144     font16->lfHeight = font32->lfHeight;
145     font16->lfWidth = font32->lfWidth;
146     font16->lfEscapement = font32->lfEscapement;
147     font16->lfOrientation = font32->lfOrientation;
148     font16->lfWeight = font32->lfWeight;
149     font16->lfItalic = font32->lfItalic;
150     font16->lfUnderline = font32->lfUnderline;
151     font16->lfStrikeOut = font32->lfStrikeOut;
152     font16->lfCharSet = font32->lfCharSet;
153     font16->lfOutPrecision = font32->lfOutPrecision;
154     font16->lfClipPrecision = font32->lfClipPrecision;
155     font16->lfQuality = font32->lfQuality;
156     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
157     WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
158                          font16->lfFaceName, LF_FACESIZE, NULL, NULL );
159     font16->lfFaceName[LF_FACESIZE-1] = 0;
160 }
161
162 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
163 {
164     font32->lfHeight = font16->lfHeight;
165     font32->lfWidth = font16->lfWidth;
166     font32->lfEscapement = font16->lfEscapement;
167     font32->lfOrientation = font16->lfOrientation;
168     font32->lfWeight = font16->lfWeight;
169     font32->lfItalic = font16->lfItalic;
170     font32->lfUnderline = font16->lfUnderline;
171     font32->lfStrikeOut = font16->lfStrikeOut;
172     font32->lfCharSet = font16->lfCharSet;
173     font32->lfOutPrecision = font16->lfOutPrecision;
174     font32->lfClipPrecision = font16->lfClipPrecision;
175     font32->lfQuality = font16->lfQuality;
176     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
177     MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
178     font32->lfFaceName[LF_FACESIZE-1] = 0;
179 }
180
181 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
182 {
183     memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
184     MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
185                         LF_FACESIZE);
186 }
187
188 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
189 {
190     memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
191     WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
192                         LF_FACESIZE, NULL, NULL);
193 }
194
195 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
196 {
197     FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
198
199     WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
200                          font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
201     font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
202     WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
203                          font16->elfStyle, LF_FACESIZE, NULL, NULL );
204     font16->elfStyle[LF_FACESIZE-1] = '\0';
205     WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
206                          font16->elfScript, LF_FACESIZE, NULL, NULL );
207     font16->elfScript[LF_FACESIZE-1] = '\0';
208 }
209
210 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
211 {
212     FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
213
214     WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
215                          fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
216     fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
217     WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
218                          fontA->elfStyle, LF_FACESIZE, NULL, NULL );
219     fontA->elfStyle[LF_FACESIZE-1] = '\0';
220     WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
221                          fontA->elfScript, LF_FACESIZE, NULL, NULL );
222     fontA->elfScript[LF_FACESIZE-1] = '\0';
223 }
224
225 /***********************************************************************
226  *              TEXTMETRIC conversion functions.
227  */
228 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
229 {
230     ptmA->tmHeight = ptmW->tmHeight;
231     ptmA->tmAscent = ptmW->tmAscent;
232     ptmA->tmDescent = ptmW->tmDescent;
233     ptmA->tmInternalLeading = ptmW->tmInternalLeading;
234     ptmA->tmExternalLeading = ptmW->tmExternalLeading;
235     ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
236     ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
237     ptmA->tmWeight = ptmW->tmWeight;
238     ptmA->tmOverhang = ptmW->tmOverhang;
239     ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
240     ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
241     ptmA->tmFirstChar = ptmW->tmFirstChar;
242     ptmA->tmLastChar = ptmW->tmLastChar;
243     ptmA->tmDefaultChar = ptmW->tmDefaultChar;
244     ptmA->tmBreakChar = ptmW->tmBreakChar;
245     ptmA->tmItalic = ptmW->tmItalic;
246     ptmA->tmUnderlined = ptmW->tmUnderlined;
247     ptmA->tmStruckOut = ptmW->tmStruckOut;
248     ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
249     ptmA->tmCharSet = ptmW->tmCharSet;
250 }
251
252
253 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
254 {
255     ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
256     ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
257     ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
258     ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
259     ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
260     ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
261     ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
262     ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
263     ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
264     ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
265     ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
266     ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
267     ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
268     ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
269     ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
270     ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
271     ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
272     ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
273     ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
274     ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
275     ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
276     ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
277     ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
278     ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
279     memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
280 }
281
282 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
283 {
284     FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
285     ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
286     ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
287     ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
288     ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
289     memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
290 }
291
292 /***********************************************************************
293  *           CreateFontIndirectA   (GDI32.@)
294  */
295 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
296 {
297     LOGFONTW lfW;
298
299     if (plfA) {
300         FONT_LogFontAToW( plfA, &lfW );
301         return CreateFontIndirectW( &lfW );
302      } else
303         return CreateFontIndirectW( NULL );
304
305 }
306
307 /***********************************************************************
308  *           CreateFontIndirectW   (GDI32.@)
309  */
310 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
311 {
312     HFONT hFont = 0;
313
314     if (plf)
315     {
316         FONTOBJ* fontPtr;
317         if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
318                                         (HGDIOBJ *)&hFont, &font_funcs )))
319         {
320             memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
321
322             TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %04x\n",
323                   plf->lfHeight, plf->lfWidth,
324                   plf->lfEscapement, plf->lfOrientation,
325                   plf->lfPitchAndFamily,
326                   plf->lfOutPrecision, plf->lfClipPrecision,
327                   plf->lfQuality, plf->lfCharSet,
328                   debugstr_w(plf->lfFaceName),
329                   plf->lfWeight > 400 ? "Bold" : "",
330                   plf->lfItalic ? "Italic" : "", hFont);
331
332             if (plf->lfEscapement != plf->lfOrientation) {
333               /* this should really depend on whether GM_ADVANCED is set */
334               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
335               WARN("orientation angle %f set to "
336                    "escapement angle %f for new font %04x\n",
337                    plf->lfOrientation/10., plf->lfEscapement/10., hFont);
338             }
339             GDI_ReleaseObj( hFont );
340         }
341     }
342     else WARN("(NULL) => NULL\n");
343
344     return hFont;
345 }
346
347 /*************************************************************************
348  *           CreateFontA    (GDI32.@)
349  */
350 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
351                               INT orient, INT weight, DWORD italic,
352                               DWORD underline, DWORD strikeout, DWORD charset,
353                               DWORD outpres, DWORD clippres, DWORD quality,
354                               DWORD pitch, LPCSTR name )
355 {
356     LOGFONTA logfont;
357
358     logfont.lfHeight = height;
359     logfont.lfWidth = width;
360     logfont.lfEscapement = esc;
361     logfont.lfOrientation = orient;
362     logfont.lfWeight = weight;
363     logfont.lfItalic = italic;
364     logfont.lfUnderline = underline;
365     logfont.lfStrikeOut = strikeout;
366     logfont.lfCharSet = charset;
367     logfont.lfOutPrecision = outpres;
368     logfont.lfClipPrecision = clippres;
369     logfont.lfQuality = quality;
370     logfont.lfPitchAndFamily = pitch;
371
372     if (name)
373         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
374     else
375         logfont.lfFaceName[0] = '\0';
376
377     return CreateFontIndirectA( &logfont );
378 }
379
380 /*************************************************************************
381  *           CreateFontW    (GDI32.@)
382  */
383 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
384                               INT orient, INT weight, DWORD italic,
385                               DWORD underline, DWORD strikeout, DWORD charset,
386                               DWORD outpres, DWORD clippres, DWORD quality,
387                               DWORD pitch, LPCWSTR name )
388 {
389     LOGFONTW logfont;
390
391     logfont.lfHeight = height;
392     logfont.lfWidth = width;
393     logfont.lfEscapement = esc;
394     logfont.lfOrientation = orient;
395     logfont.lfWeight = weight;
396     logfont.lfItalic = italic;
397     logfont.lfUnderline = underline;
398     logfont.lfStrikeOut = strikeout;
399     logfont.lfCharSet = charset;
400     logfont.lfOutPrecision = outpres;
401     logfont.lfClipPrecision = clippres;
402     logfont.lfQuality = quality;
403     logfont.lfPitchAndFamily = pitch;
404
405     if (name)
406         lstrcpynW(logfont.lfFaceName, name,
407                   sizeof(logfont.lfFaceName) / sizeof(WCHAR));
408     else
409         logfont.lfFaceName[0] = '\0';
410
411     return CreateFontIndirectW( &logfont );
412 }
413
414
415 /***********************************************************************
416  *           FONT_SelectObject
417  *
418  * If the driver supports vector fonts we create a gdi font first and
419  * then call the driver to give it a chance to supply its own device
420  * font.  If the driver wants to do this it returns TRUE and we can
421  * delete the gdi font, if the driver wants to use the gdi font it
422  * should return FALSE, to signal an error return GDI_ERROR.  For
423  * drivers that don't support vector fonts they must supply their own
424  * font.
425  */
426 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
427 {
428     HGDIOBJ ret = 0;
429     DC *dc = DC_GetDCPtr( hdc );
430
431     if (!dc) return 0;
432
433     if (dc->hFont != handle || dc->gdiFont == NULL)
434     {
435         if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
436             dc->gdiFont = WineEngCreateFontInstance(dc, handle);
437     }
438
439     if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
440
441     if (ret && dc->gdiFont) dc->gdiFont = 0;
442
443     if (ret == HGDI_ERROR)
444         ret = 0; /* SelectObject returns 0 on error */
445     else
446     {
447         ret = dc->hFont;
448         dc->hFont = handle;
449     }
450     GDI_ReleaseObj( hdc );
451     return ret;
452 }
453
454
455 /***********************************************************************
456  *           FONT_GetObject16
457  */
458 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
459 {
460     FONTOBJ *font = obj;
461     LOGFONT16 lf16;
462
463     FONT_LogFontWTo16( &font->logfont, &lf16 );
464
465     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
466     memcpy( buffer, &lf16, count );
467     return count;
468 }
469
470 /***********************************************************************
471  *           FONT_GetObjectA
472  */
473 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
474 {
475     FONTOBJ *font = obj;
476     LOGFONTA lfA;
477
478     FONT_LogFontWToA( &font->logfont, &lfA );
479
480     if (count > sizeof(lfA)) count = sizeof(lfA);
481     if(buffer)
482         memcpy( buffer, &lfA, count );
483     return count;
484 }
485
486 /***********************************************************************
487  *           FONT_GetObjectW
488  */
489 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
490 {
491     FONTOBJ *font = obj;
492     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
493     if(buffer)
494         memcpy( buffer, &font->logfont, count );
495     return count;
496 }
497
498
499 /***********************************************************************
500  *           FONT_DeleteObject
501  */
502 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
503 {
504     WineEngDestroyFontInstance( handle );
505     return GDI_FreeObject( handle, obj );
506 }
507
508
509 /***********************************************************************
510  *              FONT_EnumInstance16
511  *
512  * Called by the device driver layer to pass font info
513  * down to the application.
514  */
515 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
516                                 DWORD fType, LPARAM lp )
517 {
518     fontEnum16 *pfe = (fontEnum16*)lp;
519     INT ret = 1;
520     DC *dc;
521
522     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
523         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
524     {
525         FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
526         FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
527         GDI_ReleaseObj( pfe->hdc );  /* release the GDI lock */
528
529         ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
530                                        (UINT16)fType, (LPARAM)pfe->lpData );
531         /* get the lock again and make sure the DC is still valid */
532         dc = DC_GetDCPtr( pfe->hdc );
533         if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
534         {
535             if (dc) GDI_ReleaseObj( pfe->hdc );
536             pfe->hdc = 0;  /* make sure we don't try to release it later on */
537             ret = 0;
538         }
539     }
540     return ret;
541 }
542
543 /***********************************************************************
544  *              FONT_EnumInstance
545  */
546 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
547                               DWORD fType, LPARAM lp )
548 {
549     fontEnum32 *pfe = (fontEnum32*)lp;
550     INT ret = 1;
551     DC *dc;
552
553     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
554     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
555         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
556     {
557         /* convert font metrics */
558         ENUMLOGFONTEXA logfont;
559         NEWTEXTMETRICEXA tmA;
560
561         pfe->dwFlags |= ENUM_CALLED;
562         if (!(pfe->dwFlags & ENUM_UNICODE))
563         {
564             FONT_EnumLogFontExWToA( plf, &logfont);
565             FONT_NewTextMetricExWToA( ptm, &tmA );
566             plf = (LPENUMLOGFONTEXW)&logfont;
567             ptm = (NEWTEXTMETRICEXW *)&tmA;
568         }
569         GDI_ReleaseObj( pfe->hdc );  /* release the GDI lock */
570
571         ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
572
573         /* get the lock again and make sure the DC is still valid */
574         dc = DC_GetDCPtr( pfe->hdc );
575         if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
576         {
577             if (dc) GDI_ReleaseObj( pfe->hdc );
578             pfe->hdc = 0;  /* make sure we don't try to release it later on */
579             ret = 0;
580         }
581     }
582     return ret;
583 }
584
585 /***********************************************************************
586  *              EnumFontFamiliesEx      (GDI.613)
587  */
588 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
589                                    FONTENUMPROC16 efproc, LPARAM lParam,
590                                    DWORD dwFlags)
591 {
592     fontEnum16 fe16;
593     INT16       retVal = 0;
594     DC*         dc = DC_GetDCPtr( HDC_32(hDC) );
595
596     if (!dc) return 0;
597     fe16.hdc = HDC_32(hDC);
598     fe16.dc = dc;
599     fe16.physDev = dc->physDev;
600
601     if (dc->funcs->pEnumDeviceFonts)
602     {
603         NEWTEXTMETRICEX16 tm16;
604         ENUMLOGFONTEX16 lf16;
605         LOGFONTW lfW;
606         FONT_LogFont16ToW(plf, &lfW);
607
608         fe16.lpLogFontParam = plf;
609         fe16.lpEnumFunc = efproc;
610         fe16.lpData = lParam;
611         fe16.lpTextMetric = &tm16;
612         fe16.lpLogFont = &lf16;
613         fe16.segTextMetric = MapLS( &tm16 );
614         fe16.segLogFont = MapLS( &lf16 );
615
616         retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
617                                               FONT_EnumInstance16, (LPARAM)&fe16 );
618         UnMapLS( fe16.segTextMetric );
619         UnMapLS( fe16.segLogFont );
620     }
621     if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
622     return retVal;
623 }
624
625 /***********************************************************************
626  *              FONT_EnumFontFamiliesEx
627  */
628 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
629                                     FONTENUMPROCW efproc,
630                                     LPARAM lParam, DWORD dwUnicode)
631 {
632     INT ret = 1, ret2;
633     DC *dc = DC_GetDCPtr( hDC );
634     fontEnum32 fe32;
635     BOOL enum_gdi_fonts;
636
637     if (!dc) return 0;
638
639     TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
640           plf->lfCharSet);
641     fe32.lpLogFontParam = plf;
642     fe32.lpEnumFunc = efproc;
643     fe32.lpData = lParam;
644     fe32.dwFlags = dwUnicode;
645     fe32.hdc = hDC;
646     fe32.dc = dc;
647     fe32.physDev = dc->physDev;
648
649     enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
650
651     if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
652     {
653         ret = 0;
654         goto done;
655     }
656
657     if (enum_gdi_fonts)
658         ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
659     fe32.dwFlags &= ~ENUM_CALLED;
660     if (ret && dc->funcs->pEnumDeviceFonts) {
661         ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
662         if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
663             ret = ret2;
664     }
665  done:
666     if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
667     return ret;
668 }
669
670 /***********************************************************************
671  *              EnumFontFamiliesExW     (GDI32.@)
672  */
673 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
674                                     FONTENUMPROCW efproc,
675                                     LPARAM lParam, DWORD dwFlags )
676 {
677     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
678 }
679
680 /***********************************************************************
681  *              EnumFontFamiliesExA     (GDI32.@)
682  */
683 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
684                                     FONTENUMPROCA efproc,
685                                     LPARAM lParam, DWORD dwFlags)
686 {
687     LOGFONTW lfW;
688     FONT_LogFontAToW( plf, &lfW );
689
690     return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
691 }
692
693 /***********************************************************************
694  *              EnumFontFamilies        (GDI.330)
695  */
696 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
697                                  FONTENUMPROC16 efproc, LPARAM lpData )
698 {
699     LOGFONT16   lf;
700
701     lf.lfCharSet = DEFAULT_CHARSET;
702     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
703     else lf.lfFaceName[0] = '\0';
704
705     return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
706 }
707
708 /***********************************************************************
709  *              EnumFontFamiliesA       (GDI32.@)
710  */
711 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
712                                   FONTENUMPROCA efproc, LPARAM lpData )
713 {
714     LOGFONTA    lf;
715
716     lf.lfCharSet = DEFAULT_CHARSET;
717     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
718     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
719
720     return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
721 }
722
723 /***********************************************************************
724  *              EnumFontFamiliesW       (GDI32.@)
725  */
726 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
727                                   FONTENUMPROCW efproc, LPARAM lpData )
728 {
729     LOGFONTW  lf;
730
731     lf.lfCharSet = DEFAULT_CHARSET;
732     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
733     else lf.lfFaceName[0] = 0;
734
735     return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
736 }
737
738 /***********************************************************************
739  *              EnumFonts               (GDI.70)
740  */
741 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
742                           LPARAM lpData )
743 {
744     return EnumFontFamilies16( hDC, lpName, efproc, lpData );
745 }
746
747 /***********************************************************************
748  *              EnumFontsA              (GDI32.@)
749  */
750 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
751                            LPARAM lpData )
752 {
753     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
754 }
755
756 /***********************************************************************
757  *              EnumFontsW              (GDI32.@)
758  */
759 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
760                            LPARAM lpData )
761 {
762     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
763 }
764
765
766 /***********************************************************************
767  *           GetTextCharacterExtra    (GDI32.@)
768  */
769 INT WINAPI GetTextCharacterExtra( HDC hdc )
770 {
771     INT ret;
772     DC *dc = DC_GetDCPtr( hdc );
773     if (!dc) return 0x80000000;
774     ret = dc->charExtra;
775     GDI_ReleaseObj( hdc );
776     return ret;
777 }
778
779
780 /***********************************************************************
781  *           SetTextCharacterExtra    (GDI32.@)
782  */
783 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
784 {
785     INT prev;
786     DC * dc = DC_GetDCPtr( hdc );
787     if (!dc) return 0x80000000;
788     if (dc->funcs->pSetTextCharacterExtra)
789         prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
790     else
791     {
792         prev = dc->charExtra;
793         dc->charExtra = extra;
794     }
795     GDI_ReleaseObj( hdc );
796     return prev;
797 }
798
799
800 /***********************************************************************
801  *           SetTextJustification    (GDI32.@)
802  */
803 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
804 {
805     BOOL ret = TRUE;
806     DC * dc = DC_GetDCPtr( hdc );
807     if (!dc) return FALSE;
808     if (dc->funcs->pSetTextJustification)
809         ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
810     else
811     {
812         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
813         if (!extra) breaks = 0;
814         dc->breakTotalExtra = extra;
815         dc->breakCount = breaks;
816         if (breaks)
817         {
818             dc->breakExtra = extra / breaks;
819             dc->breakRem   = extra - (dc->breakCount * dc->breakExtra);
820         }
821         else
822         {
823             dc->breakExtra = 0;
824             dc->breakRem   = 0;
825         }
826     }
827     GDI_ReleaseObj( hdc );
828     return ret;
829 }
830
831
832 /***********************************************************************
833  *           GetTextFaceA    (GDI32.@)
834  */
835 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
836 {
837     INT res = GetTextFaceW(hdc, 0, NULL);
838     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
839     GetTextFaceW( hdc, res, nameW );
840
841     if (name)
842         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
843                                    NULL, NULL);
844     else
845         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
846     HeapFree( GetProcessHeap(), 0, nameW );
847     return res;
848 }
849
850 /***********************************************************************
851  *           GetTextFaceW    (GDI32.@)
852  */
853 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
854 {
855     FONTOBJ *font;
856     INT     ret = 0;
857
858     DC * dc = DC_GetDCPtr( hdc );
859     if (!dc) return 0;
860
861     if(dc->gdiFont)
862         ret = WineEngGetTextFace(dc->gdiFont, count, name);
863     else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
864     {
865         if (name)
866         {
867             lstrcpynW( name, font->logfont.lfFaceName, count );
868             ret = strlenW(name);
869         }
870         else ret = strlenW(font->logfont.lfFaceName) + 1;
871         GDI_ReleaseObj( dc->hFont );
872     }
873     GDI_ReleaseObj( hdc );
874     return ret;
875 }
876
877
878 /***********************************************************************
879  *           GetTextExtentPoint32A    (GDI32.@)
880  */
881 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
882                                      LPSIZE size )
883 {
884     BOOL ret = FALSE;
885     INT wlen;
886     LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
887
888     if (p) {
889         ret = GetTextExtentPoint32W( hdc, p, wlen, size );
890         HeapFree( GetProcessHeap(), 0, p );
891     }
892
893     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
894           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
895     return ret;
896 }
897
898
899 /***********************************************************************
900  * GetTextExtentPoint32W [GDI32.@]  Computes width/height for a string
901  *
902  * Computes width and height of the specified string.
903  *
904  * RETURNS
905  *    Success: TRUE
906  *    Failure: FALSE
907  */
908 BOOL WINAPI GetTextExtentPoint32W(
909     HDC hdc,     /* [in]  Handle of device context */
910     LPCWSTR str,   /* [in]  Address of text string */
911     INT count,   /* [in]  Number of characters in string */
912     LPSIZE size) /* [out] Address of structure for string size */
913 {
914     BOOL ret = FALSE;
915     DC * dc = DC_GetDCPtr( hdc );
916     if (!dc) return FALSE;
917
918     if(dc->gdiFont) {
919         ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
920         size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
921         size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
922     }
923     else if(dc->funcs->pGetTextExtentPoint)
924         ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
925
926     GDI_ReleaseObj( hdc );
927
928     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
929           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
930     return ret;
931 }
932
933 /***********************************************************************
934  * GetTextExtentPointI [GDI32.@]
935  *
936  * Computes width and height of the array of glyph indices.
937  *
938  * RETURNS
939  *    Success: TRUE
940  *    Failure: FALSE
941  */
942 BOOL WINAPI GetTextExtentPointI(
943     HDC hdc,     /* [in]  Handle of device context */
944     const WORD *indices,   /* [in]  Address of glyph index array */
945     INT count,   /* [in]  Number of glyphs in array */
946     LPSIZE size) /* [out] Address of structure for string size */
947 {
948     BOOL ret = FALSE;
949     DC * dc = DC_GetDCPtr( hdc );
950     if (!dc) return FALSE;
951
952     if(dc->gdiFont) {
953         ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
954         size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
955         size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
956     }
957     else if(dc->funcs->pGetTextExtentPoint) {
958         FIXME("calling GetTextExtentPoint\n");
959         ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
960     }
961
962     GDI_ReleaseObj( hdc );
963
964     TRACE("(%08x %p %d %p): returning %ld x %ld\n",
965           hdc, indices, count, size, size->cx, size->cy );
966     return ret;
967 }
968
969
970 /***********************************************************************
971  *           GetTextExtentPointA    (GDI32.@)
972  */
973 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
974                                           LPSIZE size )
975 {
976     TRACE("not bug compatible.\n");
977     return GetTextExtentPoint32A( hdc, str, count, size );
978 }
979
980 /***********************************************************************
981  *           GetTextExtentPointW   (GDI32.@)
982  */
983 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
984                                           LPSIZE size )
985 {
986     TRACE("not bug compatible.\n");
987     return GetTextExtentPoint32W( hdc, str, count, size );
988 }
989
990
991 /***********************************************************************
992  *           GetTextExtentExPointA    (GDI32.@)
993  */
994 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
995                                    INT maxExt, LPINT lpnFit,
996                                    LPINT alpDx, LPSIZE size )
997 {
998     BOOL ret;
999     INT wlen;
1000     LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1001     ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1002     HeapFree( GetProcessHeap(), 0, p );
1003     return ret;
1004 }
1005
1006
1007 /***********************************************************************
1008  *           GetTextExtentExPointW    (GDI32.@)
1009  *
1010  * Return the size of the string as it would be if it was output properly by
1011  * e.g. TextOut.
1012  *
1013  * This should include
1014  * - Intercharacter spacing
1015  * - justification spacing (not yet done)
1016  * - kerning? see below
1017  *
1018  * Kerning.  Since kerning would be carried out by the rendering code it should
1019  * be done by the driver.  However they don't support it yet.  Also I am not
1020  * yet persuaded that (certainly under Win95) any kerning is actually done.
1021  *
1022  * str: According to MSDN this should be null-terminated.  That is not true; a
1023  *      null will not terminate it early.
1024  * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1025  *       than count.  I have seen it be either the size of the full string or
1026  *       1 less than the size of the full string.  I have not seen it bear any
1027  *       resemblance to the portion that would fit.
1028  * lpnFit: What exactly is fitting?  Stupidly, in my opinion, it includes the
1029  *         trailing intercharacter spacing and any trailing justification.
1030  *
1031  * FIXME
1032  * Currently we do this by measuring each character etc.  We should do it by
1033  * passing the request to the driver, perhaps by extending the
1034  * pGetTextExtentPoint function to take the alpDx argument.  That would avoid
1035  * thinking about kerning issues and rounding issues in the justification.
1036  */
1037
1038 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1039                                    INT maxExt, LPINT lpnFit,
1040                                    LPINT alpDx, LPSIZE size )
1041 {
1042     int index, nFit, extent;
1043     SIZE tSize;
1044     BOOL ret = FALSE;
1045
1046     TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1047
1048     size->cx = size->cy = nFit = extent = 0;
1049     for(index = 0; index < count; index++)
1050     {
1051         if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1052         /* GetTextExtentPoint includes intercharacter spacing. */
1053         /* FIXME - justification needs doing yet.  Remember that the base
1054          * data will not be in logical coordinates.
1055          */
1056         extent += tSize.cx;
1057         if( !lpnFit || extent <= maxExt )
1058         /* It is allowed to be equal. */
1059         {
1060             nFit++;
1061             if( alpDx ) alpDx[index] = extent;
1062         }
1063         if( tSize.cy > size->cy ) size->cy = tSize.cy;
1064         str++;
1065     }
1066     size->cx = extent;
1067     if(lpnFit) *lpnFit = nFit;
1068     ret = TRUE;
1069
1070     TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1071
1072 done:
1073     return ret;
1074 }
1075
1076 /***********************************************************************
1077  *           GetTextMetricsA    (GDI32.@)
1078  */
1079 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1080 {
1081     TEXTMETRICW tm32;
1082
1083     if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1084     FONT_TextMetricWToA( &tm32, metrics );
1085     return TRUE;
1086 }
1087
1088 /***********************************************************************
1089  *           GetTextMetricsW    (GDI32.@)
1090  */
1091 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1092 {
1093     BOOL ret = FALSE;
1094     DC * dc = DC_GetDCPtr( hdc );
1095     if (!dc) return FALSE;
1096
1097     if (dc->gdiFont)
1098         ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1099     else if (dc->funcs->pGetTextMetrics)
1100         ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1101
1102     if (ret)
1103     {
1104     /* device layer returns values in device units
1105      * therefore we have to convert them to logical */
1106
1107 #define WDPTOLP(x) ((x<0)?                                      \
1108                 (-abs(INTERNAL_XDSTOWS(dc, (x)))):              \
1109                 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1110 #define HDPTOLP(y) ((y<0)?                                      \
1111                 (-abs(INTERNAL_YDSTOWS(dc, (y)))):              \
1112                 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1113
1114     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1115     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1116     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1117     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1118     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1119     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1120     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1121     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1122         ret = TRUE;
1123 #undef WDPTOLP
1124 #undef HDPTOLP
1125     TRACE("text metrics:\n"
1126           "    Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1127           "    Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1128           "    UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1129           "    StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1130           "    PitchAndFamily = %02x\n"
1131           "    --------------------\n"
1132           "    InternalLeading = %li\n"
1133           "    Ascent = %li\n"
1134           "    Descent = %li\n"
1135           "    Height = %li\n",
1136           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1137           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1138           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1139           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1140           metrics->tmPitchAndFamily,
1141           metrics->tmInternalLeading,
1142           metrics->tmAscent,
1143           metrics->tmDescent,
1144           metrics->tmHeight );
1145     }
1146     GDI_ReleaseObj( hdc );
1147     return ret;
1148 }
1149
1150
1151 /***********************************************************************
1152  * GetOutlineTextMetrics [GDI.308]  Gets metrics for TrueType fonts.
1153  *
1154  * NOTES
1155  *    lpOTM should be LPOUTLINETEXTMETRIC
1156  *
1157  * RETURNS
1158  *    Success: Non-zero or size of required buffer
1159  *    Failure: 0
1160  */
1161 UINT16 WINAPI GetOutlineTextMetrics16(
1162     HDC16 hdc,    /* [in]  Handle of device context */
1163     UINT16 cbData, /* [in]  Size of metric data array */
1164     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1165 {
1166     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1167     return 0;
1168 }
1169
1170
1171 /***********************************************************************
1172  *              GetOutlineTextMetricsA (GDI32.@)
1173  * Gets metrics for TrueType fonts.
1174  *
1175  *
1176  * RETURNS
1177  *    Success: Non-zero or size of required buffer
1178  *    Failure: 0
1179  */
1180 UINT WINAPI GetOutlineTextMetricsA(
1181     HDC hdc,    /* [in]  Handle of device context */
1182     UINT cbData, /* [in]  Size of metric data array */
1183     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1184 {
1185     char buf[512], *ptr;
1186     UINT ret, needed;
1187     OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1188     INT left, len;
1189
1190     if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1191         if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1192             return 0;
1193         lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1194         GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1195     }
1196
1197     needed = sizeof(OUTLINETEXTMETRICA);
1198     if(lpOTMW->otmpFamilyName)
1199         needed += WideCharToMultiByte(CP_ACP, 0,
1200            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1201                                       NULL, 0, NULL, NULL);
1202     if(lpOTMW->otmpFaceName)
1203         needed += WideCharToMultiByte(CP_ACP, 0,
1204            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1205                                       NULL, 0, NULL, NULL);
1206     if(lpOTMW->otmpStyleName)
1207         needed += WideCharToMultiByte(CP_ACP, 0,
1208            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1209                                       NULL, 0, NULL, NULL);
1210     if(lpOTMW->otmpFullName)
1211         needed += WideCharToMultiByte(CP_ACP, 0,
1212            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1213                                       NULL, 0, NULL, NULL);
1214
1215     if(!lpOTM) {
1216         ret = needed;
1217         goto end;
1218     }
1219
1220     if(needed > cbData) {
1221         ret = 0;
1222         goto end;
1223     }
1224
1225
1226     lpOTM->otmSize = needed;
1227     FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1228     lpOTM->otmFiller = 0;
1229     lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1230     lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1231     lpOTM->otmfsType = lpOTMW->otmfsType;
1232     lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1233     lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1234     lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1235     lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1236     lpOTM->otmAscent = lpOTMW->otmAscent;
1237     lpOTM->otmDescent = lpOTMW->otmDescent;
1238     lpOTM->otmLineGap = lpOTMW->otmLineGap;
1239     lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1240     lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1241     lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1242     lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1243     lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1244     lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1245     lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1246     lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1247     lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1248     lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1249     lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1250     lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1251     lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1252     lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1253     lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1254
1255
1256     ptr = (char*)(lpOTM + 1);
1257     left = needed - sizeof(*lpOTM);
1258
1259     if(lpOTMW->otmpFamilyName) {
1260         lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1261         len = WideCharToMultiByte(CP_ACP, 0,
1262              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1263                                   ptr, left, NULL, NULL);
1264         left -= len;
1265         ptr += len;
1266     } else
1267         lpOTM->otmpFamilyName = 0;
1268
1269     if(lpOTMW->otmpFaceName) {
1270         lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1271         len = WideCharToMultiByte(CP_ACP, 0,
1272              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1273                                   ptr, left, NULL, NULL);
1274         left -= len;
1275         ptr += len;
1276     } else
1277         lpOTM->otmpFaceName = 0;
1278
1279     if(lpOTMW->otmpStyleName) {
1280         lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1281         len = WideCharToMultiByte(CP_ACP, 0,
1282              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1283                                   ptr, left, NULL, NULL);
1284         left -= len;
1285         ptr += len;
1286     } else
1287         lpOTM->otmpStyleName = 0;
1288
1289     if(lpOTMW->otmpFullName) {
1290         lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1291         len = WideCharToMultiByte(CP_ACP, 0,
1292              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1293                                   ptr, left, NULL, NULL);
1294         left -= len;
1295     } else
1296         lpOTM->otmpFullName = 0;
1297
1298     assert(left == 0);
1299
1300     ret = needed;
1301
1302 end:
1303     if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1304         HeapFree(GetProcessHeap(), 0, lpOTMW);
1305
1306     return ret;
1307 }
1308
1309
1310 /***********************************************************************
1311  *           GetOutlineTextMetricsW [GDI32.@]
1312  */
1313 UINT WINAPI GetOutlineTextMetricsW(
1314     HDC hdc,    /* [in]  Handle of device context */
1315     UINT cbData, /* [in]  Size of metric data array */
1316     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1317 {
1318     DC *dc = DC_GetDCPtr( hdc );
1319     UINT ret;
1320
1321     TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1322     if(!dc) return 0;
1323
1324     if(dc->gdiFont) {
1325         ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1326         if(ret && ret <= cbData) {
1327 #define WDPTOLP(x) ((x<0)?                                      \
1328                 (-abs(INTERNAL_XDSTOWS(dc, (x)))):              \
1329                 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1330 #define HDPTOLP(y) ((y<0)?                                      \
1331                 (-abs(INTERNAL_YDSTOWS(dc, (y)))):              \
1332                 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1333
1334             lpOTM->otmTextMetrics.tmHeight           = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1335             lpOTM->otmTextMetrics.tmAscent           = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1336             lpOTM->otmTextMetrics.tmDescent          = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1337             lpOTM->otmTextMetrics.tmInternalLeading  = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1338             lpOTM->otmTextMetrics.tmExternalLeading  = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1339             lpOTM->otmTextMetrics.tmAveCharWidth     = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1340             lpOTM->otmTextMetrics.tmMaxCharWidth     = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1341             lpOTM->otmTextMetrics.tmOverhang         = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1342             lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1343             lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1344             lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1345             lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1346             lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1347             lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1348             lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1349             lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1350             lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1351             lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1352             lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1353             lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1354             lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1355             lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1356             lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1357             lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1358             lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1359             lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1360             lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1361             lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1362             lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1363             lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1364             lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1365             lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1366 #undef WDPTOLP
1367 #undef HDPTOLP
1368         }
1369     }
1370
1371     else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1372               but really this should just be a return 0. */
1373
1374         ret = sizeof(*lpOTM);
1375         if (lpOTM) {
1376             if(cbData < ret)
1377                 ret = 0;
1378             else {
1379                 memset(lpOTM, 0, ret);
1380                 lpOTM->otmSize = sizeof(*lpOTM);
1381                 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1382                 /*
1383                   Further fill of the structure not implemented,
1384                   Needs real values for the structure members
1385                 */
1386             }
1387         }
1388     }
1389     GDI_ReleaseObj(hdc);
1390     return ret;
1391 }
1392
1393
1394 /***********************************************************************
1395  *           GetCharWidthW      (GDI32.@)
1396  *           GetCharWidth32W    (GDI32.@)
1397  */
1398 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1399                                LPINT buffer )
1400 {
1401     UINT i, extra;
1402     BOOL ret = FALSE;
1403     DC * dc = DC_GetDCPtr( hdc );
1404     if (!dc) return FALSE;
1405
1406     if (dc->gdiFont)
1407         ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1408     else if (dc->funcs->pGetCharWidth)
1409         ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1410
1411     if (ret)
1412     {
1413         /* convert device units to logical */
1414
1415         extra = dc->vportExtX >> 1;
1416         for( i = firstChar; i <= lastChar; i++, buffer++ )
1417             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1418         ret = TRUE;
1419     }
1420     GDI_ReleaseObj( hdc );
1421     return ret;
1422 }
1423
1424
1425 /***********************************************************************
1426  *           GetCharWidthA      (GDI32.@)
1427  *           GetCharWidth32A    (GDI32.@)
1428  */
1429 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1430                                LPINT buffer )
1431 {
1432     INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1433     LPSTR str;
1434     LPWSTR wstr;
1435     BOOL ret = TRUE;
1436
1437     if(count <= 0) return FALSE;
1438
1439     str = HeapAlloc(GetProcessHeap(), 0, count);
1440     for(i = 0; i < count; i++)
1441         str[i] = (BYTE)(firstChar + i);
1442
1443     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1444
1445     for(i = 0; i < wlen; i++)
1446     {
1447         if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1448         {
1449             ret = FALSE;
1450             break;
1451         }
1452         buffer++;
1453     }
1454
1455     HeapFree(GetProcessHeap(), 0, str);
1456     HeapFree(GetProcessHeap(), 0, wstr);
1457
1458     return ret;
1459 }
1460
1461
1462 /* FIXME: all following APIs ******************************************/
1463
1464
1465 /***********************************************************************
1466  *           SetMapperFlags    (GDI32.@)
1467  */
1468 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1469 {
1470     DC *dc = DC_GetDCPtr( hDC );
1471     DWORD ret = 0;
1472     if(!dc) return 0;
1473     if(dc->funcs->pSetMapperFlags)
1474         ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1475     else
1476         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1477     GDI_ReleaseObj( hDC );
1478     return ret;
1479 }
1480
1481 /***********************************************************************
1482  *          GetAspectRatioFilterEx  (GDI.486)
1483  */
1484 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1485 {
1486   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1487   return FALSE;
1488 }
1489
1490 /***********************************************************************
1491  *          GetAspectRatioFilterEx  (GDI32.@)
1492  */
1493 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1494 {
1495   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1496   return FALSE;
1497 }
1498
1499
1500 /***********************************************************************
1501  *           GetCharABCWidthsA   (GDI32.@)
1502  */
1503 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1504                                   LPABC abc )
1505 {
1506     INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1507     LPSTR str;
1508     LPWSTR wstr;
1509     BOOL ret = TRUE;
1510
1511     if(count <= 0) return FALSE;
1512
1513     str = HeapAlloc(GetProcessHeap(), 0, count);
1514     for(i = 0; i < count; i++)
1515         str[i] = (BYTE)(firstChar + i);
1516
1517     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1518
1519     for(i = 0; i < wlen; i++)
1520     {
1521         if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1522         {
1523             ret = FALSE;
1524             break;
1525         }
1526         abc++;
1527     }
1528
1529     HeapFree(GetProcessHeap(), 0, str);
1530     HeapFree(GetProcessHeap(), 0, wstr);
1531
1532     return ret;
1533 }
1534
1535
1536 /******************************************************************************
1537  * GetCharABCWidthsW [GDI32.@]  Retrieves widths of characters in range
1538  *
1539  * PARAMS
1540  *    hdc       [I] Handle of device context
1541  *    firstChar [I] First character in range to query
1542  *    lastChar  [I] Last character in range to query
1543  *    abc       [O] Address of character-width structure
1544  *
1545  * NOTES
1546  *    Only works with TrueType fonts
1547  *
1548  * RETURNS
1549  *    Success: TRUE
1550  *    Failure: FALSE
1551  */
1552 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1553                                    LPABC abc )
1554 {
1555     DC *dc = DC_GetDCPtr(hdc);
1556     int         i;
1557     GLYPHMETRICS gm;
1558     BOOL ret = FALSE;
1559
1560     if(dc->gdiFont) {
1561         for (i=firstChar;i<=lastChar;i++) {
1562             GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1563             abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1564             abc[i-firstChar].abcB = gm.gmBlackBoxX;
1565             abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1566         }
1567         ret = TRUE;
1568     }
1569     GDI_ReleaseObj(hdc);
1570     return ret;
1571 }
1572
1573
1574 /***********************************************************************
1575  *           GetGlyphOutline    (GDI.309)
1576  */
1577 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1578                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1579                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1580 {
1581     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1582           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1583     return (DWORD)-1; /* failure */
1584 }
1585
1586
1587 /***********************************************************************
1588  *           GetGlyphOutlineA    (GDI32.@)
1589  */
1590 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1591                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1592                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1593 {
1594     LPWSTR p = NULL;
1595     DWORD ret;
1596     UINT c;
1597
1598     if(!(fuFormat & GGO_GLYPH_INDEX)) {
1599         p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1600         c = p[0];
1601     } else
1602         c = uChar;
1603     ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1604                            lpmat2);
1605     if(p)
1606         HeapFree(GetProcessHeap(), 0, p);
1607     return ret;
1608 }
1609
1610 /***********************************************************************
1611  *           GetGlyphOutlineW    (GDI32.@)
1612  */
1613 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1614                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1615                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1616 {
1617     DC *dc = DC_GetDCPtr(hdc);
1618     DWORD ret;
1619
1620     TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1621           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1622
1623     if(!dc) return GDI_ERROR;
1624
1625     if(dc->gdiFont)
1626       ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1627                                    cbBuffer, lpBuffer, lpmat2);
1628     else
1629       ret = GDI_ERROR;
1630
1631     GDI_ReleaseObj(hdc);
1632     return ret;
1633 }
1634
1635
1636 /***********************************************************************
1637  *           CreateScalableFontResourceA   (GDI32.@)
1638  */
1639 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1640                                              LPCSTR lpszResourceFile,
1641                                              LPCSTR lpszFontFile,
1642                                              LPCSTR lpszCurrentPath )
1643 {
1644     HANDLE f;
1645
1646     /* fHidden=1 - only visible for the calling app, read-only, not
1647      * enumbered with EnumFonts/EnumFontFamilies
1648      * lpszCurrentPath can be NULL
1649      */
1650     FIXME("(%ld,%s,%s,%s): stub\n",
1651           fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1652           debugstr_a(lpszCurrentPath) );
1653
1654     /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1655     if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1656         CloseHandle(f);
1657         SetLastError(ERROR_FILE_EXISTS);
1658         return FALSE;
1659     }
1660     return FALSE; /* create failed */
1661 }
1662
1663 /***********************************************************************
1664  *           CreateScalableFontResourceW   (GDI32.@)
1665  */
1666 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1667                                              LPCWSTR lpszResourceFile,
1668                                              LPCWSTR lpszFontFile,
1669                                              LPCWSTR lpszCurrentPath )
1670 {
1671     FIXME("(%ld,%p,%p,%p): stub\n",
1672           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1673     return FALSE; /* create failed */
1674 }
1675
1676
1677 /*************************************************************************
1678  *             GetRasterizerCaps   (GDI32.@)
1679  */
1680 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1681 {
1682   lprs->nSize = sizeof(RASTERIZER_STATUS);
1683   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1684   lprs->nLanguageID = 0;
1685   return TRUE;
1686 }
1687
1688
1689 /*************************************************************************
1690  *             GetKerningPairsA   (GDI32.@)
1691  */
1692 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1693 {
1694     int i;
1695     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1696     for (i = 0; i < cPairs; i++)
1697         lpKerningPairs[i].iKernAmount = 0;
1698     return 0;
1699 }
1700
1701
1702 /*************************************************************************
1703  *             GetKerningPairsW   (GDI32.@)
1704  */
1705 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1706                                  LPKERNINGPAIR lpKerningPairs )
1707 {
1708     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1709 }
1710
1711 /*************************************************************************
1712  * TranslateCharsetInfo [GDI32.@]
1713  *
1714  * Fills a CHARSETINFO structure for a character set, code page, or
1715  * font. This allows making the correspondance between different labelings
1716  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1717  * of the same encoding.
1718  *
1719  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1720  * only one codepage should be set in *lpSrc.
1721  *
1722  * RETURNS
1723  *   TRUE on success, FALSE on failure.
1724  *
1725  */
1726 BOOL WINAPI TranslateCharsetInfo(
1727   LPDWORD lpSrc, /* [in]
1728        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1729        if flags == TCI_SRCCHARSET: a character set value
1730        if flags == TCI_SRCCODEPAGE: a code page value
1731                  */
1732   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1733   DWORD flags /* [in] determines interpretation of lpSrc */
1734 ) {
1735     int index = 0;
1736     switch (flags) {
1737     case TCI_SRCFONTSIG:
1738         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1739       break;
1740     case TCI_SRCCODEPAGE:
1741       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1742       break;
1743     case TCI_SRCCHARSET:
1744       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1745       break;
1746     default:
1747       return FALSE;
1748     }
1749     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1750     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1751     return TRUE;
1752 }
1753
1754 /*************************************************************************
1755  *             GetFontLanguageInfo   (GDI32.@)
1756  */
1757 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1758 {
1759         FONTSIGNATURE fontsig;
1760         static const DWORD GCP_DBCS_MASK=0x003F0000,
1761                 GCP_DIACRITIC_MASK=0x00000000,
1762                 FLI_GLYPHS_MASK=0x00000000,
1763                 GCP_GLYPHSHAPE_MASK=0x00000040,
1764                 GCP_KASHIDA_MASK=0x00000000,
1765                 GCP_LIGATE_MASK=0x00000000,
1766                 GCP_USEKERNING_MASK=0x00000000,
1767                 GCP_REORDER_MASK=0x00000060;
1768
1769         DWORD result=0;
1770
1771         GetTextCharsetInfo( hdc, &fontsig, 0 );
1772         /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1773
1774         if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1775                 result|=GCP_DBCS;
1776
1777         if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1778                 result|=GCP_DIACRITIC;
1779
1780         if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1781                 result|=FLI_GLYPHS;
1782
1783         if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1784                 result|=GCP_GLYPHSHAPE;
1785
1786         if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1787                 result|=GCP_KASHIDA;
1788
1789         if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1790                 result|=GCP_LIGATE;
1791
1792         if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1793                 result|=GCP_USEKERNING;
1794
1795         if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1796                 result|=GCP_REORDER;
1797
1798         return result;
1799 }
1800
1801
1802 /*************************************************************************
1803  * GetFontData [GDI32.@] Retrieve data for TrueType font
1804  *
1805  * RETURNS
1806  *
1807  * success: Number of bytes returned
1808  * failure: GDI_ERROR
1809  *
1810  * NOTES
1811  *
1812  * Calls SetLastError()
1813  *
1814  */
1815 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1816     LPVOID buffer, DWORD length)
1817 {
1818     DC *dc = DC_GetDCPtr(hdc);
1819     DWORD ret = GDI_ERROR;
1820
1821     if(!dc) return GDI_ERROR;
1822
1823     if(dc->gdiFont)
1824       ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1825
1826     GDI_ReleaseObj(hdc);
1827     return ret;
1828 }
1829
1830 /*************************************************************************
1831  * GetGlyphIndicesA [GDI32.@]
1832  */
1833 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1834                               LPWORD pgi, DWORD flags)
1835 {
1836     DWORD ret;
1837     WCHAR *lpstrW;
1838     INT countW;
1839
1840     TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1841         hdc, debugstr_an(lpstr, count), count, pgi, flags);
1842
1843     lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1844     ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1845     HeapFree(GetProcessHeap(), 0, lpstrW);
1846
1847     return ret;
1848 }
1849
1850 /*************************************************************************
1851  * GetGlyphIndicesW [GDI32.@]
1852  */
1853 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1854                               LPWORD pgi, DWORD flags)
1855 {
1856     DC *dc = DC_GetDCPtr(hdc);
1857     DWORD ret = GDI_ERROR;
1858
1859     TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1860         hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1861
1862     if(!dc) return GDI_ERROR;
1863
1864     if(dc->gdiFont)
1865         ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1866
1867     GDI_ReleaseObj(hdc);
1868     return ret;
1869 }
1870
1871 /*************************************************************************
1872  * GetCharacterPlacementA [GDI32.@]
1873  *
1874  * NOTES:
1875  *  the web browser control of ie4 calls this with dwFlags=0
1876  */
1877 DWORD WINAPI
1878 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1879                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1880                          DWORD dwFlags)
1881 {
1882     WCHAR *lpStringW;
1883     INT uCountW, i;
1884     GCP_RESULTSW resultsW;
1885     DWORD ret;
1886     UINT font_cp;
1887
1888     TRACE("%s, %d, %d, 0x%08lx\n",
1889           debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1890
1891     /* both structs are equal in size */
1892     memcpy(&resultsW, lpResults, sizeof(resultsW));
1893
1894     lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1895     if(lpResults->lpOutString)
1896         resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1897
1898     ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1899
1900     if(lpResults->lpOutString) {
1901         if(font_cp != CP_SYMBOL)
1902             WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1903                                 lpResults->lpOutString, uCount, NULL, NULL );
1904         else
1905             for(i = 0; i < uCount; i++)
1906                 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1907     }
1908
1909     HeapFree(GetProcessHeap(), 0, lpStringW);
1910     HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1911
1912     return ret;
1913 }
1914
1915 /*************************************************************************
1916  * GetCharacterPlacementW [GDI32.@]
1917  *
1918  *   Retrieve information about a string. This includes the width, reordering,
1919  *   Glyphing and so on.
1920  *
1921  * RETURNS
1922  *
1923  *   The width and height of the string if succesful, 0 if failed.
1924  *
1925  * BUGS
1926  *
1927  *   All flags except GCP_REORDER are not yet implemented.
1928  *   Reordering is not 100% complient to the Windows BiDi method.
1929  *   Caret positioning is not yet implemented.
1930  *   Classes are not yet implemented.
1931  *
1932  */
1933 DWORD WINAPI
1934 GetCharacterPlacementW(
1935                 HDC hdc,                /* [in] Device context for which the rendering is to be done */
1936                 LPCWSTR lpString,       /* [in] The string for which information is to be returned */
1937                 INT uCount,             /* [in] Number of WORDS in string. */
1938                 INT nMaxExtent,         /* [in] Maximum extent the string is to take (in HDC logical units) */
1939                 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1940                 DWORD dwFlags           /* [in] Flags specifying how to process the string */
1941                 )
1942 {
1943     DWORD ret=0;
1944     SIZE size;
1945     UINT i, nSet;
1946
1947     TRACE("%s, %d, %d, 0x%08lx\n",
1948           debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1949
1950     TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1951           "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1952             lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1953             lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1954             lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1955
1956     if(dwFlags&(~GCP_REORDER))                  FIXME("flags 0x%08lx ignored\n", dwFlags);
1957     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1958     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1959
1960         nSet = (UINT)uCount;
1961         if(nSet > lpResults->nGlyphs)
1962                 nSet = lpResults->nGlyphs;
1963
1964         /* return number of initialized fields */
1965         lpResults->nGlyphs = nSet;
1966
1967         if(dwFlags==0)
1968         {
1969                 /* Treat the case where no special handling was requested in a fastpath way */
1970                 /* copy will do if the GCP_REORDER flag is not set */
1971                 if(lpResults->lpOutString)
1972                         for(i=0; i<nSet && lpString[i]!=0; ++i )
1973                                 lpResults->lpOutString[i]=lpString[i];
1974
1975                 if(lpResults->lpOrder)
1976                 {
1977                         for(i = 0; i < nSet; i++)
1978                                 lpResults->lpOrder[i] = i;
1979                 }
1980         }
1981
1982         if((dwFlags&GCP_REORDER)!=0)
1983         {
1984                 WORD *pwCharType;
1985                 int run_end;
1986                 /* Keep a static table that translates the C2 types to something meaningful */
1987                 /* 1 - left to right
1988                  * -1 - right to left
1989                  * 0 - neutral
1990                  */
1991                 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
1992
1993                 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
1994                 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
1995                 {
1996                         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1997
1998                         return 0;
1999                 }
2000
2001                 /* Fill in the order array with directionality values */
2002                 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2003
2004                 /* The complete and correct (at least according to MS) BiDi algorythm is not
2005                  * yet implemented here. Instead, we just make sure that consecutive runs of
2006                  * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2007                  * that are between runs of opposing directions the base (ok, always LTR) dir.
2008                  * While this is a LONG way from a BiDi algorithm, it does produce more or less
2009                  * readable results.
2010                  */
2011                 for( i=0; i<uCount; i+=run_end )
2012                 {
2013                         for( run_end=1; i+run_end<uCount &&
2014                              (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2015                              chardir[pwCharType[i+run_end]]==0); ++run_end )
2016                                 ;
2017
2018                         if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2019                         {
2020                                 /* A LTR run */
2021                                 if(lpResults->lpOutString)
2022                                 {
2023                                         int j;
2024                                         for( j=0; j<run_end; j++ )
2025                                         {
2026                                                 lpResults->lpOutString[i+j]=lpString[i+j];
2027                                         }
2028                                 }
2029
2030                                 if(lpResults->lpOrder)
2031                                 {
2032                                         int j;
2033                                         for( j=0; j<run_end; j++ )
2034                                                 lpResults->lpOrder[i+j] = i+j;
2035                                 }
2036                         } else
2037                         {
2038                                 /* A RTL run */
2039
2040                                 /* Since, at this stage, the paragraph context is always LTR,
2041                                  * remove any neutrals from the end of this run.
2042                                  */
2043                                 if( chardir[pwCharType[i]]!=0 )
2044                                         while( chardir[pwCharType[i+run_end-1]]==0 )
2045                                                 --run_end;
2046
2047                                 if(lpResults->lpOutString)
2048                                 {
2049                                         int j;
2050                                         for( j=0; j<run_end; j++ )
2051                                         {
2052                                                 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2053                                         }
2054                                 }
2055
2056                                 if(lpResults->lpOrder)
2057                                 {
2058                                         int j;
2059                                         for( j=0; j<run_end; j++ )
2060                                                 lpResults->lpOrder[i+j] = i+run_end-j-1;
2061                                 }
2062                         }
2063                 }
2064
2065                 HeapFree(GetProcessHeap(), 0, pwCharType);
2066         }
2067
2068         /* FIXME: Will use the placement chars */
2069         if (lpResults->lpDx)
2070         {
2071                 int c;
2072                 for (i = 0; i < nSet; i++)
2073                 {
2074                         if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2075                                 lpResults->lpDx[i]= c;
2076                 }
2077         }
2078
2079     if(lpResults->lpGlyphs)
2080         GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2081
2082     if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2083       ret = MAKELONG(size.cx, size.cy);
2084
2085     return ret;
2086 }
2087
2088 /*************************************************************************
2089  *      GetCharABCWidthsFloatA [GDI32.@]
2090  */
2091 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2092                                         LPABCFLOAT lpABCF)
2093 {
2094        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2095        return 0;
2096 }
2097
2098 /*************************************************************************
2099  *      GetCharABCWidthsFloatW [GDI32.@]
2100  */
2101 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2102                                         UINT iLastChar, LPABCFLOAT lpABCF)
2103 {
2104        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2105        return 0;
2106 }
2107
2108 /*************************************************************************
2109  *      GetCharWidthFloatA [GDI32.@]
2110  */
2111 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2112                                     UINT iLastChar, PFLOAT pxBuffer)
2113 {
2114        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2115        return 0;
2116 }
2117
2118 /*************************************************************************
2119  *      GetCharWidthFloatW [GDI32.@]
2120  */
2121 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2122                                     UINT iLastChar, PFLOAT pxBuffer)
2123 {
2124        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2125        return 0;
2126 }
2127
2128
2129 /***********************************************************************
2130  *                                                                     *
2131  *           Font Resource API                                         *
2132  *                                                                     *
2133  ***********************************************************************/
2134
2135 /***********************************************************************
2136  *           AddFontResourceA    (GDI32.@)
2137  */
2138 INT WINAPI AddFontResourceA( LPCSTR str )
2139 {
2140     return AddFontResourceExA( str, 0, NULL);
2141 }
2142
2143 /***********************************************************************
2144  *           AddFontResourceW    (GDI32.@)
2145  */
2146 INT WINAPI AddFontResourceW( LPCWSTR str )
2147 {
2148     return AddFontResourceExW(str, 0, NULL);
2149 }
2150
2151
2152 /***********************************************************************
2153  *           AddFontResourceExA    (GDI32.@)
2154  */
2155 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2156 {
2157     DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2158     LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2159     INT ret;
2160
2161     MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2162     ret = AddFontResourceExW(strW, fl, pdv);
2163     HeapFree(GetProcessHeap(), 0, strW);
2164     return ret;
2165 }
2166
2167 /***********************************************************************
2168  *           AddFontResourceExW    (GDI32.@)
2169  */
2170 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2171 {
2172     return WineEngAddFontResourceEx(str, fl, pdv);
2173 }
2174
2175 /***********************************************************************
2176  *           RemoveFontResourceA    (GDI32.@)
2177  */
2178 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2179 {
2180     return RemoveFontResourceExA(str, 0, 0);
2181 }
2182
2183 /***********************************************************************
2184  *           RemoveFontResourceW    (GDI32.@)
2185  */
2186 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2187 {
2188     return RemoveFontResourceExW(str, 0, 0);
2189 }
2190
2191 /***********************************************************************
2192  *           RemoveFontResourceExA    (GDI32.@)
2193  */
2194 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2195 {
2196     DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2197     LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2198     INT ret;
2199
2200     MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2201     ret = RemoveFontResourceExW(strW, fl, pdv);
2202     HeapFree(GetProcessHeap(), 0, strW);
2203     return ret;
2204 }
2205
2206 /***********************************************************************
2207  *           RemoveFontResourceExW    (GDI32.@)
2208  */
2209 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2210 {
2211     return WineEngRemoveFontResourceEx(str, fl, pdv);
2212 }