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