Destroying cursor is not necessarily an error.
[wine/hacks.git] / objects / font.c
blob33120b6883e51b72d3e7897ab3d855529183bfe2
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
6 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include <assert.h>
11 #include "winerror.h"
12 #include "winnls.h"
13 #include "wine/unicode.h"
14 #include "font.h"
15 #include "options.h"
16 #include "debugtools.h"
17 #include "gdi.h"
19 DEFAULT_DEBUG_CHANNEL(font);
20 DECLARE_DEBUG_CHANNEL(gdi);
22 #define ENUM_UNICODE 0x00000001
24 typedef struct
26 LPLOGFONT16 lpLogFontParam;
27 FONTENUMPROCEX16 lpEnumFunc;
28 LPARAM lpData;
30 LPNEWTEXTMETRICEX16 lpTextMetric;
31 LPENUMLOGFONTEX16 lpLogFont;
32 SEGPTR segTextMetric;
33 SEGPTR segLogFont;
34 } fontEnum16;
36 typedef struct
38 LPLOGFONTW lpLogFontParam;
39 FONTENUMPROCEXW lpEnumFunc;
40 LPARAM lpData;
42 DWORD dwFlags;
43 } fontEnum32;
46 * For TranslateCharsetInfo
48 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
49 #define MAXTCIINDEX 32
50 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
51 /* ANSI */
52 { ANSI_CHARSET, 1252, FS(0)},
53 { EASTEUROPE_CHARSET, 1250, FS(1)},
54 { RUSSIAN_CHARSET, 1251, FS(2)},
55 { GREEK_CHARSET, 1253, FS(3)},
56 { TURKISH_CHARSET, 1254, FS(4)},
57 { HEBREW_CHARSET, 1255, FS(5)},
58 { ARABIC_CHARSET, 1256, FS(6)},
59 { BALTIC_CHARSET, 1257, FS(7)},
60 /* reserved by ANSI */
61 { DEFAULT_CHARSET, 0, FS(0)},
62 { DEFAULT_CHARSET, 0, FS(0)},
63 { DEFAULT_CHARSET, 0, FS(0)},
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 /* ANSI and OEM */
70 { THAI_CHARSET, 874, FS(16)},
71 { SHIFTJIS_CHARSET, 932, FS(17)},
72 { GB2312_CHARSET, 936, FS(18)},
73 { HANGEUL_CHARSET, 949, FS(19)},
74 { CHINESEBIG5_CHARSET, 950, FS(20)},
75 { JOHAB_CHARSET, 1361, FS(21)},
76 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
84 { DEFAULT_CHARSET, 0, FS(0)},
85 /* reserved for system */
86 { DEFAULT_CHARSET, 0, FS(0)},
87 { DEFAULT_CHARSET, 0, FS(0)},
90 /* ### start build ### */
91 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
92 /* ### stop build ### */
94 /***********************************************************************
95 * LOGFONT conversion functions.
97 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
99 font16->lfHeight = font32->lfHeight;
100 font16->lfWidth = font32->lfWidth;
101 font16->lfEscapement = font32->lfEscapement;
102 font16->lfOrientation = font32->lfOrientation;
103 font16->lfWeight = font32->lfWeight;
104 font16->lfItalic = font32->lfItalic;
105 font16->lfUnderline = font32->lfUnderline;
106 font16->lfStrikeOut = font32->lfStrikeOut;
107 font16->lfCharSet = font32->lfCharSet;
108 font16->lfOutPrecision = font32->lfOutPrecision;
109 font16->lfClipPrecision = font32->lfClipPrecision;
110 font16->lfQuality = font32->lfQuality;
111 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
112 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
115 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
117 font16->lfHeight = font32->lfHeight;
118 font16->lfWidth = font32->lfWidth;
119 font16->lfEscapement = font32->lfEscapement;
120 font16->lfOrientation = font32->lfOrientation;
121 font16->lfWeight = font32->lfWeight;
122 font16->lfItalic = font32->lfItalic;
123 font16->lfUnderline = font32->lfUnderline;
124 font16->lfStrikeOut = font32->lfStrikeOut;
125 font16->lfCharSet = font32->lfCharSet;
126 font16->lfOutPrecision = font32->lfOutPrecision;
127 font16->lfClipPrecision = font32->lfClipPrecision;
128 font16->lfQuality = font32->lfQuality;
129 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
130 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
131 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
132 font16->lfFaceName[LF_FACESIZE-1] = 0;
135 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
137 font32->lfHeight = font16->lfHeight;
138 font32->lfWidth = font16->lfWidth;
139 font32->lfEscapement = font16->lfEscapement;
140 font32->lfOrientation = font16->lfOrientation;
141 font32->lfWeight = font16->lfWeight;
142 font32->lfItalic = font16->lfItalic;
143 font32->lfUnderline = font16->lfUnderline;
144 font32->lfStrikeOut = font16->lfStrikeOut;
145 font32->lfCharSet = font16->lfCharSet;
146 font32->lfOutPrecision = font16->lfOutPrecision;
147 font32->lfClipPrecision = font16->lfClipPrecision;
148 font32->lfQuality = font16->lfQuality;
149 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
150 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
153 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
155 font32->lfHeight = font16->lfHeight;
156 font32->lfWidth = font16->lfWidth;
157 font32->lfEscapement = font16->lfEscapement;
158 font32->lfOrientation = font16->lfOrientation;
159 font32->lfWeight = font16->lfWeight;
160 font32->lfItalic = font16->lfItalic;
161 font32->lfUnderline = font16->lfUnderline;
162 font32->lfStrikeOut = font16->lfStrikeOut;
163 font32->lfCharSet = font16->lfCharSet;
164 font32->lfOutPrecision = font16->lfOutPrecision;
165 font32->lfClipPrecision = font16->lfClipPrecision;
166 font32->lfQuality = font16->lfQuality;
167 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
168 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
169 font32->lfFaceName[LF_FACESIZE-1] = 0;
172 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
174 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
175 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
176 LF_FACESIZE);
179 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
181 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
182 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
183 LF_FACESIZE, NULL, NULL);
186 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
188 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
189 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
190 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
191 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
194 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
196 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
198 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
199 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
200 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
201 font32->elfStyle[LF_FACESIZE-1] = 0;
202 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
203 font32->elfScript[LF_FACESIZE-1] = 0;
206 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
208 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
210 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
211 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
212 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
213 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
214 font16->elfStyle, LF_FACESIZE, NULL, NULL );
215 font16->elfStyle[LF_FACESIZE-1] = '\0';
216 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
217 font16->elfScript, LF_FACESIZE, NULL, NULL );
218 font16->elfScript[LF_FACESIZE-1] = '\0';
221 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
223 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
225 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
226 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
227 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
228 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
229 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
230 fontA->elfStyle[LF_FACESIZE-1] = '\0';
231 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
232 fontA->elfScript, LF_FACESIZE, NULL, NULL );
233 fontA->elfScript[LF_FACESIZE-1] = '\0';
236 /***********************************************************************
237 * TEXTMETRIC conversion functions.
239 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
241 ptm16->tmHeight = ptm32->tmHeight;
242 ptm16->tmAscent = ptm32->tmAscent;
243 ptm16->tmDescent = ptm32->tmDescent;
244 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
245 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
246 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
247 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
248 ptm16->tmWeight = ptm32->tmWeight;
249 ptm16->tmOverhang = ptm32->tmOverhang;
250 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
251 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
252 ptm16->tmFirstChar = ptm32->tmFirstChar;
253 ptm16->tmLastChar = ptm32->tmLastChar;
254 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
255 ptm16->tmBreakChar = ptm32->tmBreakChar;
256 ptm16->tmItalic = ptm32->tmItalic;
257 ptm16->tmUnderlined = ptm32->tmUnderlined;
258 ptm16->tmStruckOut = ptm32->tmStruckOut;
259 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
260 ptm16->tmCharSet = ptm32->tmCharSet;
263 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
265 ptm16->tmHeight = ptm32->tmHeight;
266 ptm16->tmAscent = ptm32->tmAscent;
267 ptm16->tmDescent = ptm32->tmDescent;
268 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
269 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
270 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
271 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
272 ptm16->tmWeight = ptm32->tmWeight;
273 ptm16->tmOverhang = ptm32->tmOverhang;
274 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
275 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
276 ptm16->tmFirstChar = ptm32->tmFirstChar;
277 ptm16->tmLastChar = ptm32->tmLastChar;
278 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
279 ptm16->tmBreakChar = ptm32->tmBreakChar;
280 ptm16->tmItalic = ptm32->tmItalic;
281 ptm16->tmUnderlined = ptm32->tmUnderlined;
282 ptm16->tmStruckOut = ptm32->tmStruckOut;
283 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
284 ptm16->tmCharSet = ptm32->tmCharSet;
287 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
289 ptm32->tmHeight = ptm16->tmHeight;
290 ptm32->tmAscent = ptm16->tmAscent;
291 ptm32->tmDescent = ptm16->tmDescent;
292 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
293 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
294 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
295 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
296 ptm32->tmWeight = ptm16->tmWeight;
297 ptm32->tmOverhang = ptm16->tmOverhang;
298 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
299 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
300 ptm32->tmFirstChar = ptm16->tmFirstChar;
301 ptm32->tmLastChar = ptm16->tmLastChar;
302 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
303 ptm32->tmBreakChar = ptm16->tmBreakChar;
304 ptm32->tmItalic = ptm16->tmItalic;
305 ptm32->tmUnderlined = ptm16->tmUnderlined;
306 ptm32->tmStruckOut = ptm16->tmStruckOut;
307 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
308 ptm32->tmCharSet = ptm16->tmCharSet;
311 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
313 ptm32->tmHeight = ptm16->tmHeight;
314 ptm32->tmAscent = ptm16->tmAscent;
315 ptm32->tmDescent = ptm16->tmDescent;
316 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
317 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
318 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
319 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
320 ptm32->tmWeight = ptm16->tmWeight;
321 ptm32->tmOverhang = ptm16->tmOverhang;
322 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
323 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
324 ptm32->tmFirstChar = ptm16->tmFirstChar;
325 ptm32->tmLastChar = ptm16->tmLastChar;
326 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
327 ptm32->tmBreakChar = ptm16->tmBreakChar;
328 ptm32->tmItalic = ptm16->tmItalic;
329 ptm32->tmUnderlined = ptm16->tmUnderlined;
330 ptm32->tmStruckOut = ptm16->tmStruckOut;
331 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
332 ptm32->tmCharSet = ptm16->tmCharSet;
335 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
337 ptm32W->tmHeight = ptm32A->tmHeight;
338 ptm32W->tmAscent = ptm32A->tmAscent;
339 ptm32W->tmDescent = ptm32A->tmDescent;
340 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
341 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
342 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
343 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
344 ptm32W->tmWeight = ptm32A->tmWeight;
345 ptm32W->tmOverhang = ptm32A->tmOverhang;
346 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
347 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
348 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
349 ptm32W->tmLastChar = ptm32A->tmLastChar;
350 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
351 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
352 ptm32W->tmItalic = ptm32A->tmItalic;
353 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
354 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
355 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
356 ptm32W->tmCharSet = ptm32A->tmCharSet;
359 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
361 ptmA->tmHeight = ptmW->tmHeight;
362 ptmA->tmAscent = ptmW->tmAscent;
363 ptmA->tmDescent = ptmW->tmDescent;
364 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
365 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
366 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
367 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
368 ptmA->tmWeight = ptmW->tmWeight;
369 ptmA->tmOverhang = ptmW->tmOverhang;
370 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
371 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
372 ptmA->tmFirstChar = ptmW->tmFirstChar;
373 ptmA->tmLastChar = ptmW->tmLastChar;
374 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
375 ptmA->tmBreakChar = ptmW->tmBreakChar;
376 ptmA->tmItalic = ptmW->tmItalic;
377 ptmA->tmUnderlined = ptmW->tmUnderlined;
378 ptmA->tmStruckOut = ptmW->tmStruckOut;
379 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
380 ptmA->tmCharSet = ptmW->tmCharSet;
384 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
386 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
387 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
388 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
389 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
390 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
391 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
394 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
396 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
397 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
398 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
399 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
400 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
401 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
404 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
406 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
407 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
408 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
409 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
410 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
411 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
415 /***********************************************************************
416 * CreateFontIndirect (GDI.57)
418 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
420 LOGFONTW lfW;
422 if(plf16) {
423 FONT_LogFont16ToW( plf16, &lfW );
424 return CreateFontIndirectW( &lfW );
425 } else {
426 return CreateFontIndirectW( NULL );
431 /***********************************************************************
432 * CreateFontIndirectA (GDI32.@)
434 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
436 LOGFONTW lfW;
438 if (plfA) {
439 FONT_LogFontAToW( plfA, &lfW );
440 return CreateFontIndirectW( &lfW );
441 } else
442 return CreateFontIndirectW( NULL );
446 /***********************************************************************
447 * CreateFontIndirectW (GDI32.@)
449 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
451 HFONT hFont = 0;
453 if (plf)
455 FONTOBJ* fontPtr;
456 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
458 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
460 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
461 plf->lfHeight, plf->lfWidth,
462 plf->lfEscapement, plf->lfOrientation,
463 plf->lfPitchAndFamily,
464 debugstr_w(plf->lfFaceName),
465 plf->lfWeight > 400 ? "Bold" : "",
466 plf->lfItalic ? "Italic" : "", hFont);
468 if (plf->lfEscapement != plf->lfOrientation) {
469 /* this should really depend on whether GM_ADVANCED is set */
470 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
471 WARN("orientation angle %f set to "
472 "escapement angle %f for new font %04x\n",
473 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
475 GDI_ReleaseObj( hFont );
478 else WARN("(NULL) => NULL\n");
480 return hFont;
483 /***********************************************************************
484 * CreateFont (GDI.56)
486 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
487 INT16 weight, BYTE italic, BYTE underline,
488 BYTE strikeout, BYTE charset, BYTE outpres,
489 BYTE clippres, BYTE quality, BYTE pitch,
490 LPCSTR name )
492 LOGFONT16 logfont;
494 logfont.lfHeight = height;
495 logfont.lfWidth = width;
496 logfont.lfEscapement = esc;
497 logfont.lfOrientation = orient;
498 logfont.lfWeight = weight;
499 logfont.lfItalic = italic;
500 logfont.lfUnderline = underline;
501 logfont.lfStrikeOut = strikeout;
502 logfont.lfCharSet = charset;
503 logfont.lfOutPrecision = outpres;
504 logfont.lfClipPrecision = clippres;
505 logfont.lfQuality = quality;
506 logfont.lfPitchAndFamily = pitch;
508 if (name)
509 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
510 else
511 logfont.lfFaceName[0] = '\0';
513 return CreateFontIndirect16( &logfont );
516 /*************************************************************************
517 * CreateFontA (GDI32.@)
519 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
520 INT orient, INT weight, DWORD italic,
521 DWORD underline, DWORD strikeout, DWORD charset,
522 DWORD outpres, DWORD clippres, DWORD quality,
523 DWORD pitch, LPCSTR name )
525 LOGFONTA logfont;
527 logfont.lfHeight = height;
528 logfont.lfWidth = width;
529 logfont.lfEscapement = esc;
530 logfont.lfOrientation = orient;
531 logfont.lfWeight = weight;
532 logfont.lfItalic = italic;
533 logfont.lfUnderline = underline;
534 logfont.lfStrikeOut = strikeout;
535 logfont.lfCharSet = charset;
536 logfont.lfOutPrecision = outpres;
537 logfont.lfClipPrecision = clippres;
538 logfont.lfQuality = quality;
539 logfont.lfPitchAndFamily = pitch;
541 if (name)
542 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
543 else
544 logfont.lfFaceName[0] = '\0';
546 return CreateFontIndirectA( &logfont );
549 /*************************************************************************
550 * CreateFontW (GDI32.@)
552 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
553 INT orient, INT weight, DWORD italic,
554 DWORD underline, DWORD strikeout, DWORD charset,
555 DWORD outpres, DWORD clippres, DWORD quality,
556 DWORD pitch, LPCWSTR name )
558 LOGFONTW logfont;
560 logfont.lfHeight = height;
561 logfont.lfWidth = width;
562 logfont.lfEscapement = esc;
563 logfont.lfOrientation = orient;
564 logfont.lfWeight = weight;
565 logfont.lfItalic = italic;
566 logfont.lfUnderline = underline;
567 logfont.lfStrikeOut = strikeout;
568 logfont.lfCharSet = charset;
569 logfont.lfOutPrecision = outpres;
570 logfont.lfClipPrecision = clippres;
571 logfont.lfQuality = quality;
572 logfont.lfPitchAndFamily = pitch;
574 if (name)
575 lstrcpynW(logfont.lfFaceName, name,
576 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
577 else
578 logfont.lfFaceName[0] = '\0';
580 return CreateFontIndirectW( &logfont );
584 /***********************************************************************
585 * FONT_GetObject16
587 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
589 LOGFONT16 lf16;
591 FONT_LogFontWTo16( &font->logfont, &lf16 );
593 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
594 memcpy( buffer, &lf16, count );
595 return count;
598 /***********************************************************************
599 * FONT_GetObjectA
601 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
603 LOGFONTA lfA;
605 FONT_LogFontWToA( &font->logfont, &lfA );
607 if (count > sizeof(lfA)) count = sizeof(lfA);
608 memcpy( buffer, &lfA, count );
609 return count;
611 /***********************************************************************
612 * FONT_GetObjectW
614 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
616 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
617 memcpy( buffer, &font->logfont, count );
618 return count;
622 /***********************************************************************
623 * FONT_EnumInstance16
625 * Called by the device driver layer to pass font info
626 * down to the application.
628 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
629 DWORD fType, LPARAM lp )
631 #define pfe ((fontEnum16*)lp)
632 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
633 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
635 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
636 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
638 return FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
639 (UINT16)fType, (LPARAM)pfe->lpData );
641 #undef pfe
642 return 1;
645 /***********************************************************************
646 * FONT_EnumInstance
648 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
649 DWORD fType, LPARAM lp )
651 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
653 #define pfe ((fontEnum32*)lp)
654 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
655 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
657 /* convert font metrics */
659 if( pfe->dwFlags & ENUM_UNICODE )
661 return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
663 else
665 ENUMLOGFONTEXA logfont;
666 NEWTEXTMETRICEXA tmA;
668 FONT_EnumLogFontExWToA( plf, &logfont);
669 FONT_NewTextMetricExWToA( ptm, &tmA );
671 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
672 (LPNEWTEXTMETRICEXW)&tmA, fType,
673 pfe->lpData );
676 #undef pfe
677 return 1;
680 /***********************************************************************
681 * EnumFontFamiliesEx16 (GDI.613)
683 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
684 FONTENUMPROCEX16 efproc, LPARAM lParam,
685 DWORD dwFlags)
687 BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
688 INT16 retVal = 0;
689 DC* dc = DC_GetDCPtr( hDC );
691 if (!dc) return 0;
692 enum_func = dc->funcs->pEnumDeviceFonts;
693 GDI_ReleaseObj( hDC );
695 if (enum_func)
697 NEWTEXTMETRICEX16 tm16;
698 ENUMLOGFONTEX16 lf16;
699 fontEnum16 fe16;
700 LOGFONTW lfW;
701 FONT_LogFont16ToW(plf, &lfW);
703 fe16.lpLogFontParam = plf;
704 fe16.lpEnumFunc = efproc;
705 fe16.lpData = lParam;
706 fe16.lpTextMetric = &tm16;
707 fe16.lpLogFont = &lf16;
708 fe16.segTextMetric = MapLS( &tm16 );
709 fe16.segLogFont = MapLS( &lf16 );
711 retVal = enum_func( hDC, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
712 UnMapLS( fe16.segTextMetric );
713 UnMapLS( fe16.segLogFont );
715 return retVal;
718 /***********************************************************************
719 * FONT_EnumFontFamiliesEx
721 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
722 FONTENUMPROCEXW efproc,
723 LPARAM lParam, DWORD dwUnicode)
725 BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
726 INT ret = 1;
727 DC *dc = DC_GetDCPtr( hDC );
728 fontEnum32 fe32;
729 BOOL enum_gdi_fonts;
731 if (!dc) return 0;
733 fe32.lpLogFontParam = plf;
734 fe32.lpEnumFunc = efproc;
735 fe32.lpData = lParam;
736 fe32.dwFlags = dwUnicode;
738 enum_func = dc->funcs->pEnumDeviceFonts;
739 GDI_ReleaseObj( hDC );
740 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
742 if (!enum_func && !enum_gdi_fonts) return 0;
744 if (enum_gdi_fonts)
745 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
746 if (ret && enum_func)
747 ret = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
748 return ret;
751 /***********************************************************************
752 * EnumFontFamiliesExW (GDI32.@)
754 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
755 FONTENUMPROCEXW efproc,
756 LPARAM lParam, DWORD dwFlags )
758 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
761 /***********************************************************************
762 * EnumFontFamiliesExA (GDI32.@)
764 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
765 FONTENUMPROCEXA efproc,
766 LPARAM lParam, DWORD dwFlags)
768 LOGFONTW lfW;
769 FONT_LogFontAToW( plf, &lfW );
771 return FONT_EnumFontFamiliesEx( hDC, &lfW,
772 (FONTENUMPROCEXW)efproc, lParam, 0);
775 /***********************************************************************
776 * EnumFontFamilies16 (GDI.330)
778 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
779 FONTENUMPROC16 efproc, LPARAM lpData )
781 LOGFONT16 lf;
783 lf.lfCharSet = DEFAULT_CHARSET;
784 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
785 else lf.lfFaceName[0] = '\0';
787 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
790 /***********************************************************************
791 * EnumFontFamiliesA (GDI32.@)
793 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
794 FONTENUMPROCA efproc, LPARAM lpData )
796 LOGFONTA lf;
798 lf.lfCharSet = DEFAULT_CHARSET;
799 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
800 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
802 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
805 /***********************************************************************
806 * EnumFontFamiliesW (GDI32.@)
808 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
809 FONTENUMPROCW efproc, LPARAM lpData )
811 LOGFONTW lf;
813 lf.lfCharSet = DEFAULT_CHARSET;
814 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
815 else lf.lfFaceName[0] = 0;
817 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
820 /***********************************************************************
821 * EnumFonts16 (GDI.70)
823 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
824 LPARAM lpData )
826 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
829 /***********************************************************************
830 * EnumFontsA (GDI32.@)
832 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
833 LPARAM lpData )
835 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
838 /***********************************************************************
839 * EnumFontsW (GDI32.@)
841 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
842 LPARAM lpData )
844 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
848 /***********************************************************************
849 * GetTextCharacterExtra (GDI.89)
851 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
853 return (INT16)GetTextCharacterExtra( hdc );
857 /***********************************************************************
858 * GetTextCharacterExtra (GDI32.@)
860 INT WINAPI GetTextCharacterExtra( HDC hdc )
862 INT ret;
863 DC *dc = DC_GetDCPtr( hdc );
864 if (!dc) return 0;
865 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
866 / dc->vportExtX );
867 GDI_ReleaseObj( hdc );
868 return ret;
872 /***********************************************************************
873 * SetTextCharacterExtra (GDI.8)
875 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
877 return (INT16)SetTextCharacterExtra( hdc, extra );
881 /***********************************************************************
882 * SetTextCharacterExtra (GDI32.@)
884 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
886 INT prev;
887 DC * dc = DC_GetDCPtr( hdc );
888 if (!dc) return 0;
889 if (dc->funcs->pSetTextCharacterExtra)
890 prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
891 else
893 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
894 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
895 dc->charExtra = abs(extra);
897 GDI_ReleaseObj( hdc );
898 return prev;
902 /***********************************************************************
903 * SetTextJustification (GDI.10)
905 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
907 return SetTextJustification( hdc, extra, breaks );
911 /***********************************************************************
912 * SetTextJustification (GDI32.@)
914 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
916 BOOL ret = TRUE;
917 DC * dc = DC_GetDCPtr( hdc );
918 if (!dc) return FALSE;
919 if (dc->funcs->pSetTextJustification)
920 ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
921 else
923 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
924 if (!extra) breaks = 0;
925 dc->breakTotalExtra = extra;
926 dc->breakCount = breaks;
927 if (breaks)
929 dc->breakExtra = extra / breaks;
930 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
932 else
934 dc->breakExtra = 0;
935 dc->breakRem = 0;
938 GDI_ReleaseObj( hdc );
939 return ret;
943 /***********************************************************************
944 * GetTextFace (GDI.92)
946 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
948 return GetTextFaceA(hdc,count,name);
951 /***********************************************************************
952 * GetTextFaceA (GDI32.@)
954 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
956 INT res = GetTextFaceW(hdc, 0, NULL);
957 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
958 GetTextFaceW( hdc, res, nameW );
960 if (name)
961 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
962 NULL, NULL);
963 else
964 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
965 HeapFree( GetProcessHeap(), 0, nameW );
966 return res;
969 /***********************************************************************
970 * GetTextFaceW (GDI32.@)
972 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
974 FONTOBJ *font;
975 INT ret = 0;
977 DC * dc = DC_GetDCPtr( hdc );
978 if (!dc) return 0;
980 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
982 if (name)
984 lstrcpynW( name, font->logfont.lfFaceName, count );
985 ret = strlenW(name);
987 else ret = strlenW(font->logfont.lfFaceName) + 1;
988 GDI_ReleaseObj( dc->hFont );
990 GDI_ReleaseObj( hdc );
991 return ret;
995 /***********************************************************************
996 * GetTextExtent (GDI.91)
998 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1000 SIZE16 size;
1001 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1002 return MAKELONG( size.cx, size.cy );
1006 /***********************************************************************
1007 * GetTextExtentPoint (GDI.471)
1009 * FIXME: Should this have a bug for compatibility?
1010 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1011 * bugs (-> MSDN KB q147647.txt).
1013 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1014 LPSIZE16 size )
1016 SIZE size32;
1017 BOOL ret;
1018 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1019 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1020 size->cx = size32.cx;
1021 size->cy = size32.cy;
1022 return (BOOL16)ret;
1026 /***********************************************************************
1027 * GetTextExtentPoint32A (GDI32.@)
1029 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1030 LPSIZE size )
1032 BOOL ret = FALSE;
1033 INT wlen;
1034 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1036 if (p) {
1037 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1038 HeapFree( GetProcessHeap(), 0, p );
1041 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1042 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1043 return ret;
1047 /***********************************************************************
1048 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1050 * Computes width and height of the specified string.
1052 * RETURNS
1053 * Success: TRUE
1054 * Failure: FALSE
1056 BOOL WINAPI GetTextExtentPoint32W(
1057 HDC hdc, /* [in] Handle of device context */
1058 LPCWSTR str, /* [in] Address of text string */
1059 INT count, /* [in] Number of characters in string */
1060 LPSIZE size) /* [out] Address of structure for string size */
1062 BOOL ret = FALSE;
1063 DC * dc = DC_GetDCPtr( hdc );
1064 if (!dc) return FALSE;
1066 if(dc->gdiFont)
1067 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1068 else if(dc->funcs->pGetTextExtentPoint)
1069 ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
1071 GDI_ReleaseObj( hdc );
1073 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1074 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1075 return ret;
1079 /***********************************************************************
1080 * GetTextExtentPointA (GDI32.@)
1082 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1083 LPSIZE size )
1085 TRACE("not bug compatible.\n");
1086 return GetTextExtentPoint32A( hdc, str, count, size );
1089 /***********************************************************************
1090 * GetTextExtentPointW (GDI32.@)
1092 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1093 LPSIZE size )
1095 TRACE("not bug compatible.\n");
1096 return GetTextExtentPoint32W( hdc, str, count, size );
1100 /***********************************************************************
1101 * GetTextExtentExPointA (GDI32.@)
1103 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1104 INT maxExt, LPINT lpnFit,
1105 LPINT alpDx, LPSIZE size )
1107 BOOL ret;
1108 INT wlen;
1109 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1110 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1111 HeapFree( GetProcessHeap(), 0, p );
1112 return ret;
1116 /***********************************************************************
1117 * GetTextExtentExPointW (GDI32.@)
1119 * Return the size of the string as it would be if it was output properly by
1120 * e.g. TextOut.
1122 * This should include
1123 * - Intercharacter spacing
1124 * - justification spacing (not yet done)
1125 * - kerning? see below
1127 * Kerning. Since kerning would be carried out by the rendering code it should
1128 * be done by the driver. However they don't support it yet. Also I am not
1129 * yet persuaded that (certainly under Win95) any kerning is actually done.
1131 * str: According to MSDN this should be null-terminated. That is not true; a
1132 * null will not terminate it early.
1133 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1134 * than count. I have seen it be either the size of the full string or
1135 * 1 less than the size of the full string. I have not seen it bear any
1136 * resemblance to the portion that would fit.
1137 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1138 * trailing intercharacter spacing and any trailing justification.
1140 * FIXME
1141 * Currently we do this by measuring each character etc. We should do it by
1142 * passing the request to the driver, perhaps by extending the
1143 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1144 * thinking about kerning issues and rounding issues in the justification.
1147 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1148 INT maxExt, LPINT lpnFit,
1149 LPINT alpDx, LPSIZE size )
1151 int index, nFit, extent;
1152 SIZE tSize;
1153 BOOL ret = FALSE;
1155 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1157 size->cx = size->cy = nFit = extent = 0;
1158 for(index = 0; index < count; index++)
1160 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1161 /* GetTextExtentPoint includes intercharacter spacing. */
1162 /* FIXME - justification needs doing yet. Remember that the base
1163 * data will not be in logical coordinates.
1165 extent += tSize.cx;
1166 if( !lpnFit || extent <= maxExt )
1167 /* It is allowed to be equal. */
1169 nFit++;
1170 if( alpDx ) alpDx[index] = extent;
1172 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1173 str++;
1175 size->cx = extent;
1176 if(lpnFit) *lpnFit = nFit;
1177 ret = TRUE;
1179 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1181 done:
1182 return ret;
1185 /***********************************************************************
1186 * GetTextMetrics (GDI.93)
1188 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1190 TEXTMETRICW tm32;
1192 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1193 FONT_TextMetricWTo16( &tm32, metrics );
1194 return TRUE;
1198 /***********************************************************************
1199 * GetTextMetricsA (GDI32.@)
1201 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1203 TEXTMETRICW tm32;
1205 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1206 FONT_TextMetricWToA( &tm32, metrics );
1207 return TRUE;
1210 /***********************************************************************
1211 * GetTextMetricsW (GDI32.@)
1213 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1215 BOOL ret = FALSE;
1216 DC * dc = DC_GetDCPtr( hdc );
1217 if (!dc) return FALSE;
1219 if (dc->gdiFont)
1220 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1221 else if (dc->funcs->pGetTextMetrics)
1222 ret = dc->funcs->pGetTextMetrics( dc, metrics );
1224 if (ret)
1226 /* device layer returns values in device units
1227 * therefore we have to convert them to logical */
1229 #define WDPTOLP(x) ((x<0)? \
1230 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1231 (abs((x)*dc->wndExtX/dc->vportExtX)))
1232 #define HDPTOLP(y) ((y<0)? \
1233 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1234 (abs((y)*dc->wndExtY/dc->vportExtY)))
1236 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1237 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1238 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1239 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1240 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1241 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1242 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1243 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1244 ret = TRUE;
1246 TRACE("text metrics:\n"
1247 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1248 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1249 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1250 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1251 " PitchAndFamily = %02x\n"
1252 " --------------------\n"
1253 " InternalLeading = %li\n"
1254 " Ascent = %li\n"
1255 " Descent = %li\n"
1256 " Height = %li\n",
1257 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1258 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1259 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1260 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1261 metrics->tmPitchAndFamily,
1262 metrics->tmInternalLeading,
1263 metrics->tmAscent,
1264 metrics->tmDescent,
1265 metrics->tmHeight );
1267 GDI_ReleaseObj( hdc );
1268 return ret;
1272 /***********************************************************************
1273 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1275 * NOTES
1276 * lpOTM should be LPOUTLINETEXTMETRIC
1278 * RETURNS
1279 * Success: Non-zero or size of required buffer
1280 * Failure: 0
1282 UINT16 WINAPI GetOutlineTextMetrics16(
1283 HDC16 hdc, /* [in] Handle of device context */
1284 UINT16 cbData, /* [in] Size of metric data array */
1285 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1287 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1288 return 0;
1292 /***********************************************************************
1293 * GetOutlineTextMetricsA (GDI32.@)
1294 * Gets metrics for TrueType fonts.
1297 * RETURNS
1298 * Success: Non-zero or size of required buffer
1299 * Failure: 0
1301 UINT WINAPI GetOutlineTextMetricsA(
1302 HDC hdc, /* [in] Handle of device context */
1303 UINT cbData, /* [in] Size of metric data array */
1304 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1306 char buf[512], *ptr;
1307 UINT ret, needed;
1308 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1309 INT left, len;
1311 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1312 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1313 return 0;
1314 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1315 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1318 needed = sizeof(OUTLINETEXTMETRICA);
1319 if(lpOTMW->otmpFamilyName)
1320 needed += WideCharToMultiByte(CP_ACP, 0,
1321 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1322 NULL, 0, NULL, NULL);
1323 if(lpOTMW->otmpFaceName)
1324 needed += WideCharToMultiByte(CP_ACP, 0,
1325 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1326 NULL, 0, NULL, NULL);
1327 if(lpOTMW->otmpStyleName)
1328 needed += WideCharToMultiByte(CP_ACP, 0,
1329 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1330 NULL, 0, NULL, NULL);
1331 if(lpOTMW->otmpFullName)
1332 needed += WideCharToMultiByte(CP_ACP, 0,
1333 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1334 NULL, 0, NULL, NULL);
1336 if(!lpOTM) {
1337 ret = needed;
1338 goto end;
1341 if(needed > cbData) {
1342 ret = 0;
1343 goto end;
1347 lpOTM->otmSize = needed;
1348 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1349 lpOTM->otmFiller = 0;
1350 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1351 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1352 lpOTM->otmfsType = lpOTMW->otmfsType;
1353 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1354 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1355 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1356 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1357 lpOTM->otmAscent = lpOTMW->otmAscent;
1358 lpOTM->otmDescent = lpOTMW->otmDescent;
1359 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1360 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1361 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1362 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1363 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1364 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1365 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1366 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1367 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1368 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1369 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1370 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1371 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1372 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1373 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1374 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1377 ptr = (char*)(lpOTM + 1);
1378 left = needed - sizeof(*lpOTM);
1380 if(lpOTMW->otmpFamilyName) {
1381 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1382 len = WideCharToMultiByte(CP_ACP, 0,
1383 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1384 ptr, left, NULL, NULL);
1385 left -= len;
1386 ptr += len;
1387 } else
1388 lpOTM->otmpFamilyName = 0;
1390 if(lpOTMW->otmpFaceName) {
1391 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1392 len = WideCharToMultiByte(CP_ACP, 0,
1393 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1394 ptr, left, NULL, NULL);
1395 left -= len;
1396 ptr += len;
1397 } else
1398 lpOTM->otmpFaceName = 0;
1400 if(lpOTMW->otmpStyleName) {
1401 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1402 len = WideCharToMultiByte(CP_ACP, 0,
1403 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1404 ptr, left, NULL, NULL);
1405 left -= len;
1406 ptr += len;
1407 } else
1408 lpOTM->otmpStyleName = 0;
1410 if(lpOTMW->otmpFullName) {
1411 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1412 len = WideCharToMultiByte(CP_ACP, 0,
1413 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1414 ptr, left, NULL, NULL);
1415 left -= len;
1416 } else
1417 lpOTM->otmpFullName = 0;
1419 assert(left == 0);
1421 ret = needed;
1423 end:
1424 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1425 HeapFree(GetProcessHeap(), 0, lpOTMW);
1427 return ret;
1431 /***********************************************************************
1432 * GetOutlineTextMetricsW [GDI32.@]
1434 UINT WINAPI GetOutlineTextMetricsW(
1435 HDC hdc, /* [in] Handle of device context */
1436 UINT cbData, /* [in] Size of metric data array */
1437 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1439 DC *dc = DC_GetDCPtr( hdc );
1440 UINT ret;
1442 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1443 if(!dc) return 0;
1445 if(dc->gdiFont)
1446 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1448 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1449 but really this should just be a return 0. */
1451 ret = sizeof(*lpOTM);
1452 if (lpOTM) {
1453 if(cbData < ret)
1454 ret = 0;
1455 else {
1456 memset(lpOTM, 0, ret);
1457 lpOTM->otmSize = sizeof(*lpOTM);
1458 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1460 Further fill of the structure not implemented,
1461 Needs real values for the structure members
1466 GDI_ReleaseObj(hdc);
1467 return ret;
1471 /***********************************************************************
1472 * GetCharWidth (GDI.350)
1474 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1475 LPINT16 buffer )
1477 BOOL retVal = FALSE;
1479 if( firstChar != lastChar )
1481 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1482 sizeof(INT)*(1 + (lastChar - firstChar)));
1483 if( buf32 )
1485 LPINT obuf32 = buf32;
1486 int i;
1488 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1489 if (retVal)
1491 for (i = firstChar; i <= lastChar; i++)
1492 *buffer++ = *buf32++;
1494 HeapFree(GetProcessHeap(), 0, obuf32);
1497 else /* happens quite often to warrant a special treatment */
1499 INT chWidth;
1500 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1501 *buffer = chWidth;
1503 return retVal;
1507 /***********************************************************************
1508 * GetCharWidthW (GDI32.@)
1509 * GetCharWidth32W (GDI32.@)
1511 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1512 LPINT buffer )
1514 UINT i, extra;
1515 BOOL ret = FALSE;
1516 DC * dc = DC_GetDCPtr( hdc );
1517 if (!dc) return FALSE;
1519 if (dc->gdiFont)
1520 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1521 else if (dc->funcs->pGetCharWidth)
1522 ret = dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer);
1524 if (ret)
1526 /* convert device units to logical */
1528 extra = dc->vportExtX >> 1;
1529 for( i = firstChar; i <= lastChar; i++, buffer++ )
1530 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1531 ret = TRUE;
1533 GDI_ReleaseObj( hdc );
1534 return ret;
1538 /***********************************************************************
1539 * GetCharWidthA (GDI32.@)
1540 * GetCharWidth32A (GDI32.@)
1542 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1543 LPINT buffer )
1545 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1546 LPSTR str;
1547 LPWSTR wstr;
1548 BOOL ret = TRUE;
1550 if(count <= 0) return FALSE;
1552 str = HeapAlloc(GetProcessHeap(), 0, count);
1553 for(i = 0; i < count; i++)
1554 str[i] = (BYTE)(firstChar + i);
1556 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1558 for(i = 0; i < wlen; i++)
1560 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1562 ret = FALSE;
1563 break;
1565 buffer++;
1568 HeapFree(GetProcessHeap(), 0, str);
1569 HeapFree(GetProcessHeap(), 0, wstr);
1571 return ret;
1575 /* FIXME: all following APIs ******************************************/
1578 /***********************************************************************
1579 * SetMapperFlags (GDI.349)
1581 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1583 return SetMapperFlags( hDC, dwFlag );
1587 /***********************************************************************
1588 * SetMapperFlags (GDI32.@)
1590 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1592 DC *dc = DC_GetDCPtr( hDC );
1593 DWORD ret = 0;
1594 if(!dc) return 0;
1595 if(dc->funcs->pSetMapperFlags)
1596 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1597 else
1598 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1599 GDI_ReleaseObj( hDC );
1600 return ret;
1603 /***********************************************************************
1604 * GetAspectRatioFilterEx (GDI.486)
1606 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1608 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1609 return FALSE;
1612 /***********************************************************************
1613 * GetAspectRatioFilterEx (GDI32.@)
1615 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1617 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1618 return FALSE;
1621 /***********************************************************************
1622 * GetCharABCWidths (GDI.307)
1624 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1625 LPABC16 abc )
1627 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1628 int i;
1630 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1631 HeapFree(GetProcessHeap(),0,abc32);
1632 return FALSE;
1635 for (i=firstChar;i<=lastChar;i++) {
1636 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1637 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1638 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1640 HeapFree(GetProcessHeap(),0,abc32);
1641 return TRUE;
1645 /***********************************************************************
1646 * GetCharABCWidthsA (GDI32.@)
1648 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1649 LPABC abc )
1651 return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1655 /******************************************************************************
1656 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1658 * PARAMS
1659 * hdc [I] Handle of device context
1660 * firstChar [I] First character in range to query
1661 * lastChar [I] Last character in range to query
1662 * abc [O] Address of character-width structure
1664 * NOTES
1665 * Only works with TrueType fonts
1667 * RETURNS
1668 * Success: TRUE
1669 * Failure: FALSE
1671 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1672 LPABC abc )
1674 int i;
1675 LPINT widths = HeapAlloc(GetProcessHeap(),0,(lastChar-firstChar+1)*sizeof(INT));
1677 FIXME("(%04x,%04x,%04x,%p), returns slightly bogus values.\n", hdc, firstChar, lastChar, abc);
1679 GetCharWidth32A(hdc,firstChar,lastChar,widths);
1681 for (i=firstChar;i<=lastChar;i++) {
1682 abc[i-firstChar].abcA = 0; /* left distance */
1683 abc[i-firstChar].abcB = widths[i-firstChar];/* width */
1684 abc[i-firstChar].abcC = 0; /* right distance */
1686 HeapFree(GetProcessHeap(),0,widths);
1687 return TRUE;
1691 /***********************************************************************
1692 * GetGlyphOutline (GDI.309)
1694 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1695 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1696 LPVOID lpBuffer, const MAT2 *lpmat2 )
1698 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1699 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1700 return (DWORD)-1; /* failure */
1704 /***********************************************************************
1705 * GetGlyphOutlineA (GDI32.@)
1707 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1708 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1709 LPVOID lpBuffer, const MAT2 *lpmat2 )
1711 return GetGlyphOutlineW(hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer,
1712 lpmat2);
1715 /***********************************************************************
1716 * GetGlyphOutlineW (GDI32.@)
1718 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1719 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1720 LPVOID lpBuffer, const MAT2 *lpmat2 )
1722 DC *dc = DC_GetDCPtr(hdc);
1723 DWORD ret;
1725 TRACE("(%04x, '%c', %04x, %p, %ld, %p, %p)\n",
1726 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1728 if(!dc) return GDI_ERROR;
1730 if(dc->gdiFont)
1731 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1732 cbBuffer, lpBuffer, lpmat2);
1733 else
1734 ret = GDI_ERROR;
1736 GDI_ReleaseObj(hdc);
1737 return ret;
1740 /***********************************************************************
1741 * CreateScalableFontResource (GDI.310)
1743 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1744 LPCSTR lpszResourceFile,
1745 LPCSTR fontFile, LPCSTR path )
1747 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1748 fontFile, path );
1751 /***********************************************************************
1752 * CreateScalableFontResourceA (GDI32.@)
1754 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1755 LPCSTR lpszResourceFile,
1756 LPCSTR lpszFontFile,
1757 LPCSTR lpszCurrentPath )
1759 /* fHidden=1 - only visible for the calling app, read-only, not
1760 * enumbered with EnumFonts/EnumFontFamilies
1761 * lpszCurrentPath can be NULL
1763 FIXME("(%ld,%s,%s,%s): stub\n",
1764 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1765 debugstr_a(lpszCurrentPath) );
1766 return FALSE; /* create failed */
1769 /***********************************************************************
1770 * CreateScalableFontResourceW (GDI32.@)
1772 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1773 LPCWSTR lpszResourceFile,
1774 LPCWSTR lpszFontFile,
1775 LPCWSTR lpszCurrentPath )
1777 FIXME("(%ld,%p,%p,%p): stub\n",
1778 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1779 return FALSE; /* create failed */
1783 /*************************************************************************
1784 * GetRasterizerCaps (GDI.313)
1786 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1788 return GetRasterizerCaps( lprs, cbNumBytes );
1792 /*************************************************************************
1793 * GetRasterizerCaps (GDI32.@)
1795 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1797 lprs->nSize = sizeof(RASTERIZER_STATUS);
1798 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1799 lprs->nLanguageID = 0;
1800 return TRUE;
1804 /*************************************************************************
1805 * GetKerningPairs (GDI.332)
1808 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1809 LPKERNINGPAIR16 lpKerningPairs )
1811 /* At this time kerning is ignored (set to 0) */
1812 int i;
1813 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1814 if (lpKerningPairs)
1815 for (i = 0; i < cPairs; i++)
1816 lpKerningPairs[i].iKernAmount = 0;
1817 /* FIXME: Should this function call SetLastError (0)? This is yet another
1818 * Microsoft function that can return 0 on success or failure
1820 return 0;
1825 /*************************************************************************
1826 * GetKerningPairsA (GDI32.@)
1828 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1829 LPKERNINGPAIR lpKerningPairs )
1831 int i;
1832 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1833 for (i = 0; i < cPairs; i++)
1834 lpKerningPairs[i].iKernAmount = 0;
1835 return 0;
1839 /*************************************************************************
1840 * GetKerningPairsW (GDI32.@)
1842 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1843 LPKERNINGPAIR lpKerningPairs )
1845 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1848 /*************************************************************************
1849 * TranslateCharsetInfo [GDI32.@]
1850 * TranslateCharsetInfo [USER32.@]
1852 * Fills a CHARSETINFO structure for a character set, code page, or
1853 * font. This allows making the correspondance between different labelings
1854 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1855 * of the same encoding.
1857 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1858 * only one codepage should be set in *lpSrc.
1860 * RETURNS
1861 * TRUE on success, FALSE on failure.
1864 BOOL WINAPI TranslateCharsetInfo(
1865 LPDWORD lpSrc, /* [in]
1866 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1867 if flags == TCI_SRCCHARSET: a character set value
1868 if flags == TCI_SRCCODEPAGE: a code page value
1870 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1871 DWORD flags /* [in] determines interpretation of lpSrc */
1873 int index = 0;
1874 switch (flags) {
1875 case TCI_SRCFONTSIG:
1876 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1877 break;
1878 case TCI_SRCCODEPAGE:
1879 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1880 break;
1881 case TCI_SRCCHARSET:
1882 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1883 break;
1884 default:
1885 return FALSE;
1887 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1888 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1889 return TRUE;
1892 /*************************************************************************
1893 * GetFontLanguageInfo (GDI32.@)
1895 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1896 /* return value 0 is correct for most cases anyway */
1897 FIXME("(%x):stub!\n", hdc);
1898 return 0;
1901 /*************************************************************************
1902 * GetFontLanguageInfo (GDI.616)
1904 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1905 /* return value 0 is correct for most cases anyway */
1906 FIXME("(%x):stub!\n",hdc);
1907 return 0;
1910 /*************************************************************************
1911 * GetFontData [GDI32.@] Retrieve data for TrueType font
1913 * RETURNS
1915 * success: Number of bytes returned
1916 * failure: GDI_ERROR
1918 * NOTES
1920 * Calls SetLastError()
1923 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1924 LPVOID buffer, DWORD length)
1926 DC *dc = DC_GetDCPtr(hdc);
1927 DWORD ret = GDI_ERROR;
1929 if(!dc) return GDI_ERROR;
1931 if(dc->gdiFont)
1932 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1934 GDI_ReleaseObj(hdc);
1935 return ret;
1938 /*************************************************************************
1939 * GetFontData [GDI.311]
1942 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1943 LPVOID lpvBuffer, DWORD cbData)
1945 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1948 /*************************************************************************
1949 * GetCharacterPlacementA [GDI32.@]
1951 * NOTES:
1952 * the web browser control of ie4 calls this with dwFlags=0
1954 DWORD WINAPI
1955 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1956 INT nMaxExtent, GCP_RESULTSA *lpResults,
1957 DWORD dwFlags)
1959 DWORD ret=0;
1960 SIZE size;
1962 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1963 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1965 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1966 "lpOutString=%p lpGlyphs=%p\n",
1967 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1968 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1970 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
1971 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
1972 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1973 if(lpResults->lpClass) FIXME("classes not implemented\n");
1974 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
1976 /* copy will do if the GCP_REORDER flag is not set */
1977 if(lpResults->lpOutString)
1979 lstrcpynA(lpResults->lpOutString, lpString, uCount);
1982 if (lpResults->lpDx)
1984 int i, c;
1985 for (i=0; i<uCount;i++)
1987 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1988 lpResults->lpDx[i]= c;
1992 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1993 ret = MAKELONG(size.cx, size.cy);
1995 return ret;
1998 /*************************************************************************
1999 * GetCharacterPlacementW [GDI32.@]
2001 DWORD WINAPI
2002 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2003 INT nMaxExtent, GCP_RESULTSW *lpResults,
2004 DWORD dwFlags)
2006 DWORD ret=0;
2007 SIZE size;
2009 TRACE("%s 0x%08x 0x%08x 0x%08lx:partial stub!\n",
2010 debugstr_w(lpString), uCount, nMaxExtent, dwFlags);
2012 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
2013 "lpOutString=%p lpGlyphs=%p\n",
2014 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
2015 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
2017 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2018 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
2019 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2020 if(lpResults->lpClass) FIXME("classes not implemented\n");
2021 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
2023 /* copy will do if the GCP_REORDER flag is not set */
2024 if(lpResults->lpOutString)
2026 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2029 if (lpResults->lpDx)
2031 int i, c;
2032 for (i=0; i<uCount;i++)
2034 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2035 lpResults->lpDx[i]= c;
2039 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2040 ret = MAKELONG(size.cx, size.cy);
2042 return ret;
2045 /*************************************************************************
2046 * GetCharABCWidthsFloatA [GDI32.@]
2048 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2049 LPABCFLOAT lpABCF)
2051 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2052 return 0;
2055 /*************************************************************************
2056 * GetCharABCWidthsFloatW [GDI32.@]
2058 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2059 UINT iLastChar, LPABCFLOAT lpABCF)
2061 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2062 return 0;
2065 /*************************************************************************
2066 * GetCharWidthFloatA [GDI32.@]
2068 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2069 UINT iLastChar, PFLOAT pxBuffer)
2071 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2072 return 0;
2075 /*************************************************************************
2076 * GetCharWidthFloatW [GDI32.@]
2078 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2079 UINT iLastChar, PFLOAT pxBuffer)
2081 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2082 return 0;
2086 /***********************************************************************
2088 * Font Resource API *
2090 ***********************************************************************/
2091 /***********************************************************************
2092 * AddFontResource (GDI.119)
2094 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2096 * FIXME: Load header and find the best-matching font in the fontList;
2097 * fixup dfPoints if all metrics are identical, otherwise create
2098 * new fontAlias. When soft font support is ready this will
2099 * simply create a new fontResource ('filename' will go into
2100 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2101 * flag set.
2103 INT16 WINAPI AddFontResource16( LPCSTR filename )
2105 return AddFontResourceA( filename );
2109 /***********************************************************************
2110 * AddFontResourceA (GDI32.@)
2112 INT WINAPI AddFontResourceA( LPCSTR str )
2114 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2115 "this font manually.\n", debugres_a(str));
2116 return 1;
2120 /***********************************************************************
2121 * AddFontResourceW (GDI32.@)
2123 INT WINAPI AddFontResourceW( LPCWSTR str )
2125 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2126 "this font manually.\n", debugres_w(str));
2127 return 1;
2130 /***********************************************************************
2131 * RemoveFontResource (GDI.136)
2133 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2135 FIXME("(%s): stub\n", debugres_a(str));
2136 return TRUE;
2140 /***********************************************************************
2141 * RemoveFontResourceA (GDI32.@)
2143 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2145 /* This is how it should look like */
2147 fontResource** ppfr;
2148 BOOL32 retVal = FALSE;
2150 EnterCriticalSection( &crtsc_fonts_X11 );
2151 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2152 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2154 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2155 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2157 if( (*ppfr)->fo_count )
2158 (*ppfr)->fr_flags |= FR_REMOVED;
2159 else
2160 XFONT_RemoveFontResource( ppfr );
2162 retVal = TRUE;
2164 LeaveCriticalSection( &crtsc_fonts_X11 );
2165 return retVal;
2167 FIXME("(%s): stub\n", debugres_a(str));
2168 return TRUE;
2172 /***********************************************************************
2173 * RemoveFontResourceW (GDI32.@)
2175 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2177 FIXME("(%s): stub\n", debugres_w(str) );
2178 return TRUE;