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