Backed out font codepage change.
[wine] / objects / font.c
1 /*
2  * GDI font objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *           1997 Alex Korobka
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include "wine/winestring.h"
11 #include "font.h"
12 #include "heap.h"
13 #include "metafile.h"
14 #include "options.h"
15 #include "debugtools.h"
16 #include "winerror.h"
17 #include "dc.h"
18 #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 *) GDI_GetObjPtr( hdc, DC_MAGIC );
730     if (!dc) return 0;
731     ret = abs( (dc->w.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->w.charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
761         dc->w.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->w.breakTotalExtra = extra;
792         dc->w.breakCount = breaks;
793         if (breaks)
794         {
795             dc->w.breakExtra = extra / breaks;
796             dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
797         }
798         else
799         {
800             dc->w.breakExtra = 0;
801             dc->w.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 *) DC_GetDCPtr( hdc );
826     if (!dc) return 0;
827
828     if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->w.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->w.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 %d,%d\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 %d,%d\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 %d %d\n",
1025           hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1026 done:
1027     GDI_ReleaseObj( hdc );
1028     return ret;
1029 }
1030
1031 /***********************************************************************
1032  *           GetTextMetrics16    (GDI.93)
1033  */
1034 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1035 {
1036     TEXTMETRICA tm32;
1037
1038     if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
1039     FONT_TextMetric32Ato16( &tm32, metrics );
1040     return TRUE;
1041 }
1042
1043
1044 /***********************************************************************
1045  *           GetTextMetricsA    (GDI32.236)
1046  */
1047 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1048     {
1049     BOOL ret = FALSE;
1050     DC * dc = DC_GetDCPtr( hdc );
1051     if (!dc) return FALSE;
1052
1053     if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
1054     {
1055     /* device layer returns values in device units
1056      * therefore we have to convert them to logical */
1057
1058 #define WDPTOLP(x) ((x<0)?                                      \
1059                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
1060                 (abs((x)*dc->wndExtX/dc->vportExtX)))
1061 #define HDPTOLP(y) ((y<0)?                                      \
1062                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
1063                 (abs((y)*dc->wndExtY/dc->vportExtY)))
1064         
1065     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1066     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1067     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1068     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1069     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1070     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1071     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1072     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1073         ret = TRUE;
1074
1075     TRACE("text metrics:\n"
1076           "    Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1077           "    Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1078           "    UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1079           "    StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1080           "    PitchAndFamily = %02x\n"
1081           "    --------------------\n"
1082           "    InternalLeading = %li\n"
1083           "    Ascent = %li\n"
1084           "    Descent = %li\n"
1085           "    Height = %li\n",
1086           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1087           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1088           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1089           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1090           metrics->tmPitchAndFamily,
1091           metrics->tmInternalLeading,
1092           metrics->tmAscent,
1093           metrics->tmDescent,
1094           metrics->tmHeight );
1095     }
1096     GDI_ReleaseObj( hdc );
1097     return ret;
1098 }
1099
1100
1101 /***********************************************************************
1102  *           GetTextMetricsW    (GDI32.237)
1103  */
1104 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1105 {
1106     TEXTMETRICA tm;
1107     if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1108     FONT_TextMetric32Ato32W( &tm, metrics );
1109     return TRUE;
1110 }
1111
1112
1113 /***********************************************************************
1114  * GetOutlineTextMetrics16 [GDI.308]  Gets metrics for TrueType fonts.
1115  *
1116  * NOTES
1117  *    lpOTM should be LPOUTLINETEXTMETRIC
1118  *
1119  * RETURNS
1120  *    Success: Non-zero or size of required buffer
1121  *    Failure: 0
1122  */
1123 UINT16 WINAPI GetOutlineTextMetrics16(
1124     HDC16 hdc,    /* [in]  Handle of device context */
1125     UINT16 cbData, /* [in]  Size of metric data array */
1126     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1127 {
1128     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1129     return 0;
1130 }
1131
1132
1133 /***********************************************************************
1134  * GetOutlineTextMetricsA [GDI.207]  Gets metrics for TrueType fonts.
1135  *
1136  *
1137  * RETURNS
1138  *    Success: Non-zero or size of required buffer
1139  *    Failure: 0
1140  */
1141 UINT WINAPI GetOutlineTextMetricsA(
1142     HDC hdc,    /* [in]  Handle of device context */
1143     UINT cbData, /* [in]  Size of metric data array */
1144     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1145 {
1146
1147
1148     UINT rtn = FALSE;
1149     LPTEXTMETRICA lptxtMetr;
1150
1151
1152
1153     if (lpOTM == 0)
1154     {
1155         
1156         lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1157         rtn = sizeof(OUTLINETEXTMETRICA);
1158         cbData = rtn;
1159     } else
1160     {
1161         cbData = sizeof(*lpOTM);
1162         rtn = cbData;
1163     };
1164
1165     lpOTM->otmSize = cbData;
1166
1167     lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1168     
1169     if (!GetTextMetricsA(hdc,lptxtMetr))
1170     {
1171         return 0;
1172     } else
1173     {
1174        memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1175     };
1176
1177     HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1178     
1179     lpOTM->otmFilter = 0;
1180
1181     lpOTM->otmPanoseNumber.bFamilyType  = 0;
1182     lpOTM->otmPanoseNumber.bSerifStyle  = 0;
1183     lpOTM->otmPanoseNumber.bWeight      = 0;
1184     lpOTM->otmPanoseNumber.bProportion  = 0;
1185     lpOTM->otmPanoseNumber.bContrast    = 0;
1186     lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1187     lpOTM->otmPanoseNumber.bArmStyle    = 0;
1188     lpOTM->otmPanoseNumber.bLetterform  = 0;
1189     lpOTM->otmPanoseNumber.bMidline     = 0;
1190     lpOTM->otmPanoseNumber.bXHeight     = 0;
1191
1192     lpOTM->otmfsSelection     = 0;
1193     lpOTM->otmfsType          = 0;
1194
1195     /*
1196      Further fill of the structure not implemented,
1197      Needs real values for the structure members
1198      */
1199     
1200     return rtn;
1201 }
1202
1203 /***********************************************************************
1204  *           GetOutlineTextMetricsW [GDI32.208]
1205  */
1206 UINT WINAPI GetOutlineTextMetricsW(
1207     HDC hdc,    /* [in]  Handle of device context */
1208     UINT cbData, /* [in]  Size of metric data array */
1209     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1210 {
1211     FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1212     return 0; 
1213 }
1214
1215 /***********************************************************************
1216  *           GetCharWidth16    (GDI.350)
1217  */
1218 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1219                               LPINT16 buffer )
1220 {
1221     BOOL        retVal = FALSE;
1222
1223     if( firstChar != lastChar )
1224     {
1225         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1226                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1227         if( buf32 )
1228         {
1229             LPINT       obuf32 = buf32;
1230             int         i;
1231
1232             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1233             if (retVal)
1234             {
1235                 for (i = firstChar; i <= lastChar; i++)
1236                     *buffer++ = *buf32++;
1237             }
1238             HeapFree(GetProcessHeap(), 0, obuf32);
1239         }
1240     }
1241     else /* happens quite often to warrant a special treatment */
1242     {
1243         INT chWidth;
1244         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1245        *buffer = chWidth;
1246     }
1247     return retVal;
1248 }
1249
1250
1251 /***********************************************************************
1252  *           GetCharWidth32A    (GDI32.155)
1253  */
1254 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1255                                LPINT buffer )
1256 {
1257     UINT i, extra;
1258     BOOL ret = FALSE;
1259     DC * dc = DC_GetDCPtr( hdc );
1260     if (!dc) return FALSE;
1261
1262     if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1263     {
1264         /* convert device units to logical */
1265
1266         extra = dc->vportExtX >> 1;
1267         for( i = firstChar; i <= lastChar; i++, buffer++ )
1268             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1269         ret = TRUE;
1270     }
1271     GDI_ReleaseObj( hdc );
1272     return ret;
1273 }
1274
1275
1276 /***********************************************************************
1277  *           GetCharWidth32W    (GDI32.158)
1278  */
1279 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1280                                LPINT buffer )
1281 {
1282     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1283 }
1284
1285
1286 /* FIXME: all following APIs ******************************************/
1287  
1288
1289 /***********************************************************************
1290  *           SetMapperFlags16    (GDI.349)
1291  */
1292 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1293 {
1294     return SetMapperFlags( hDC, dwFlag );
1295 }
1296
1297
1298 /***********************************************************************
1299  *           SetMapperFlags    (GDI32.322)
1300  */
1301 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1302 {
1303     DC *dc = DC_GetDCPtr( hDC );
1304     DWORD ret = 0; 
1305     if(!dc) return 0;
1306     if(dc->funcs->pSetMapperFlags)
1307         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1308     else
1309         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1310     GDI_ReleaseObj( hDC );
1311     return ret;
1312 }
1313
1314 /***********************************************************************
1315  *          GetAspectRatioFilterEx16  (GDI.486)
1316  */
1317 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1318 {
1319   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1320   return FALSE;
1321 }
1322
1323 /***********************************************************************
1324  *          GetAspectRatioFilterEx  (GDI32.142)
1325  */
1326 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1327 {
1328   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1329   return FALSE;
1330 }
1331
1332 /***********************************************************************
1333  *           GetCharABCWidths16   (GDI.307)
1334  */
1335 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1336                                   LPABC16 abc )
1337 {
1338     ABC abc32;
1339     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1340     abc->abcA = abc32.abcA;
1341     abc->abcB = abc32.abcB;
1342     abc->abcC = abc32.abcC;
1343     return TRUE;
1344 }
1345
1346
1347 /***********************************************************************
1348  *           GetCharABCWidthsA   (GDI32.149)
1349  */
1350 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1351                                   LPABC abc )
1352 {
1353     return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1354 }
1355
1356
1357 /******************************************************************************
1358  * GetCharABCWidthsW [GDI32.152]  Retrieves widths of characters in range
1359  *
1360  * PARAMS
1361  *    hdc       [I] Handle of device context
1362  *    firstChar [I] First character in range to query
1363  *    lastChar  [I] Last character in range to query
1364  *    abc       [O] Address of character-width structure
1365  *
1366  * NOTES
1367  *    Only works with TrueType fonts
1368  *
1369  * RETURNS
1370  *    Success: TRUE
1371  *    Failure: FALSE
1372  */
1373 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1374                                    LPABC abc )
1375 {
1376     /* No TrueType fonts in Wine so far */
1377     FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1378     return FALSE;
1379 }
1380
1381
1382 /***********************************************************************
1383  *           GetGlyphOutline16    (GDI.309)
1384  */
1385 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1386                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1387                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1388 {
1389     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1390           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1391     return (DWORD)-1; /* failure */
1392 }
1393
1394
1395 /***********************************************************************
1396  *           GetGlyphOutlineA    (GDI32.186)
1397  */
1398 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1399                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1400                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1401 {
1402     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1403           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1404     return (DWORD)-1; /* failure */
1405 }
1406
1407 /***********************************************************************
1408  *           GetGlyphOutlineW    (GDI32.187)
1409  */
1410 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1411                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1412                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1413 {
1414     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1415           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1416     return (DWORD)-1; /* failure */
1417 }
1418
1419 /***********************************************************************
1420  *           CreateScalableFontResource16   (GDI.310)
1421  */
1422 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1423                                             LPCSTR lpszResourceFile,
1424                                             LPCSTR fontFile, LPCSTR path )
1425 {
1426     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1427                                           fontFile, path );
1428 }
1429
1430 /***********************************************************************
1431  *           CreateScalableFontResourceA   (GDI32.62)
1432  */
1433 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1434                                              LPCSTR lpszResourceFile,
1435                                              LPCSTR lpszFontFile,
1436                                              LPCSTR lpszCurrentPath )
1437 {
1438     /* fHidden=1 - only visible for the calling app, read-only, not
1439      * enumbered with EnumFonts/EnumFontFamilies
1440      * lpszCurrentPath can be NULL
1441      */
1442     FIXME("(%ld,%s,%s,%s): stub\n",
1443           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1444     return FALSE; /* create failed */
1445 }
1446
1447 /***********************************************************************
1448  *           CreateScalableFontResourceW   (GDI32.63)
1449  */
1450 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1451                                              LPCWSTR lpszResourceFile,
1452                                              LPCWSTR lpszFontFile,
1453                                              LPCWSTR lpszCurrentPath )
1454 {
1455     FIXME("(%ld,%p,%p,%p): stub\n",
1456           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1457     return FALSE; /* create failed */
1458 }
1459
1460
1461 /*************************************************************************
1462  *             GetRasterizerCaps16   (GDI.313)
1463  */
1464 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1465 {
1466     return GetRasterizerCaps( lprs, cbNumBytes );
1467 }
1468
1469
1470 /*************************************************************************
1471  *             GetRasterizerCaps   (GDI32.216)
1472  */
1473 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1474 {
1475   lprs->nSize = sizeof(RASTERIZER_STATUS);
1476   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1477   lprs->nLanguageID = 0;
1478   return TRUE;
1479 }
1480
1481
1482 /*************************************************************************
1483  *             GetKerningPairs16   (GDI.332)
1484  */
1485 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1486                                 LPKERNINGPAIR16 lpKerningPairs )
1487 {
1488     /* At this time kerning is ignored (set to 0) */
1489     int i;
1490     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1491     for (i = 0; i < cPairs; i++) 
1492         lpKerningPairs[i].iKernAmount = 0;
1493     return 0;
1494 }
1495
1496
1497
1498 /*************************************************************************
1499  *             GetKerningPairsA   (GDI32.192)
1500  */
1501 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1502                                  LPKERNINGPAIR lpKerningPairs )
1503 {
1504     int i;
1505     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1506     for (i = 0; i < cPairs; i++) 
1507         lpKerningPairs[i].iKernAmount = 0;
1508     return 0;
1509 }
1510
1511
1512 /*************************************************************************
1513  *             GetKerningPairsW   (GDI32.193)
1514  */
1515 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1516                                  LPKERNINGPAIR lpKerningPairs )
1517 {
1518     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1519 }
1520
1521 /*************************************************************************
1522  * TranslateCharsetInfo [GDI32.382]
1523  *
1524  * Fills a CHARSETINFO structure for a character set, code page, or
1525  * font. This allows making the correspondance between different labelings
1526  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1527  * of the same encoding.
1528  *
1529  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1530  * only one codepage should be set in *lpSrc.
1531  *
1532  * RETURNS
1533  *   TRUE on success, FALSE on failure.
1534  *
1535  */
1536 BOOL WINAPI TranslateCharsetInfo(
1537   LPDWORD lpSrc, /*
1538        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1539        if flags == TCI_SRCCHARSET: a character set value
1540        if flags == TCI_SRCCODEPAGE: a code page value
1541                  */
1542   LPCHARSETINFO lpCs, /* structure to receive charset information */
1543   DWORD flags /* determines interpretation of lpSrc */
1544 ) {
1545     int index = 0;
1546     switch (flags) {
1547     case TCI_SRCFONTSIG:
1548         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1549       break;
1550     case TCI_SRCCODEPAGE:
1551       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1552       break;
1553     case TCI_SRCCHARSET:
1554       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1555       break;
1556     default:
1557       return FALSE;
1558     }
1559     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1560     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1561     return TRUE;
1562 }
1563
1564 /*************************************************************************
1565  *             GetFontLanguageInfo   (GDI32.182)
1566  */
1567 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1568         /* return value 0 is correct for most cases anyway */
1569         FIXME("(%x):stub!\n", hdc);
1570         return 0;
1571 }
1572
1573 /*************************************************************************
1574  *             GetFontLanguageInfo   (GDI.616)
1575  */
1576 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1577         /* return value 0 is correct for most cases anyway */
1578         FIXME("(%x):stub!\n",hdc);
1579         return 0;
1580 }
1581
1582 /*************************************************************************
1583  * GetFontData [GDI32.181] Retrieve data for TrueType font
1584  *
1585  * RETURNS
1586  *
1587  * success: Number of bytes returned 
1588  * failure: GDI_ERROR
1589  *
1590  * NOTES
1591  *
1592  * Calls SetLastError()  
1593  *
1594  * BUGS
1595  *
1596  * Unimplemented
1597  */
1598 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1599     LPVOID buffer, DWORD length)
1600 {
1601     FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1602     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1603     return GDI_ERROR;
1604 }
1605
1606 /*************************************************************************
1607  * GetFontData16 [GDI.311]
1608  *
1609  */
1610 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1611                             LPVOID lpvBuffer, DWORD cbData)
1612 {
1613     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1614 }
1615
1616 /*************************************************************************
1617  * GetCharacterPlacementA [GDI32.160]
1618  *
1619  * NOTES:
1620  *  the web browser control of ie4 calls this with dwFlags=0
1621  */
1622 DWORD WINAPI
1623 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1624                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1625                          DWORD dwFlags)
1626 {
1627     DWORD ret=0;
1628     SIZE size;
1629
1630     TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1631           debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1632
1633     TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1634           "lpOutString=%p lpGlyphs=%p\n",
1635           lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1636           lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1637
1638     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
1639     if(lpResults->lpOrder)      FIXME("reordering not implemented\n");
1640     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1641     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1642     if(lpResults->lpGlyphs)     FIXME("glyphs not implemented\n");
1643
1644     /* copy will do if the GCP_REORDER flag is not set */
1645     if(lpResults->lpOutString)
1646     {
1647       lstrcpynA(lpResults->lpOutString, lpString, uCount);
1648     }
1649
1650     if (lpResults->lpDx)
1651     {
1652       int i, c;
1653       for (i=0; i<uCount;i++)
1654       { 
1655         if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1656           lpResults->lpDx[i]= c;
1657       }
1658     }
1659
1660     if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1661       ret = MAKELONG(size.cx, size.cy);
1662
1663     return ret;
1664 }
1665
1666 /*************************************************************************
1667  * GetCharacterPlacementW [GDI32.161]
1668  */
1669 DWORD WINAPI
1670 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1671                          INT nMaxExtent, GCP_RESULTSW *lpResults,
1672                          DWORD dwFlags)
1673 {
1674     /* return value 0 is correct for most cases anyway */
1675     FIXME(":stub!\n");
1676     return 0;
1677 }
1678
1679 /*************************************************************************
1680  *      GetCharABCWidthsFloatA [GDI32.150]
1681  */
1682 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1683                                         LPABCFLOAT lpABCF)
1684 {
1685        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1686        return 0;
1687 }
1688
1689 /*************************************************************************
1690  *      GetCharABCWidthsFloatW [GDI32.151]
1691  */
1692 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1693                                         UINT iLastChar, LPABCFLOAT lpABCF)
1694 {
1695        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1696        return 0;
1697 }
1698
1699 /*************************************************************************
1700  *      GetCharWidthFloatA [GDI32.156]
1701  */
1702 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1703                                     UINT iLastChar, PFLOAT pxBuffer)
1704 {
1705        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1706        return 0;
1707 }
1708
1709 /*************************************************************************
1710  *      GetCharWidthFloatW [GDI32.157]
1711  */
1712 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1713                                     UINT iLastChar, PFLOAT pxBuffer)
1714 {
1715        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1716        return 0;
1717 }
1718  
1719
1720 /***********************************************************************
1721  *                                                                     *
1722  *           Font Resource API                                         *
1723  *                                                                     *
1724  ***********************************************************************/
1725 /***********************************************************************
1726  *           AddFontResource16    (GDI.119)
1727  *
1728  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1729  *
1730  *  FIXME: Load header and find the best-matching font in the fontList;
1731  *         fixup dfPoints if all metrics are identical, otherwise create
1732  *         new fontAlias. When soft font support is ready this will
1733  *         simply create a new fontResource ('filename' will go into
1734  *         the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
1735  *         flag set. 
1736  */
1737 INT16 WINAPI AddFontResource16( LPCSTR filename )
1738 {
1739     return AddFontResourceA( filename );
1740 }
1741
1742
1743 /***********************************************************************
1744  *           AddFontResourceA    (GDI32.2)
1745  */
1746 INT WINAPI AddFontResourceA( LPCSTR str )
1747 {
1748     FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1749             "this font manually.\n", debugres_a(str));
1750     return 1;
1751 }
1752
1753
1754 /***********************************************************************
1755  *           AddFontResourceW    (GDI32.4)
1756  */
1757 INT WINAPI AddFontResourceW( LPCWSTR str )
1758 {
1759     FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1760             "this font manually.\n", debugres_w(str));
1761     return 1;
1762 }
1763
1764 /***********************************************************************
1765  *           RemoveFontResource16    (GDI.136)
1766  */
1767 BOOL16 WINAPI RemoveFontResource16( SEGPTR str )
1768 {
1769     FIXME("(%s): stub\n",       debugres_a(PTR_SEG_TO_LIN(str)));
1770     return TRUE;
1771 }
1772
1773
1774 /***********************************************************************
1775  *           RemoveFontResourceA    (GDI32.284)
1776  */
1777 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1778 {
1779 /*  This is how it should look like */
1780 /*
1781     fontResource** ppfr;
1782     BOOL32 retVal = FALSE;
1783
1784     EnterCriticalSection( &crtsc_fonts_X11 );
1785     for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1786          if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1787          {
1788              if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1789                  (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1790              {
1791                  if( (*ppfr)->fo_count )
1792                      (*ppfr)->fr_flags |= FR_REMOVED;
1793                  else
1794                      XFONT_RemoveFontResource( ppfr );
1795              }
1796              retVal = TRUE;
1797          }
1798     LeaveCriticalSection( &crtsc_fonts_X11 );
1799     return retVal;
1800  */
1801     FIXME("(%s): stub\n", debugres_a(str));
1802     return TRUE;
1803 }
1804
1805
1806 /***********************************************************************
1807  *           RemoveFontResourceW    (GDI32.286)
1808  */
1809 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1810 {
1811     FIXME("(%s): stub\n", debugres_w(str) );
1812     return TRUE;
1813 }