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