Use the font charset to obtain a codepage for A->W conversion in the
[wine/wine64.git] / objects / font.c
blob11747730dad00305546f910ce1d6ead4684e6bff
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 "font.h"
14 #include "heap.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 /***********************************************************************
91 * LOGFONT conversion functions.
93 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
95 font16->lfHeight = font32->lfHeight;
96 font16->lfWidth = font32->lfWidth;
97 font16->lfEscapement = font32->lfEscapement;
98 font16->lfOrientation = font32->lfOrientation;
99 font16->lfWeight = font32->lfWeight;
100 font16->lfItalic = font32->lfItalic;
101 font16->lfUnderline = font32->lfUnderline;
102 font16->lfStrikeOut = font32->lfStrikeOut;
103 font16->lfCharSet = font32->lfCharSet;
104 font16->lfOutPrecision = font32->lfOutPrecision;
105 font16->lfClipPrecision = font32->lfClipPrecision;
106 font16->lfQuality = font32->lfQuality;
107 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
108 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
111 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
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 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
127 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
128 font16->lfFaceName[LF_FACESIZE-1] = 0;
131 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
133 font32->lfHeight = font16->lfHeight;
134 font32->lfWidth = font16->lfWidth;
135 font32->lfEscapement = font16->lfEscapement;
136 font32->lfOrientation = font16->lfOrientation;
137 font32->lfWeight = font16->lfWeight;
138 font32->lfItalic = font16->lfItalic;
139 font32->lfUnderline = font16->lfUnderline;
140 font32->lfStrikeOut = font16->lfStrikeOut;
141 font32->lfCharSet = font16->lfCharSet;
142 font32->lfOutPrecision = font16->lfOutPrecision;
143 font32->lfClipPrecision = font16->lfClipPrecision;
144 font32->lfQuality = font16->lfQuality;
145 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
146 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
149 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
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 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
165 font32->lfFaceName[LF_FACESIZE-1] = 0;
168 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
170 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
171 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
172 LF_FACESIZE);
175 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
177 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
178 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
179 LF_FACESIZE, NULL, NULL);
182 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
184 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
185 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
186 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
187 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
190 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
192 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
194 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
195 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
196 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
197 font32->elfStyle[LF_FACESIZE-1] = 0;
198 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
199 font32->elfScript[LF_FACESIZE-1] = 0;
202 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
204 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
206 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
207 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
208 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
209 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
210 font16->elfStyle, LF_FACESIZE, NULL, NULL );
211 font16->elfStyle[LF_FACESIZE-1] = '\0';
212 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
213 font16->elfScript, LF_FACESIZE, NULL, NULL );
214 font16->elfScript[LF_FACESIZE-1] = '\0';
217 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
219 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
221 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
222 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
223 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
224 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
225 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
226 fontA->elfStyle[LF_FACESIZE-1] = '\0';
227 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
228 fontA->elfScript, LF_FACESIZE, NULL, NULL );
229 fontA->elfScript[LF_FACESIZE-1] = '\0';
232 /***********************************************************************
233 * TEXTMETRIC conversion functions.
235 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
237 ptm16->tmHeight = ptm32->tmHeight;
238 ptm16->tmAscent = ptm32->tmAscent;
239 ptm16->tmDescent = ptm32->tmDescent;
240 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
241 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
242 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
243 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
244 ptm16->tmWeight = ptm32->tmWeight;
245 ptm16->tmOverhang = ptm32->tmOverhang;
246 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
247 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
248 ptm16->tmFirstChar = ptm32->tmFirstChar;
249 ptm16->tmLastChar = ptm32->tmLastChar;
250 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
251 ptm16->tmBreakChar = ptm32->tmBreakChar;
252 ptm16->tmItalic = ptm32->tmItalic;
253 ptm16->tmUnderlined = ptm32->tmUnderlined;
254 ptm16->tmStruckOut = ptm32->tmStruckOut;
255 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
256 ptm16->tmCharSet = ptm32->tmCharSet;
259 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
261 ptm16->tmHeight = ptm32->tmHeight;
262 ptm16->tmAscent = ptm32->tmAscent;
263 ptm16->tmDescent = ptm32->tmDescent;
264 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
265 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
266 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
267 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
268 ptm16->tmWeight = ptm32->tmWeight;
269 ptm16->tmOverhang = ptm32->tmOverhang;
270 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
271 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
272 ptm16->tmFirstChar = ptm32->tmFirstChar;
273 ptm16->tmLastChar = ptm32->tmLastChar;
274 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
275 ptm16->tmBreakChar = ptm32->tmBreakChar;
276 ptm16->tmItalic = ptm32->tmItalic;
277 ptm16->tmUnderlined = ptm32->tmUnderlined;
278 ptm16->tmStruckOut = ptm32->tmStruckOut;
279 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
280 ptm16->tmCharSet = ptm32->tmCharSet;
283 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
285 ptm32->tmHeight = ptm16->tmHeight;
286 ptm32->tmAscent = ptm16->tmAscent;
287 ptm32->tmDescent = ptm16->tmDescent;
288 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
289 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
290 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
291 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
292 ptm32->tmWeight = ptm16->tmWeight;
293 ptm32->tmOverhang = ptm16->tmOverhang;
294 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
295 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
296 ptm32->tmFirstChar = ptm16->tmFirstChar;
297 ptm32->tmLastChar = ptm16->tmLastChar;
298 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
299 ptm32->tmBreakChar = ptm16->tmBreakChar;
300 ptm32->tmItalic = ptm16->tmItalic;
301 ptm32->tmUnderlined = ptm16->tmUnderlined;
302 ptm32->tmStruckOut = ptm16->tmStruckOut;
303 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
304 ptm32->tmCharSet = ptm16->tmCharSet;
307 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
309 ptm32->tmHeight = ptm16->tmHeight;
310 ptm32->tmAscent = ptm16->tmAscent;
311 ptm32->tmDescent = ptm16->tmDescent;
312 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
313 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
314 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
315 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
316 ptm32->tmWeight = ptm16->tmWeight;
317 ptm32->tmOverhang = ptm16->tmOverhang;
318 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
319 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
320 ptm32->tmFirstChar = ptm16->tmFirstChar;
321 ptm32->tmLastChar = ptm16->tmLastChar;
322 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
323 ptm32->tmBreakChar = ptm16->tmBreakChar;
324 ptm32->tmItalic = ptm16->tmItalic;
325 ptm32->tmUnderlined = ptm16->tmUnderlined;
326 ptm32->tmStruckOut = ptm16->tmStruckOut;
327 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
328 ptm32->tmCharSet = ptm16->tmCharSet;
331 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
333 ptm32W->tmHeight = ptm32A->tmHeight;
334 ptm32W->tmAscent = ptm32A->tmAscent;
335 ptm32W->tmDescent = ptm32A->tmDescent;
336 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
337 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
338 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
339 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
340 ptm32W->tmWeight = ptm32A->tmWeight;
341 ptm32W->tmOverhang = ptm32A->tmOverhang;
342 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
343 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
344 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
345 ptm32W->tmLastChar = ptm32A->tmLastChar;
346 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
347 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
348 ptm32W->tmItalic = ptm32A->tmItalic;
349 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
350 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
351 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
352 ptm32W->tmCharSet = ptm32A->tmCharSet;
355 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
357 ptmA->tmHeight = ptmW->tmHeight;
358 ptmA->tmAscent = ptmW->tmAscent;
359 ptmA->tmDescent = ptmW->tmDescent;
360 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
361 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
362 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
363 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
364 ptmA->tmWeight = ptmW->tmWeight;
365 ptmA->tmOverhang = ptmW->tmOverhang;
366 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
367 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
368 ptmA->tmFirstChar = ptmW->tmFirstChar;
369 ptmA->tmLastChar = ptmW->tmLastChar;
370 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
371 ptmA->tmBreakChar = ptmW->tmBreakChar;
372 ptmA->tmItalic = ptmW->tmItalic;
373 ptmA->tmUnderlined = ptmW->tmUnderlined;
374 ptmA->tmStruckOut = ptmW->tmStruckOut;
375 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
376 ptmA->tmCharSet = ptmW->tmCharSet;
380 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
382 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
383 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
384 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
385 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
386 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
387 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
390 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
392 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
393 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
394 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
395 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
396 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
397 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
400 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
402 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
403 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
404 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
405 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
406 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
407 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
411 /***********************************************************************
412 * CreateFontIndirect (GDI.57)
414 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
416 LOGFONTW lfW;
418 if(plf16) {
419 FONT_LogFont16ToW( plf16, &lfW );
420 return CreateFontIndirectW( &lfW );
421 } else {
422 return CreateFontIndirectW( NULL );
427 /***********************************************************************
428 * CreateFontIndirectA (GDI32.@)
430 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
432 LOGFONTW lfW;
434 if (plfA) {
435 FONT_LogFontAToW( plfA, &lfW );
436 return CreateFontIndirectW( &lfW );
437 } else
438 return CreateFontIndirectW( NULL );
442 /***********************************************************************
443 * CreateFontIndirectW (GDI32.@)
445 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
447 HFONT hFont = 0;
449 if (plf)
451 FONTOBJ* fontPtr;
452 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
454 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
456 TRACE("(%ld %ld %ld %ld) %s %s %s => %04x\n",
457 plf->lfHeight, plf->lfWidth,
458 plf->lfEscapement, plf->lfOrientation,
459 debugstr_w(plf->lfFaceName),
460 plf->lfWeight > 400 ? "Bold" : "",
461 plf->lfItalic ? "Italic" : "", hFont);
463 if (plf->lfEscapement != plf->lfOrientation) {
464 /* this should really depend on whether GM_ADVANCED is set */
465 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
466 WARN("orientation angle %f set to "
467 "escapement angle %f for new font %04x\n",
468 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
470 GDI_ReleaseObj( hFont );
473 else WARN("(NULL) => NULL\n");
475 return hFont;
478 /***********************************************************************
479 * CreateFont (GDI.56)
481 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
482 INT16 weight, BYTE italic, BYTE underline,
483 BYTE strikeout, BYTE charset, BYTE outpres,
484 BYTE clippres, BYTE quality, BYTE pitch,
485 LPCSTR name )
487 LOGFONT16 logfont;
489 logfont.lfHeight = height;
490 logfont.lfWidth = width;
491 logfont.lfEscapement = esc;
492 logfont.lfOrientation = orient;
493 logfont.lfWeight = weight;
494 logfont.lfItalic = italic;
495 logfont.lfUnderline = underline;
496 logfont.lfStrikeOut = strikeout;
497 logfont.lfCharSet = charset;
498 logfont.lfOutPrecision = outpres;
499 logfont.lfClipPrecision = clippres;
500 logfont.lfQuality = quality;
501 logfont.lfPitchAndFamily = pitch;
503 if (name)
504 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
505 else
506 logfont.lfFaceName[0] = '\0';
508 return CreateFontIndirect16( &logfont );
511 /*************************************************************************
512 * CreateFontA (GDI32.@)
514 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
515 INT orient, INT weight, DWORD italic,
516 DWORD underline, DWORD strikeout, DWORD charset,
517 DWORD outpres, DWORD clippres, DWORD quality,
518 DWORD pitch, LPCSTR name )
520 LOGFONTA logfont;
522 logfont.lfHeight = height;
523 logfont.lfWidth = width;
524 logfont.lfEscapement = esc;
525 logfont.lfOrientation = orient;
526 logfont.lfWeight = weight;
527 logfont.lfItalic = italic;
528 logfont.lfUnderline = underline;
529 logfont.lfStrikeOut = strikeout;
530 logfont.lfCharSet = charset;
531 logfont.lfOutPrecision = outpres;
532 logfont.lfClipPrecision = clippres;
533 logfont.lfQuality = quality;
534 logfont.lfPitchAndFamily = pitch;
536 if (name)
537 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
538 else
539 logfont.lfFaceName[0] = '\0';
541 return CreateFontIndirectA( &logfont );
544 /*************************************************************************
545 * CreateFontW (GDI32.@)
547 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
548 INT orient, INT weight, DWORD italic,
549 DWORD underline, DWORD strikeout, DWORD charset,
550 DWORD outpres, DWORD clippres, DWORD quality,
551 DWORD pitch, LPCWSTR name )
553 LOGFONTW logfont;
555 logfont.lfHeight = height;
556 logfont.lfWidth = width;
557 logfont.lfEscapement = esc;
558 logfont.lfOrientation = orient;
559 logfont.lfWeight = weight;
560 logfont.lfItalic = italic;
561 logfont.lfUnderline = underline;
562 logfont.lfStrikeOut = strikeout;
563 logfont.lfCharSet = charset;
564 logfont.lfOutPrecision = outpres;
565 logfont.lfClipPrecision = clippres;
566 logfont.lfQuality = quality;
567 logfont.lfPitchAndFamily = pitch;
569 if (name)
570 lstrcpynW(logfont.lfFaceName, name,
571 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
572 else
573 logfont.lfFaceName[0] = '\0';
575 return CreateFontIndirectW( &logfont );
579 /***********************************************************************
580 * FONT_GetObject16
582 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
584 LOGFONT16 lf16;
586 FONT_LogFontWTo16( &font->logfont, &lf16 );
588 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
589 memcpy( buffer, &lf16, count );
590 return count;
593 /***********************************************************************
594 * FONT_GetObjectA
596 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
598 LOGFONTA lfA;
600 FONT_LogFontWToA( &font->logfont, &lfA );
602 if (count > sizeof(lfA)) count = sizeof(lfA);
603 memcpy( buffer, &lfA, count );
604 return count;
606 /***********************************************************************
607 * FONT_GetObjectW
609 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
611 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
612 memcpy( buffer, &font->logfont, count );
613 return count;
617 /***********************************************************************
618 * FONT_EnumInstance16
620 * Called by the device driver layer to pass font info
621 * down to the application.
623 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
624 DWORD fType, LPARAM lp )
626 #define pfe ((fontEnum16*)lp)
627 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
628 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
630 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
631 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
632 return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric,
633 (UINT16)fType, (LPARAM)(pfe->lpData) );
635 #undef pfe
636 return 1;
639 /***********************************************************************
640 * FONT_EnumInstance
642 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
643 DWORD fType, LPARAM lp )
645 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
647 #define pfe ((fontEnum32*)lp)
648 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
649 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
651 /* convert font metrics */
653 if( pfe->dwFlags & ENUM_UNICODE )
655 return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
657 else
659 ENUMLOGFONTEXA logfont;
660 NEWTEXTMETRICEXA tmA;
662 FONT_EnumLogFontExWToA( plf, &logfont);
663 FONT_NewTextMetricExWToA( ptm, &tmA );
665 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
666 (LPNEWTEXTMETRICEXW)&tmA, fType,
667 pfe->lpData );
670 #undef pfe
671 return 1;
674 /***********************************************************************
675 * EnumFontFamiliesEx16 (GDI.613)
677 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
678 FONTENUMPROCEX16 efproc, LPARAM lParam,
679 DWORD dwFlags)
681 BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
682 INT16 retVal = 0;
683 DC* dc = DC_GetDCPtr( hDC );
685 if (!dc) return 0;
686 enum_func = dc->funcs->pEnumDeviceFonts;
687 GDI_ReleaseObj( hDC );
689 if (enum_func)
691 LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
692 if( lptm16 )
694 LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
695 if( lplf16 )
697 fontEnum16 fe16;
698 LOGFONTW lfW;
699 FONT_LogFont16ToW(plf, &lfW);
701 fe16.lpLogFontParam = plf;
702 fe16.lpEnumFunc = efproc;
703 fe16.lpData = lParam;
705 fe16.lpTextMetric = lptm16;
706 fe16.lpLogFont = lplf16;
707 fe16.segTextMetric = SEGPTR_GET(lptm16);
708 fe16.segLogFont = SEGPTR_GET(lplf16);
710 retVal = enum_func( hDC, &lfW, FONT_EnumInstance16,
711 (LPARAM)&fe16 );
712 SEGPTR_FREE(lplf16);
714 SEGPTR_FREE(lptm16);
717 return retVal;
720 /***********************************************************************
721 * FONT_EnumFontFamiliesEx
723 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
724 FONTENUMPROCEXW efproc,
725 LPARAM lParam, DWORD dwUnicode)
727 BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
728 INT ret = 1;
729 DC *dc = DC_GetDCPtr( hDC );
730 fontEnum32 fe32;
731 BOOL enum_gdi_fonts;
733 if (!dc) return 0;
735 fe32.lpLogFontParam = plf;
736 fe32.lpEnumFunc = efproc;
737 fe32.lpData = lParam;
738 fe32.dwFlags = dwUnicode;
740 enum_func = dc->funcs->pEnumDeviceFonts;
741 GDI_ReleaseObj( hDC );
742 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
744 if (!enum_func && !enum_gdi_fonts) return 0;
746 if (enum_gdi_fonts)
747 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
748 if (ret && enum_func)
749 ret = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
750 return ret;
753 /***********************************************************************
754 * EnumFontFamiliesExW (GDI32.@)
756 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
757 FONTENUMPROCEXW efproc,
758 LPARAM lParam, DWORD dwFlags )
760 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
763 /***********************************************************************
764 * EnumFontFamiliesExA (GDI32.@)
766 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
767 FONTENUMPROCEXA efproc,
768 LPARAM lParam, DWORD dwFlags)
770 LOGFONTW lfW;
771 FONT_LogFontAToW( plf, &lfW );
773 return FONT_EnumFontFamiliesEx( hDC, &lfW,
774 (FONTENUMPROCEXW)efproc, lParam, 0);
777 /***********************************************************************
778 * EnumFontFamilies16 (GDI.330)
780 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
781 FONTENUMPROC16 efproc, LPARAM lpData )
783 LOGFONT16 lf;
785 lf.lfCharSet = DEFAULT_CHARSET;
786 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
787 else lf.lfFaceName[0] = '\0';
789 return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
792 /***********************************************************************
793 * EnumFontFamiliesA (GDI32.@)
795 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
796 FONTENUMPROCA efproc, LPARAM lpData )
798 LOGFONTA lf;
800 lf.lfCharSet = DEFAULT_CHARSET;
801 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
802 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
804 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
807 /***********************************************************************
808 * EnumFontFamiliesW (GDI32.@)
810 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
811 FONTENUMPROCW efproc, LPARAM lpData )
813 LOGFONTW lf;
815 lf.lfCharSet = DEFAULT_CHARSET;
816 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
817 else lf.lfFaceName[0] = 0;
819 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
822 /***********************************************************************
823 * EnumFonts16 (GDI.70)
825 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
826 LPARAM lpData )
828 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
831 /***********************************************************************
832 * EnumFontsA (GDI32.@)
834 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
835 LPARAM lpData )
837 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
840 /***********************************************************************
841 * EnumFontsW (GDI32.@)
843 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
844 LPARAM lpData )
846 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
850 /***********************************************************************
851 * GetTextCharacterExtra (GDI.89)
853 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
855 return (INT16)GetTextCharacterExtra( hdc );
859 /***********************************************************************
860 * GetTextCharacterExtra (GDI32.@)
862 INT WINAPI GetTextCharacterExtra( HDC hdc )
864 INT ret;
865 DC *dc = DC_GetDCPtr( hdc );
866 if (!dc) return 0;
867 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
868 / dc->vportExtX );
869 GDI_ReleaseObj( hdc );
870 return ret;
874 /***********************************************************************
875 * SetTextCharacterExtra (GDI.8)
877 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
879 return (INT16)SetTextCharacterExtra( hdc, extra );
883 /***********************************************************************
884 * SetTextCharacterExtra (GDI32.@)
886 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
888 INT prev;
889 DC * dc = DC_GetDCPtr( hdc );
890 if (!dc) return 0;
891 if (dc->funcs->pSetTextCharacterExtra)
892 prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
893 else
895 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
896 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
897 dc->charExtra = abs(extra);
899 GDI_ReleaseObj( hdc );
900 return prev;
904 /***********************************************************************
905 * SetTextJustification (GDI.10)
907 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
909 return SetTextJustification( hdc, extra, breaks );
913 /***********************************************************************
914 * SetTextJustification (GDI32.@)
916 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
918 BOOL ret = TRUE;
919 DC * dc = DC_GetDCPtr( hdc );
920 if (!dc) return FALSE;
921 if (dc->funcs->pSetTextJustification)
922 ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
923 else
925 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
926 if (!extra) breaks = 0;
927 dc->breakTotalExtra = extra;
928 dc->breakCount = breaks;
929 if (breaks)
931 dc->breakExtra = extra / breaks;
932 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
934 else
936 dc->breakExtra = 0;
937 dc->breakRem = 0;
940 GDI_ReleaseObj( hdc );
941 return ret;
945 /***********************************************************************
946 * GetTextFace (GDI.92)
948 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
950 return GetTextFaceA(hdc,count,name);
953 /***********************************************************************
954 * GetTextFaceA (GDI32.@)
956 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
958 INT res = GetTextFaceW(hdc, 0, NULL);
959 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
960 GetTextFaceW( hdc, res, nameW );
962 if (name)
963 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
964 NULL, NULL);
965 else
966 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
967 HeapFree( GetProcessHeap(), 0, nameW );
968 return res;
971 /***********************************************************************
972 * GetTextFaceW (GDI32.@)
974 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
976 FONTOBJ *font;
977 INT ret = 0;
979 DC * dc = DC_GetDCPtr( hdc );
980 if (!dc) return 0;
982 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
984 if (name)
986 lstrcpynW( name, font->logfont.lfFaceName, count );
987 ret = strlenW(name);
989 else ret = strlenW(font->logfont.lfFaceName) + 1;
990 GDI_ReleaseObj( dc->hFont );
992 GDI_ReleaseObj( hdc );
993 return ret;
997 /***********************************************************************
998 * GetTextExtent (GDI.91)
1000 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1002 SIZE16 size;
1003 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1004 return MAKELONG( size.cx, size.cy );
1008 /***********************************************************************
1009 * GetTextExtentPoint (GDI.471)
1011 * FIXME: Should this have a bug for compatibility?
1012 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1013 * bugs (-> MSDN KB q147647.txt).
1015 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1016 LPSIZE16 size )
1018 SIZE size32;
1019 BOOL ret;
1020 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1021 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1022 size->cx = size32.cx;
1023 size->cy = size32.cy;
1024 return (BOOL16)ret;
1028 /***********************************************************************
1029 * GetTextExtentPoint32A (GDI32.@)
1031 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1032 LPSIZE size )
1034 BOOL ret = FALSE;
1035 INT wlen;
1036 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1038 if (p) {
1039 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1040 HeapFree( GetProcessHeap(), 0, p );
1043 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1044 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1045 return ret;
1049 /***********************************************************************
1050 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1052 * Computes width and height of the specified string.
1054 * RETURNS
1055 * Success: TRUE
1056 * Failure: FALSE
1058 BOOL WINAPI GetTextExtentPoint32W(
1059 HDC hdc, /* [in] Handle of device context */
1060 LPCWSTR str, /* [in] Address of text string */
1061 INT count, /* [in] Number of characters in string */
1062 LPSIZE size) /* [out] Address of structure for string size */
1064 BOOL ret = FALSE;
1065 DC * dc = DC_GetDCPtr( hdc );
1066 if (!dc) return FALSE;
1068 if(dc->gdiFont)
1069 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1070 else if(dc->funcs->pGetTextExtentPoint)
1071 ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
1073 GDI_ReleaseObj( hdc );
1075 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1076 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1077 return ret;
1081 /***********************************************************************
1082 * GetTextExtentPointA (GDI32.@)
1084 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1085 LPSIZE size )
1087 TRACE("not bug compatible.\n");
1088 return GetTextExtentPoint32A( hdc, str, count, size );
1091 /***********************************************************************
1092 * GetTextExtentPointW (GDI32.@)
1094 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1095 LPSIZE size )
1097 TRACE("not bug compatible.\n");
1098 return GetTextExtentPoint32W( hdc, str, count, size );
1102 /***********************************************************************
1103 * GetTextExtentExPointA (GDI32.@)
1105 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1106 INT maxExt, LPINT lpnFit,
1107 LPINT alpDx, LPSIZE size )
1109 BOOL ret;
1110 INT wlen;
1111 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1112 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1113 HeapFree( GetProcessHeap(), 0, p );
1114 return ret;
1118 /***********************************************************************
1119 * GetTextExtentExPointW (GDI32.@)
1121 * Return the size of the string as it would be if it was output properly by
1122 * e.g. TextOut.
1124 * This should include
1125 * - Intercharacter spacing
1126 * - justification spacing (not yet done)
1127 * - kerning? see below
1129 * Kerning. Since kerning would be carried out by the rendering code it should
1130 * be done by the driver. However they don't support it yet. Also I am not
1131 * yet persuaded that (certainly under Win95) any kerning is actually done.
1133 * str: According to MSDN this should be null-terminated. That is not true; a
1134 * null will not terminate it early.
1135 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1136 * than count. I have seen it be either the size of the full string or
1137 * 1 less than the size of the full string. I have not seen it bear any
1138 * resemblance to the portion that would fit.
1139 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1140 * trailing intercharacter spacing and any trailing justification.
1142 * FIXME
1143 * Currently we do this by measuring each character etc. We should do it by
1144 * passing the request to the driver, perhaps by extending the
1145 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1146 * thinking about kerning issues and rounding issues in the justification.
1149 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1150 INT maxExt, LPINT lpnFit,
1151 LPINT alpDx, LPSIZE size )
1153 int index, nFit, extent;
1154 SIZE tSize;
1155 BOOL ret = FALSE;
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("(%08x %s %d) returning %d %ld x %ld\n",
1180 hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1182 done:
1183 return ret;
1186 /***********************************************************************
1187 * GetTextMetrics (GDI.93)
1189 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1191 TEXTMETRICW tm32;
1193 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1194 FONT_TextMetricWTo16( &tm32, metrics );
1195 return TRUE;
1199 /***********************************************************************
1200 * GetTextMetricsA (GDI32.@)
1202 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1204 TEXTMETRICW tm32;
1206 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1207 FONT_TextMetricWToA( &tm32, metrics );
1208 return TRUE;
1211 /***********************************************************************
1212 * GetTextMetricsW (GDI32.@)
1214 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1216 BOOL ret = FALSE;
1217 DC * dc = DC_GetDCPtr( hdc );
1218 if (!dc) return FALSE;
1220 if (dc->gdiFont)
1221 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1222 else if (dc->funcs->pGetTextMetrics)
1223 ret = dc->funcs->pGetTextMetrics( dc, metrics );
1225 if (ret)
1227 /* device layer returns values in device units
1228 * therefore we have to convert them to logical */
1230 #define WDPTOLP(x) ((x<0)? \
1231 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1232 (abs((x)*dc->wndExtX/dc->vportExtX)))
1233 #define HDPTOLP(y) ((y<0)? \
1234 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1235 (abs((y)*dc->wndExtY/dc->vportExtY)))
1237 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1238 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1239 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1240 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1241 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1242 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1243 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1244 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1245 ret = TRUE;
1247 TRACE("text metrics:\n"
1248 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1249 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1250 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1251 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1252 " PitchAndFamily = %02x\n"
1253 " --------------------\n"
1254 " InternalLeading = %li\n"
1255 " Ascent = %li\n"
1256 " Descent = %li\n"
1257 " Height = %li\n",
1258 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1259 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1260 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1261 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1262 metrics->tmPitchAndFamily,
1263 metrics->tmInternalLeading,
1264 metrics->tmAscent,
1265 metrics->tmDescent,
1266 metrics->tmHeight );
1268 GDI_ReleaseObj( hdc );
1269 return ret;
1273 /***********************************************************************
1274 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1276 * NOTES
1277 * lpOTM should be LPOUTLINETEXTMETRIC
1279 * RETURNS
1280 * Success: Non-zero or size of required buffer
1281 * Failure: 0
1283 UINT16 WINAPI GetOutlineTextMetrics16(
1284 HDC16 hdc, /* [in] Handle of device context */
1285 UINT16 cbData, /* [in] Size of metric data array */
1286 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1288 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1289 return 0;
1293 /***********************************************************************
1294 * GetOutlineTextMetricsA (GDI32.@)
1295 * Gets metrics for TrueType fonts.
1298 * RETURNS
1299 * Success: Non-zero or size of required buffer
1300 * Failure: 0
1302 UINT WINAPI GetOutlineTextMetricsA(
1303 HDC hdc, /* [in] Handle of device context */
1304 UINT cbData, /* [in] Size of metric data array */
1305 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1307 char buf[512], *ptr;
1308 UINT ret, needed;
1309 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1310 INT left, len;
1312 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1313 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1314 return 0;
1315 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1316 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1319 needed = sizeof(OUTLINETEXTMETRICA);
1320 if(lpOTMW->otmpFamilyName)
1321 needed += WideCharToMultiByte(CP_ACP, 0,
1322 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1323 NULL, 0, NULL, NULL);
1324 if(lpOTMW->otmpFaceName)
1325 needed += WideCharToMultiByte(CP_ACP, 0,
1326 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1327 NULL, 0, NULL, NULL);
1328 if(lpOTMW->otmpStyleName)
1329 needed += WideCharToMultiByte(CP_ACP, 0,
1330 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1331 NULL, 0, NULL, NULL);
1332 if(lpOTMW->otmpFullName)
1333 needed += WideCharToMultiByte(CP_ACP, 0,
1334 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1335 NULL, 0, NULL, NULL);
1337 if(!lpOTM) {
1338 ret = needed;
1339 goto end;
1342 if(needed > cbData) {
1343 ret = 0;
1344 goto end;
1348 lpOTM->otmSize = needed;
1349 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1350 lpOTM->otmFiller = 0;
1351 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1352 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1353 lpOTM->otmfsType = lpOTMW->otmfsType;
1354 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1355 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1356 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1357 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1358 lpOTM->otmAscent = lpOTMW->otmAscent;
1359 lpOTM->otmDescent = lpOTMW->otmDescent;
1360 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1361 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1362 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1363 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1364 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1365 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1366 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1367 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1368 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1369 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1370 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1371 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1372 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1373 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1374 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1375 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1378 ptr = (char*)(lpOTM + 1);
1379 left = needed - sizeof(*lpOTM);
1381 if(lpOTMW->otmpFamilyName) {
1382 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1383 len = WideCharToMultiByte(CP_ACP, 0,
1384 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1385 ptr, left, NULL, NULL);
1386 left -= len;
1387 ptr += len;
1388 } else
1389 lpOTM->otmpFamilyName = 0;
1391 if(lpOTMW->otmpFaceName) {
1392 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1393 len = WideCharToMultiByte(CP_ACP, 0,
1394 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1395 ptr, left, NULL, NULL);
1396 left -= len;
1397 ptr += len;
1398 } else
1399 lpOTM->otmpFaceName = 0;
1401 if(lpOTMW->otmpStyleName) {
1402 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1403 len = WideCharToMultiByte(CP_ACP, 0,
1404 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1405 ptr, left, NULL, NULL);
1406 left -= len;
1407 ptr += len;
1408 } else
1409 lpOTM->otmpStyleName = 0;
1411 if(lpOTMW->otmpFullName) {
1412 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1413 len = WideCharToMultiByte(CP_ACP, 0,
1414 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1415 ptr, left, NULL, NULL);
1416 left -= len;
1417 } else
1418 lpOTM->otmpFullName = 0;
1420 assert(left == 0);
1422 ret = needed;
1424 end:
1425 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1426 HeapFree(GetProcessHeap(), 0, lpOTMW);
1428 return ret;
1432 /***********************************************************************
1433 * GetOutlineTextMetricsW [GDI32.@]
1435 UINT WINAPI GetOutlineTextMetricsW(
1436 HDC hdc, /* [in] Handle of device context */
1437 UINT cbData, /* [in] Size of metric data array */
1438 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1440 DC *dc = DC_GetDCPtr( hdc );
1441 UINT ret;
1443 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1444 if(!dc) return 0;
1446 if(dc->gdiFont)
1447 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1449 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1450 but really this should just be a return 0. */
1452 ret = sizeof(*lpOTM);
1453 if (lpOTM) {
1454 if(cbData < ret)
1455 ret = 0;
1456 else {
1457 memset(lpOTM, 0, ret);
1458 lpOTM->otmSize = sizeof(*lpOTM);
1459 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1461 Further fill of the structure not implemented,
1462 Needs real values for the structure members
1467 GDI_ReleaseObj(hdc);
1468 return ret;
1472 /***********************************************************************
1473 * GetCharWidth (GDI.350)
1475 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1476 LPINT16 buffer )
1478 BOOL retVal = FALSE;
1480 if( firstChar != lastChar )
1482 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1483 sizeof(INT)*(1 + (lastChar - firstChar)));
1484 if( buf32 )
1486 LPINT obuf32 = buf32;
1487 int i;
1489 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1490 if (retVal)
1492 for (i = firstChar; i <= lastChar; i++)
1493 *buffer++ = *buf32++;
1495 HeapFree(GetProcessHeap(), 0, obuf32);
1498 else /* happens quite often to warrant a special treatment */
1500 INT chWidth;
1501 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1502 *buffer = chWidth;
1504 return retVal;
1508 /***********************************************************************
1509 * GetCharWidthA (GDI32.@)
1510 * GetCharWidth32A (GDI32.@)
1512 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1513 LPINT buffer )
1515 UINT i, extra;
1516 BOOL ret = FALSE;
1517 DC * dc = DC_GetDCPtr( hdc );
1518 if (!dc) return FALSE;
1520 if (dc->gdiFont)
1521 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1522 else if (dc->funcs->pGetCharWidth)
1523 ret = dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer);
1525 if (ret)
1527 /* convert device units to logical */
1529 extra = dc->vportExtX >> 1;
1530 for( i = firstChar; i <= lastChar; i++, buffer++ )
1531 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1532 ret = TRUE;
1534 GDI_ReleaseObj( hdc );
1535 return ret;
1539 /***********************************************************************
1540 * GetCharWidthW (GDI32.@)
1541 * GetCharWidth32W (GDI32.@)
1543 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1544 LPINT buffer )
1546 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1550 /* FIXME: all following APIs ******************************************/
1553 /***********************************************************************
1554 * SetMapperFlags (GDI.349)
1556 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1558 return SetMapperFlags( hDC, dwFlag );
1562 /***********************************************************************
1563 * SetMapperFlags (GDI32.@)
1565 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1567 DC *dc = DC_GetDCPtr( hDC );
1568 DWORD ret = 0;
1569 if(!dc) return 0;
1570 if(dc->funcs->pSetMapperFlags)
1571 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1572 else
1573 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1574 GDI_ReleaseObj( hDC );
1575 return ret;
1578 /***********************************************************************
1579 * GetAspectRatioFilterEx (GDI.486)
1581 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1583 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1584 return FALSE;
1587 /***********************************************************************
1588 * GetAspectRatioFilterEx (GDI32.@)
1590 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1592 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1593 return FALSE;
1596 /***********************************************************************
1597 * GetCharABCWidths (GDI.307)
1599 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1600 LPABC16 abc )
1602 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1603 int i;
1605 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1606 HeapFree(GetProcessHeap(),0,abc32);
1607 return FALSE;
1610 for (i=firstChar;i<=lastChar;i++) {
1611 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1612 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1613 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1615 HeapFree(GetProcessHeap(),0,abc32);
1616 return TRUE;
1620 /***********************************************************************
1621 * GetCharABCWidthsA (GDI32.@)
1623 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1624 LPABC abc )
1626 return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1630 /******************************************************************************
1631 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1633 * PARAMS
1634 * hdc [I] Handle of device context
1635 * firstChar [I] First character in range to query
1636 * lastChar [I] Last character in range to query
1637 * abc [O] Address of character-width structure
1639 * NOTES
1640 * Only works with TrueType fonts
1642 * RETURNS
1643 * Success: TRUE
1644 * Failure: FALSE
1646 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1647 LPABC abc )
1649 int i;
1650 LPINT widths = HeapAlloc(GetProcessHeap(),0,(lastChar-firstChar+1)*sizeof(INT));
1652 FIXME("(%04x,%04x,%04x,%p), returns slightly bogus values.\n", hdc, firstChar, lastChar, abc);
1654 GetCharWidth32A(hdc,firstChar,lastChar,widths);
1656 for (i=firstChar;i<=lastChar;i++) {
1657 abc[i-firstChar].abcA = 0; /* left distance */
1658 abc[i-firstChar].abcB = widths[i-firstChar];/* width */
1659 abc[i-firstChar].abcC = 0; /* right distance */
1661 HeapFree(GetProcessHeap(),0,widths);
1662 return TRUE;
1666 /***********************************************************************
1667 * GetGlyphOutline (GDI.309)
1669 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1670 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1671 LPVOID lpBuffer, const MAT2 *lpmat2 )
1673 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1674 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1675 return (DWORD)-1; /* failure */
1679 /***********************************************************************
1680 * GetGlyphOutlineA (GDI32.@)
1682 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1683 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1684 LPVOID lpBuffer, const MAT2 *lpmat2 )
1686 return GetGlyphOutlineW(hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer,
1687 lpmat2);
1690 /***********************************************************************
1691 * GetGlyphOutlineW (GDI32.@)
1693 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1694 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1695 LPVOID lpBuffer, const MAT2 *lpmat2 )
1697 DC *dc = DC_GetDCPtr(hdc);
1698 DWORD ret;
1700 TRACE("(%04x, '%c', %04x, %p, %ld, %p, %p)\n",
1701 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1703 if(!dc) return GDI_ERROR;
1705 if(dc->gdiFont)
1706 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1707 cbBuffer, lpBuffer, lpmat2);
1708 else
1709 ret = GDI_ERROR;
1711 GDI_ReleaseObj(hdc);
1712 return ret;
1715 /***********************************************************************
1716 * CreateScalableFontResource (GDI.310)
1718 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1719 LPCSTR lpszResourceFile,
1720 LPCSTR fontFile, LPCSTR path )
1722 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1723 fontFile, path );
1726 /***********************************************************************
1727 * CreateScalableFontResourceA (GDI32.@)
1729 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1730 LPCSTR lpszResourceFile,
1731 LPCSTR lpszFontFile,
1732 LPCSTR lpszCurrentPath )
1734 /* fHidden=1 - only visible for the calling app, read-only, not
1735 * enumbered with EnumFonts/EnumFontFamilies
1736 * lpszCurrentPath can be NULL
1738 FIXME("(%ld,%s,%s,%s): stub\n",
1739 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1740 return FALSE; /* create failed */
1743 /***********************************************************************
1744 * CreateScalableFontResourceW (GDI32.@)
1746 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1747 LPCWSTR lpszResourceFile,
1748 LPCWSTR lpszFontFile,
1749 LPCWSTR lpszCurrentPath )
1751 FIXME("(%ld,%p,%p,%p): stub\n",
1752 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1753 return FALSE; /* create failed */
1757 /*************************************************************************
1758 * GetRasterizerCaps (GDI.313)
1760 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1762 return GetRasterizerCaps( lprs, cbNumBytes );
1766 /*************************************************************************
1767 * GetRasterizerCaps (GDI32.@)
1769 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1771 lprs->nSize = sizeof(RASTERIZER_STATUS);
1772 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1773 lprs->nLanguageID = 0;
1774 return TRUE;
1778 /*************************************************************************
1779 * GetKerningPairs (GDI.332)
1782 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1783 LPKERNINGPAIR16 lpKerningPairs )
1785 /* At this time kerning is ignored (set to 0) */
1786 int i;
1787 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1788 if (lpKerningPairs)
1789 for (i = 0; i < cPairs; i++)
1790 lpKerningPairs[i].iKernAmount = 0;
1791 /* FIXME: Should this function call SetLastError (0)? This is yet another
1792 * Microsoft function that can return 0 on success or failure
1794 return 0;
1799 /*************************************************************************
1800 * GetKerningPairsA (GDI32.@)
1802 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1803 LPKERNINGPAIR lpKerningPairs )
1805 int i;
1806 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1807 for (i = 0; i < cPairs; i++)
1808 lpKerningPairs[i].iKernAmount = 0;
1809 return 0;
1813 /*************************************************************************
1814 * GetKerningPairsW (GDI32.@)
1816 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1817 LPKERNINGPAIR lpKerningPairs )
1819 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1822 /*************************************************************************
1823 * TranslateCharsetInfo [GDI32.@]
1824 * TranslateCharsetInfo [USER32.@]
1826 * Fills a CHARSETINFO structure for a character set, code page, or
1827 * font. This allows making the correspondance between different labelings
1828 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1829 * of the same encoding.
1831 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1832 * only one codepage should be set in *lpSrc.
1834 * RETURNS
1835 * TRUE on success, FALSE on failure.
1838 BOOL WINAPI TranslateCharsetInfo(
1839 LPDWORD lpSrc, /* [in]
1840 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1841 if flags == TCI_SRCCHARSET: a character set value
1842 if flags == TCI_SRCCODEPAGE: a code page value
1844 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1845 DWORD flags /* [in] determines interpretation of lpSrc */
1847 int index = 0;
1848 switch (flags) {
1849 case TCI_SRCFONTSIG:
1850 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1851 break;
1852 case TCI_SRCCODEPAGE:
1853 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1854 break;
1855 case TCI_SRCCHARSET:
1856 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1857 break;
1858 default:
1859 return FALSE;
1861 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1862 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1863 return TRUE;
1866 /*************************************************************************
1867 * GetFontLanguageInfo (GDI32.@)
1869 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1870 /* return value 0 is correct for most cases anyway */
1871 FIXME("(%x):stub!\n", hdc);
1872 return 0;
1875 /*************************************************************************
1876 * GetFontLanguageInfo (GDI.616)
1878 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1879 /* return value 0 is correct for most cases anyway */
1880 FIXME("(%x):stub!\n",hdc);
1881 return 0;
1884 /*************************************************************************
1885 * GetFontData [GDI32.@] Retrieve data for TrueType font
1887 * RETURNS
1889 * success: Number of bytes returned
1890 * failure: GDI_ERROR
1892 * NOTES
1894 * Calls SetLastError()
1896 * BUGS
1898 * Unimplemented
1900 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1901 LPVOID buffer, DWORD length)
1903 FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1904 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1905 return GDI_ERROR;
1908 /*************************************************************************
1909 * GetFontData [GDI.311]
1912 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1913 LPVOID lpvBuffer, DWORD cbData)
1915 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1918 /*************************************************************************
1919 * GetCharacterPlacementA [GDI32.@]
1921 * NOTES:
1922 * the web browser control of ie4 calls this with dwFlags=0
1924 DWORD WINAPI
1925 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1926 INT nMaxExtent, GCP_RESULTSA *lpResults,
1927 DWORD dwFlags)
1929 DWORD ret=0;
1930 SIZE size;
1932 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1933 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1935 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1936 "lpOutString=%p lpGlyphs=%p\n",
1937 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1938 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1940 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
1941 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
1942 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1943 if(lpResults->lpClass) FIXME("classes not implemented\n");
1944 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
1946 /* copy will do if the GCP_REORDER flag is not set */
1947 if(lpResults->lpOutString)
1949 lstrcpynA(lpResults->lpOutString, lpString, uCount);
1952 if (lpResults->lpDx)
1954 int i, c;
1955 for (i=0; i<uCount;i++)
1957 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1958 lpResults->lpDx[i]= c;
1962 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1963 ret = MAKELONG(size.cx, size.cy);
1965 return ret;
1968 /*************************************************************************
1969 * GetCharacterPlacementW [GDI32.@]
1971 DWORD WINAPI
1972 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1973 INT nMaxExtent, GCP_RESULTSW *lpResults,
1974 DWORD dwFlags)
1976 /* return value 0 is correct for most cases anyway */
1977 FIXME(":stub!\n");
1978 return 0;
1981 /*************************************************************************
1982 * GetCharABCWidthsFloatA [GDI32.@]
1984 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1985 LPABCFLOAT lpABCF)
1987 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1988 return 0;
1991 /*************************************************************************
1992 * GetCharABCWidthsFloatW [GDI32.@]
1994 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1995 UINT iLastChar, LPABCFLOAT lpABCF)
1997 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1998 return 0;
2001 /*************************************************************************
2002 * GetCharWidthFloatA [GDI32.@]
2004 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2005 UINT iLastChar, PFLOAT pxBuffer)
2007 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2008 return 0;
2011 /*************************************************************************
2012 * GetCharWidthFloatW [GDI32.@]
2014 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2015 UINT iLastChar, PFLOAT pxBuffer)
2017 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2018 return 0;
2022 /***********************************************************************
2024 * Font Resource API *
2026 ***********************************************************************/
2027 /***********************************************************************
2028 * AddFontResource (GDI.119)
2030 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2032 * FIXME: Load header and find the best-matching font in the fontList;
2033 * fixup dfPoints if all metrics are identical, otherwise create
2034 * new fontAlias. When soft font support is ready this will
2035 * simply create a new fontResource ('filename' will go into
2036 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2037 * flag set.
2039 INT16 WINAPI AddFontResource16( LPCSTR filename )
2041 return AddFontResourceA( filename );
2045 /***********************************************************************
2046 * AddFontResourceA (GDI32.@)
2048 INT WINAPI AddFontResourceA( LPCSTR str )
2050 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2051 "this font manually.\n", debugres_a(str));
2052 return 1;
2056 /***********************************************************************
2057 * AddFontResourceW (GDI32.@)
2059 INT WINAPI AddFontResourceW( LPCWSTR str )
2061 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2062 "this font manually.\n", debugres_w(str));
2063 return 1;
2066 /***********************************************************************
2067 * RemoveFontResource (GDI.136)
2069 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2071 FIXME("(%s): stub\n", debugres_a(str));
2072 return TRUE;
2076 /***********************************************************************
2077 * RemoveFontResourceA (GDI32.@)
2079 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2081 /* This is how it should look like */
2083 fontResource** ppfr;
2084 BOOL32 retVal = FALSE;
2086 EnterCriticalSection( &crtsc_fonts_X11 );
2087 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2088 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2090 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2091 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2093 if( (*ppfr)->fo_count )
2094 (*ppfr)->fr_flags |= FR_REMOVED;
2095 else
2096 XFONT_RemoveFontResource( ppfr );
2098 retVal = TRUE;
2100 LeaveCriticalSection( &crtsc_fonts_X11 );
2101 return retVal;
2103 FIXME("(%s): stub\n", debugres_a(str));
2104 return TRUE;
2108 /***********************************************************************
2109 * RemoveFontResourceW (GDI32.@)
2111 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2113 FIXME("(%s): stub\n", debugres_w(str) );
2114 return TRUE;