4 * Copyright 1993 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/unicode.h"
29 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(font);
33 WINE_DECLARE_DEBUG_CHANNEL(gdi);
35 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
36 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
37 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
38 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
39 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
41 static const struct gdi_obj_funcs font_funcs =
43 FONT_SelectObject, /* pSelectObject */
44 FONT_GetObject16, /* pGetObject16 */
45 FONT_GetObjectA, /* pGetObjectA */
46 FONT_GetObjectW, /* pGetObjectW */
47 NULL, /* pUnrealizeObject */
48 FONT_DeleteObject /* pDeleteObject */
51 #define ENUM_UNICODE 0x00000001
52 #define ENUM_CALLED 0x00000002
62 LPLOGFONT16 lpLogFontParam;
63 FONTENUMPROCEX16 lpEnumFunc;
66 LPNEWTEXTMETRICEX16 lpTextMetric;
67 LPENUMLOGFONTEX16 lpLogFont;
77 LPLOGFONTW lpLogFontParam;
78 FONTENUMPROCEXW lpEnumFunc;
87 * For TranslateCharsetInfo
89 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
90 #define MAXTCIINDEX 32
91 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
93 { ANSI_CHARSET, 1252, FS(0)},
94 { EASTEUROPE_CHARSET, 1250, FS(1)},
95 { RUSSIAN_CHARSET, 1251, FS(2)},
96 { GREEK_CHARSET, 1253, FS(3)},
97 { TURKISH_CHARSET, 1254, FS(4)},
98 { HEBREW_CHARSET, 1255, FS(5)},
99 { ARABIC_CHARSET, 1256, FS(6)},
100 { BALTIC_CHARSET, 1257, FS(7)},
101 /* reserved by ANSI */
102 { DEFAULT_CHARSET, 0, FS(0)},
103 { DEFAULT_CHARSET, 0, FS(0)},
104 { DEFAULT_CHARSET, 0, FS(0)},
105 { DEFAULT_CHARSET, 0, FS(0)},
106 { DEFAULT_CHARSET, 0, FS(0)},
107 { DEFAULT_CHARSET, 0, FS(0)},
108 { DEFAULT_CHARSET, 0, FS(0)},
109 { DEFAULT_CHARSET, 0, FS(0)},
111 { THAI_CHARSET, 874, FS(16)},
112 { SHIFTJIS_CHARSET, 932, FS(17)},
113 { GB2312_CHARSET, 936, FS(18)},
114 { HANGEUL_CHARSET, 949, FS(19)},
115 { CHINESEBIG5_CHARSET, 950, FS(20)},
116 { JOHAB_CHARSET, 1361, FS(21)},
117 /* reserved for alternate ANSI and OEM */
118 { DEFAULT_CHARSET, 0, FS(0)},
119 { DEFAULT_CHARSET, 0, FS(0)},
120 { DEFAULT_CHARSET, 0, FS(0)},
121 { DEFAULT_CHARSET, 0, FS(0)},
122 { DEFAULT_CHARSET, 0, FS(0)},
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
126 /* reserved for system */
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
131 /* ### start build ### */
132 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
133 /* ### stop build ### */
135 /***********************************************************************
136 * LOGFONT conversion functions.
138 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
140 font16->lfHeight = font32->lfHeight;
141 font16->lfWidth = font32->lfWidth;
142 font16->lfEscapement = font32->lfEscapement;
143 font16->lfOrientation = font32->lfOrientation;
144 font16->lfWeight = font32->lfWeight;
145 font16->lfItalic = font32->lfItalic;
146 font16->lfUnderline = font32->lfUnderline;
147 font16->lfStrikeOut = font32->lfStrikeOut;
148 font16->lfCharSet = font32->lfCharSet;
149 font16->lfOutPrecision = font32->lfOutPrecision;
150 font16->lfClipPrecision = font32->lfClipPrecision;
151 font16->lfQuality = font32->lfQuality;
152 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
153 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
156 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
158 font16->lfHeight = font32->lfHeight;
159 font16->lfWidth = font32->lfWidth;
160 font16->lfEscapement = font32->lfEscapement;
161 font16->lfOrientation = font32->lfOrientation;
162 font16->lfWeight = font32->lfWeight;
163 font16->lfItalic = font32->lfItalic;
164 font16->lfUnderline = font32->lfUnderline;
165 font16->lfStrikeOut = font32->lfStrikeOut;
166 font16->lfCharSet = font32->lfCharSet;
167 font16->lfOutPrecision = font32->lfOutPrecision;
168 font16->lfClipPrecision = font32->lfClipPrecision;
169 font16->lfQuality = font32->lfQuality;
170 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
171 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
172 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
173 font16->lfFaceName[LF_FACESIZE-1] = 0;
176 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
178 font32->lfHeight = font16->lfHeight;
179 font32->lfWidth = font16->lfWidth;
180 font32->lfEscapement = font16->lfEscapement;
181 font32->lfOrientation = font16->lfOrientation;
182 font32->lfWeight = font16->lfWeight;
183 font32->lfItalic = font16->lfItalic;
184 font32->lfUnderline = font16->lfUnderline;
185 font32->lfStrikeOut = font16->lfStrikeOut;
186 font32->lfCharSet = font16->lfCharSet;
187 font32->lfOutPrecision = font16->lfOutPrecision;
188 font32->lfClipPrecision = font16->lfClipPrecision;
189 font32->lfQuality = font16->lfQuality;
190 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
191 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
194 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
196 font32->lfHeight = font16->lfHeight;
197 font32->lfWidth = font16->lfWidth;
198 font32->lfEscapement = font16->lfEscapement;
199 font32->lfOrientation = font16->lfOrientation;
200 font32->lfWeight = font16->lfWeight;
201 font32->lfItalic = font16->lfItalic;
202 font32->lfUnderline = font16->lfUnderline;
203 font32->lfStrikeOut = font16->lfStrikeOut;
204 font32->lfCharSet = font16->lfCharSet;
205 font32->lfOutPrecision = font16->lfOutPrecision;
206 font32->lfClipPrecision = font16->lfClipPrecision;
207 font32->lfQuality = font16->lfQuality;
208 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
209 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
210 font32->lfFaceName[LF_FACESIZE-1] = 0;
213 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
215 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
216 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
220 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
222 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
223 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
224 LF_FACESIZE, NULL, NULL);
227 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
229 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
230 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
231 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
232 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
235 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
237 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
239 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
240 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
241 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
242 font32->elfStyle[LF_FACESIZE-1] = 0;
243 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
244 font32->elfScript[LF_FACESIZE-1] = 0;
247 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
249 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
251 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
252 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
253 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
254 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
255 font16->elfStyle, LF_FACESIZE, NULL, NULL );
256 font16->elfStyle[LF_FACESIZE-1] = '\0';
257 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
258 font16->elfScript, LF_FACESIZE, NULL, NULL );
259 font16->elfScript[LF_FACESIZE-1] = '\0';
262 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
264 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
266 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
267 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
268 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
269 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
270 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
271 fontA->elfStyle[LF_FACESIZE-1] = '\0';
272 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
273 fontA->elfScript, LF_FACESIZE, NULL, NULL );
274 fontA->elfScript[LF_FACESIZE-1] = '\0';
277 /***********************************************************************
278 * TEXTMETRIC conversion functions.
280 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
282 ptm16->tmHeight = ptm32->tmHeight;
283 ptm16->tmAscent = ptm32->tmAscent;
284 ptm16->tmDescent = ptm32->tmDescent;
285 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
286 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
287 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
288 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
289 ptm16->tmWeight = ptm32->tmWeight;
290 ptm16->tmOverhang = ptm32->tmOverhang;
291 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
292 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
293 ptm16->tmFirstChar = ptm32->tmFirstChar;
294 ptm16->tmLastChar = ptm32->tmLastChar;
295 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
296 ptm16->tmBreakChar = ptm32->tmBreakChar;
297 ptm16->tmItalic = ptm32->tmItalic;
298 ptm16->tmUnderlined = ptm32->tmUnderlined;
299 ptm16->tmStruckOut = ptm32->tmStruckOut;
300 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
301 ptm16->tmCharSet = ptm32->tmCharSet;
304 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
306 ptm16->tmHeight = ptm32->tmHeight;
307 ptm16->tmAscent = ptm32->tmAscent;
308 ptm16->tmDescent = ptm32->tmDescent;
309 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
310 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
311 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
312 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
313 ptm16->tmWeight = ptm32->tmWeight;
314 ptm16->tmOverhang = ptm32->tmOverhang;
315 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
316 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
317 ptm16->tmFirstChar = ptm32->tmFirstChar;
318 ptm16->tmLastChar = ptm32->tmLastChar;
319 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
320 ptm16->tmBreakChar = ptm32->tmBreakChar;
321 ptm16->tmItalic = ptm32->tmItalic;
322 ptm16->tmUnderlined = ptm32->tmUnderlined;
323 ptm16->tmStruckOut = ptm32->tmStruckOut;
324 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
325 ptm16->tmCharSet = ptm32->tmCharSet;
328 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
330 ptm32->tmHeight = ptm16->tmHeight;
331 ptm32->tmAscent = ptm16->tmAscent;
332 ptm32->tmDescent = ptm16->tmDescent;
333 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
334 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
335 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
336 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
337 ptm32->tmWeight = ptm16->tmWeight;
338 ptm32->tmOverhang = ptm16->tmOverhang;
339 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
340 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
341 ptm32->tmFirstChar = ptm16->tmFirstChar;
342 ptm32->tmLastChar = ptm16->tmLastChar;
343 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
344 ptm32->tmBreakChar = ptm16->tmBreakChar;
345 ptm32->tmItalic = ptm16->tmItalic;
346 ptm32->tmUnderlined = ptm16->tmUnderlined;
347 ptm32->tmStruckOut = ptm16->tmStruckOut;
348 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
349 ptm32->tmCharSet = ptm16->tmCharSet;
352 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
354 ptm32->tmHeight = ptm16->tmHeight;
355 ptm32->tmAscent = ptm16->tmAscent;
356 ptm32->tmDescent = ptm16->tmDescent;
357 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
358 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
359 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
360 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
361 ptm32->tmWeight = ptm16->tmWeight;
362 ptm32->tmOverhang = ptm16->tmOverhang;
363 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
364 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
365 ptm32->tmFirstChar = ptm16->tmFirstChar;
366 ptm32->tmLastChar = ptm16->tmLastChar;
367 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
368 ptm32->tmBreakChar = ptm16->tmBreakChar;
369 ptm32->tmItalic = ptm16->tmItalic;
370 ptm32->tmUnderlined = ptm16->tmUnderlined;
371 ptm32->tmStruckOut = ptm16->tmStruckOut;
372 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
373 ptm32->tmCharSet = ptm16->tmCharSet;
376 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
378 ptm32W->tmHeight = ptm32A->tmHeight;
379 ptm32W->tmAscent = ptm32A->tmAscent;
380 ptm32W->tmDescent = ptm32A->tmDescent;
381 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
382 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
383 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
384 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
385 ptm32W->tmWeight = ptm32A->tmWeight;
386 ptm32W->tmOverhang = ptm32A->tmOverhang;
387 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
388 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
389 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
390 ptm32W->tmLastChar = ptm32A->tmLastChar;
391 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
392 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
393 ptm32W->tmItalic = ptm32A->tmItalic;
394 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
395 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
396 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
397 ptm32W->tmCharSet = ptm32A->tmCharSet;
400 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
402 ptmA->tmHeight = ptmW->tmHeight;
403 ptmA->tmAscent = ptmW->tmAscent;
404 ptmA->tmDescent = ptmW->tmDescent;
405 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
406 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
407 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
408 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
409 ptmA->tmWeight = ptmW->tmWeight;
410 ptmA->tmOverhang = ptmW->tmOverhang;
411 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
412 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
413 ptmA->tmFirstChar = ptmW->tmFirstChar;
414 ptmA->tmLastChar = ptmW->tmLastChar;
415 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
416 ptmA->tmBreakChar = ptmW->tmBreakChar;
417 ptmA->tmItalic = ptmW->tmItalic;
418 ptmA->tmUnderlined = ptmW->tmUnderlined;
419 ptmA->tmStruckOut = ptmW->tmStruckOut;
420 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
421 ptmA->tmCharSet = ptmW->tmCharSet;
425 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
427 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
428 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
429 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
430 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
431 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
432 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
435 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
437 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
438 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
439 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
440 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
441 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
442 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
445 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
447 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
448 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
449 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
450 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
451 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
452 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
456 /***********************************************************************
457 * CreateFontIndirect (GDI.57)
459 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
464 FONT_LogFont16ToW( plf16, &lfW );
465 return CreateFontIndirectW( &lfW );
467 return CreateFontIndirectW( NULL );
472 /***********************************************************************
473 * CreateFontIndirectA (GDI32.@)
475 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
480 FONT_LogFontAToW( plfA, &lfW );
481 return CreateFontIndirectW( &lfW );
483 return CreateFontIndirectW( NULL );
487 /***********************************************************************
488 * CreateFontIndirectW (GDI32.@)
490 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
497 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
499 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
501 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
502 plf->lfHeight, plf->lfWidth,
503 plf->lfEscapement, plf->lfOrientation,
504 plf->lfPitchAndFamily,
505 debugstr_w(plf->lfFaceName),
506 plf->lfWeight > 400 ? "Bold" : "",
507 plf->lfItalic ? "Italic" : "", hFont);
509 if (plf->lfEscapement != plf->lfOrientation) {
510 /* this should really depend on whether GM_ADVANCED is set */
511 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
512 WARN("orientation angle %f set to "
513 "escapement angle %f for new font %04x\n",
514 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
516 GDI_ReleaseObj( hFont );
519 else WARN("(NULL) => NULL\n");
524 /***********************************************************************
525 * CreateFont (GDI.56)
527 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
528 INT16 weight, BYTE italic, BYTE underline,
529 BYTE strikeout, BYTE charset, BYTE outpres,
530 BYTE clippres, BYTE quality, BYTE pitch,
535 logfont.lfHeight = height;
536 logfont.lfWidth = width;
537 logfont.lfEscapement = esc;
538 logfont.lfOrientation = orient;
539 logfont.lfWeight = weight;
540 logfont.lfItalic = italic;
541 logfont.lfUnderline = underline;
542 logfont.lfStrikeOut = strikeout;
543 logfont.lfCharSet = charset;
544 logfont.lfOutPrecision = outpres;
545 logfont.lfClipPrecision = clippres;
546 logfont.lfQuality = quality;
547 logfont.lfPitchAndFamily = pitch;
550 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
552 logfont.lfFaceName[0] = '\0';
554 return CreateFontIndirect16( &logfont );
557 /*************************************************************************
558 * CreateFontA (GDI32.@)
560 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
561 INT orient, INT weight, DWORD italic,
562 DWORD underline, DWORD strikeout, DWORD charset,
563 DWORD outpres, DWORD clippres, DWORD quality,
564 DWORD pitch, LPCSTR name )
568 logfont.lfHeight = height;
569 logfont.lfWidth = width;
570 logfont.lfEscapement = esc;
571 logfont.lfOrientation = orient;
572 logfont.lfWeight = weight;
573 logfont.lfItalic = italic;
574 logfont.lfUnderline = underline;
575 logfont.lfStrikeOut = strikeout;
576 logfont.lfCharSet = charset;
577 logfont.lfOutPrecision = outpres;
578 logfont.lfClipPrecision = clippres;
579 logfont.lfQuality = quality;
580 logfont.lfPitchAndFamily = pitch;
583 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
585 logfont.lfFaceName[0] = '\0';
587 return CreateFontIndirectA( &logfont );
590 /*************************************************************************
591 * CreateFontW (GDI32.@)
593 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
594 INT orient, INT weight, DWORD italic,
595 DWORD underline, DWORD strikeout, DWORD charset,
596 DWORD outpres, DWORD clippres, DWORD quality,
597 DWORD pitch, LPCWSTR name )
601 logfont.lfHeight = height;
602 logfont.lfWidth = width;
603 logfont.lfEscapement = esc;
604 logfont.lfOrientation = orient;
605 logfont.lfWeight = weight;
606 logfont.lfItalic = italic;
607 logfont.lfUnderline = underline;
608 logfont.lfStrikeOut = strikeout;
609 logfont.lfCharSet = charset;
610 logfont.lfOutPrecision = outpres;
611 logfont.lfClipPrecision = clippres;
612 logfont.lfQuality = quality;
613 logfont.lfPitchAndFamily = pitch;
616 lstrcpynW(logfont.lfFaceName, name,
617 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
619 logfont.lfFaceName[0] = '\0';
621 return CreateFontIndirectW( &logfont );
625 /***********************************************************************
628 * If the driver supports vector fonts we create a gdi font first and
629 * then call the driver to give it a chance to supply its own device
630 * font. If the driver wants to do this it returns TRUE and we can
631 * delete the gdi font, if the driver wants to use the gdi font it
632 * should return FALSE, to signal an error return GDI_ERROR. For
633 * drivers that don't support vector fonts they must supply their own
636 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
639 DC *dc = DC_GetDCPtr( hdc );
643 if (dc->hFont != handle || dc->gdiFont == NULL)
645 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
646 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
649 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
651 if (ret && dc->gdiFont) dc->gdiFont = 0;
653 if (ret == GDI_ERROR)
654 ret = 0; /* SelectObject returns 0 on error */
660 GDI_ReleaseObj( hdc );
665 /***********************************************************************
668 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
673 FONT_LogFontWTo16( &font->logfont, &lf16 );
675 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
676 memcpy( buffer, &lf16, count );
680 /***********************************************************************
683 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
688 FONT_LogFontWToA( &font->logfont, &lfA );
690 if (count > sizeof(lfA)) count = sizeof(lfA);
691 memcpy( buffer, &lfA, count );
695 /***********************************************************************
698 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
701 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
702 memcpy( buffer, &font->logfont, count );
707 /***********************************************************************
710 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
712 WineEngDestroyFontInstance( handle );
713 return GDI_FreeObject( handle, obj );
717 /***********************************************************************
718 * FONT_EnumInstance16
720 * Called by the device driver layer to pass font info
721 * down to the application.
723 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
724 DWORD fType, LPARAM lp )
726 fontEnum16 *pfe = (fontEnum16*)lp;
730 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
731 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
733 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
734 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
735 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
737 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
738 (UINT16)fType, (LPARAM)pfe->lpData );
739 /* get the lock again and make sure the DC is still valid */
740 dc = DC_GetDCPtr( pfe->hdc );
741 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
743 if (dc) GDI_ReleaseObj( pfe->hdc );
744 pfe->hdc = 0; /* make sure we don't try to release it later on */
751 /***********************************************************************
754 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
755 DWORD fType, LPARAM lp )
757 fontEnum32 *pfe = (fontEnum32*)lp;
761 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
762 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
763 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
765 /* convert font metrics */
766 ENUMLOGFONTEXA logfont;
767 NEWTEXTMETRICEXA tmA;
769 pfe->dwFlags |= ENUM_CALLED;
770 if (!(pfe->dwFlags & ENUM_UNICODE))
772 FONT_EnumLogFontExWToA( plf, &logfont);
773 FONT_NewTextMetricExWToA( ptm, &tmA );
774 plf = (LPENUMLOGFONTEXW)&logfont;
775 ptm = (LPNEWTEXTMETRICEXW)&tmA;
777 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
779 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
781 /* get the lock again and make sure the DC is still valid */
782 dc = DC_GetDCPtr( pfe->hdc );
783 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
785 if (dc) GDI_ReleaseObj( pfe->hdc );
786 pfe->hdc = 0; /* make sure we don't try to release it later on */
793 /***********************************************************************
794 * EnumFontFamiliesEx (GDI.613)
796 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
797 FONTENUMPROCEX16 efproc, LPARAM lParam,
802 DC* dc = DC_GetDCPtr( hDC );
807 fe16.physDev = dc->physDev;
809 if (dc->funcs->pEnumDeviceFonts)
811 NEWTEXTMETRICEX16 tm16;
812 ENUMLOGFONTEX16 lf16;
814 FONT_LogFont16ToW(plf, &lfW);
816 fe16.lpLogFontParam = plf;
817 fe16.lpEnumFunc = efproc;
818 fe16.lpData = lParam;
819 fe16.lpTextMetric = &tm16;
820 fe16.lpLogFont = &lf16;
821 fe16.segTextMetric = MapLS( &tm16 );
822 fe16.segLogFont = MapLS( &lf16 );
824 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
825 FONT_EnumInstance16, (LPARAM)&fe16 );
826 UnMapLS( fe16.segTextMetric );
827 UnMapLS( fe16.segLogFont );
829 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
833 /***********************************************************************
834 * FONT_EnumFontFamiliesEx
836 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
837 FONTENUMPROCEXW efproc,
838 LPARAM lParam, DWORD dwUnicode)
841 DC *dc = DC_GetDCPtr( hDC );
847 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
849 fe32.lpLogFontParam = plf;
850 fe32.lpEnumFunc = efproc;
851 fe32.lpData = lParam;
852 fe32.dwFlags = dwUnicode;
855 fe32.physDev = dc->physDev;
857 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
859 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
866 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
867 fe32.dwFlags &= ~ENUM_CALLED;
868 if (ret && dc->funcs->pEnumDeviceFonts) {
869 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
870 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
874 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
878 /***********************************************************************
879 * EnumFontFamiliesExW (GDI32.@)
881 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
882 FONTENUMPROCEXW efproc,
883 LPARAM lParam, DWORD dwFlags )
885 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
888 /***********************************************************************
889 * EnumFontFamiliesExA (GDI32.@)
891 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
892 FONTENUMPROCEXA efproc,
893 LPARAM lParam, DWORD dwFlags)
896 FONT_LogFontAToW( plf, &lfW );
898 return FONT_EnumFontFamiliesEx( hDC, &lfW,
899 (FONTENUMPROCEXW)efproc, lParam, 0);
902 /***********************************************************************
903 * EnumFontFamilies (GDI.330)
905 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
906 FONTENUMPROC16 efproc, LPARAM lpData )
910 lf.lfCharSet = DEFAULT_CHARSET;
911 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
912 else lf.lfFaceName[0] = '\0';
914 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
917 /***********************************************************************
918 * EnumFontFamiliesA (GDI32.@)
920 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
921 FONTENUMPROCA efproc, LPARAM lpData )
925 lf.lfCharSet = DEFAULT_CHARSET;
926 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
927 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
929 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
932 /***********************************************************************
933 * EnumFontFamiliesW (GDI32.@)
935 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
936 FONTENUMPROCW efproc, LPARAM lpData )
940 lf.lfCharSet = DEFAULT_CHARSET;
941 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
942 else lf.lfFaceName[0] = 0;
944 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
947 /***********************************************************************
950 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
953 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
956 /***********************************************************************
957 * EnumFontsA (GDI32.@)
959 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
962 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
965 /***********************************************************************
966 * EnumFontsW (GDI32.@)
968 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
971 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
975 /***********************************************************************
976 * GetTextCharacterExtra (GDI.89)
978 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
980 return (INT16)GetTextCharacterExtra( hdc );
984 /***********************************************************************
985 * GetTextCharacterExtra (GDI32.@)
987 INT WINAPI GetTextCharacterExtra( HDC hdc )
990 DC *dc = DC_GetDCPtr( hdc );
992 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
994 GDI_ReleaseObj( hdc );
999 /***********************************************************************
1000 * SetTextCharacterExtra (GDI.8)
1002 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
1004 return (INT16)SetTextCharacterExtra( hdc, extra );
1008 /***********************************************************************
1009 * SetTextCharacterExtra (GDI32.@)
1011 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
1014 DC * dc = DC_GetDCPtr( hdc );
1016 if (dc->funcs->pSetTextCharacterExtra)
1017 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
1020 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
1021 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
1022 dc->charExtra = abs(extra);
1024 GDI_ReleaseObj( hdc );
1029 /***********************************************************************
1030 * SetTextJustification (GDI.10)
1032 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
1034 return SetTextJustification( hdc, extra, breaks );
1038 /***********************************************************************
1039 * SetTextJustification (GDI32.@)
1041 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
1044 DC * dc = DC_GetDCPtr( hdc );
1045 if (!dc) return FALSE;
1046 if (dc->funcs->pSetTextJustification)
1047 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
1050 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
1051 if (!extra) breaks = 0;
1052 dc->breakTotalExtra = extra;
1053 dc->breakCount = breaks;
1056 dc->breakExtra = extra / breaks;
1057 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
1065 GDI_ReleaseObj( hdc );
1070 /***********************************************************************
1071 * GetTextFace (GDI.92)
1073 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
1075 return GetTextFaceA(hdc,count,name);
1078 /***********************************************************************
1079 * GetTextFaceA (GDI32.@)
1081 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
1083 INT res = GetTextFaceW(hdc, 0, NULL);
1084 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
1085 GetTextFaceW( hdc, res, nameW );
1088 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
1091 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
1092 HeapFree( GetProcessHeap(), 0, nameW );
1096 /***********************************************************************
1097 * GetTextFaceW (GDI32.@)
1099 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
1104 DC * dc = DC_GetDCPtr( hdc );
1107 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1111 lstrcpynW( name, font->logfont.lfFaceName, count );
1112 ret = strlenW(name);
1114 else ret = strlenW(font->logfont.lfFaceName) + 1;
1115 GDI_ReleaseObj( dc->hFont );
1117 GDI_ReleaseObj( hdc );
1122 /***********************************************************************
1123 * GetTextExtent (GDI.91)
1125 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1128 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1129 return MAKELONG( size.cx, size.cy );
1133 /***********************************************************************
1134 * GetTextExtentPoint (GDI.471)
1136 * FIXME: Should this have a bug for compatibility?
1137 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1138 * bugs (-> MSDN KB q147647.txt).
1140 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1145 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1146 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1147 size->cx = size32.cx;
1148 size->cy = size32.cy;
1153 /***********************************************************************
1154 * GetTextExtentPoint32A (GDI32.@)
1156 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1161 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1164 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1165 HeapFree( GetProcessHeap(), 0, p );
1168 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1169 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1174 /***********************************************************************
1175 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1177 * Computes width and height of the specified string.
1183 BOOL WINAPI GetTextExtentPoint32W(
1184 HDC hdc, /* [in] Handle of device context */
1185 LPCWSTR str, /* [in] Address of text string */
1186 INT count, /* [in] Number of characters in string */
1187 LPSIZE size) /* [out] Address of structure for string size */
1190 DC * dc = DC_GetDCPtr( hdc );
1191 if (!dc) return FALSE;
1194 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1195 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1196 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1198 else if(dc->funcs->pGetTextExtentPoint)
1199 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1201 GDI_ReleaseObj( hdc );
1203 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1204 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1208 /***********************************************************************
1209 * GetTextExtentPointI [GDI32.@]
1211 * Computes width and height of the array of glyph indices.
1217 BOOL WINAPI GetTextExtentPointI(
1218 HDC hdc, /* [in] Handle of device context */
1219 const WORD *indices, /* [in] Address of glyph index array */
1220 INT count, /* [in] Number of glyphs in array */
1221 LPSIZE size) /* [out] Address of structure for string size */
1224 DC * dc = DC_GetDCPtr( hdc );
1225 if (!dc) return FALSE;
1228 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1229 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1230 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1232 else if(dc->funcs->pGetTextExtentPoint) {
1233 FIXME("calling GetTextExtentPoint\n");
1234 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1237 GDI_ReleaseObj( hdc );
1239 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1240 hdc, indices, count, size, size->cx, size->cy );
1245 /***********************************************************************
1246 * GetTextExtentPointA (GDI32.@)
1248 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1251 TRACE("not bug compatible.\n");
1252 return GetTextExtentPoint32A( hdc, str, count, size );
1255 /***********************************************************************
1256 * GetTextExtentPointW (GDI32.@)
1258 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1261 TRACE("not bug compatible.\n");
1262 return GetTextExtentPoint32W( hdc, str, count, size );
1266 /***********************************************************************
1267 * GetTextExtentExPointA (GDI32.@)
1269 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1270 INT maxExt, LPINT lpnFit,
1271 LPINT alpDx, LPSIZE size )
1275 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1276 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1277 HeapFree( GetProcessHeap(), 0, p );
1282 /***********************************************************************
1283 * GetTextExtentExPointW (GDI32.@)
1285 * Return the size of the string as it would be if it was output properly by
1288 * This should include
1289 * - Intercharacter spacing
1290 * - justification spacing (not yet done)
1291 * - kerning? see below
1293 * Kerning. Since kerning would be carried out by the rendering code it should
1294 * be done by the driver. However they don't support it yet. Also I am not
1295 * yet persuaded that (certainly under Win95) any kerning is actually done.
1297 * str: According to MSDN this should be null-terminated. That is not true; a
1298 * null will not terminate it early.
1299 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1300 * than count. I have seen it be either the size of the full string or
1301 * 1 less than the size of the full string. I have not seen it bear any
1302 * resemblance to the portion that would fit.
1303 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1304 * trailing intercharacter spacing and any trailing justification.
1307 * Currently we do this by measuring each character etc. We should do it by
1308 * passing the request to the driver, perhaps by extending the
1309 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1310 * thinking about kerning issues and rounding issues in the justification.
1313 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1314 INT maxExt, LPINT lpnFit,
1315 LPINT alpDx, LPSIZE size )
1317 int index, nFit, extent;
1321 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1323 size->cx = size->cy = nFit = extent = 0;
1324 for(index = 0; index < count; index++)
1326 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1327 /* GetTextExtentPoint includes intercharacter spacing. */
1328 /* FIXME - justification needs doing yet. Remember that the base
1329 * data will not be in logical coordinates.
1332 if( !lpnFit || extent <= maxExt )
1333 /* It is allowed to be equal. */
1336 if( alpDx ) alpDx[index] = extent;
1338 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1342 if(lpnFit) *lpnFit = nFit;
1345 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1351 /***********************************************************************
1352 * GetTextMetrics (GDI.93)
1354 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1358 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1359 FONT_TextMetricWTo16( &tm32, metrics );
1364 /***********************************************************************
1365 * GetTextMetricsA (GDI32.@)
1367 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1371 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1372 FONT_TextMetricWToA( &tm32, metrics );
1376 /***********************************************************************
1377 * GetTextMetricsW (GDI32.@)
1379 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1382 DC * dc = DC_GetDCPtr( hdc );
1383 if (!dc) return FALSE;
1386 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1387 else if (dc->funcs->pGetTextMetrics)
1388 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1392 /* device layer returns values in device units
1393 * therefore we have to convert them to logical */
1395 #define WDPTOLP(x) ((x<0)? \
1396 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1397 (abs((x)*dc->wndExtX/dc->vportExtX)))
1398 #define HDPTOLP(y) ((y<0)? \
1399 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1400 (abs((y)*dc->wndExtY/dc->vportExtY)))
1402 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1403 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1404 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1405 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1406 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1407 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1408 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1409 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1412 TRACE("text metrics:\n"
1413 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1414 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1415 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1416 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1417 " PitchAndFamily = %02x\n"
1418 " --------------------\n"
1419 " InternalLeading = %li\n"
1423 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1424 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1425 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1426 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1427 metrics->tmPitchAndFamily,
1428 metrics->tmInternalLeading,
1431 metrics->tmHeight );
1433 GDI_ReleaseObj( hdc );
1438 /***********************************************************************
1439 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1442 * lpOTM should be LPOUTLINETEXTMETRIC
1445 * Success: Non-zero or size of required buffer
1448 UINT16 WINAPI GetOutlineTextMetrics16(
1449 HDC16 hdc, /* [in] Handle of device context */
1450 UINT16 cbData, /* [in] Size of metric data array */
1451 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1453 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1458 /***********************************************************************
1459 * GetOutlineTextMetricsA (GDI32.@)
1460 * Gets metrics for TrueType fonts.
1464 * Success: Non-zero or size of required buffer
1467 UINT WINAPI GetOutlineTextMetricsA(
1468 HDC hdc, /* [in] Handle of device context */
1469 UINT cbData, /* [in] Size of metric data array */
1470 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1472 char buf[512], *ptr;
1474 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1477 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1478 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1480 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1481 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1484 needed = sizeof(OUTLINETEXTMETRICA);
1485 if(lpOTMW->otmpFamilyName)
1486 needed += WideCharToMultiByte(CP_ACP, 0,
1487 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1488 NULL, 0, NULL, NULL);
1489 if(lpOTMW->otmpFaceName)
1490 needed += WideCharToMultiByte(CP_ACP, 0,
1491 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1492 NULL, 0, NULL, NULL);
1493 if(lpOTMW->otmpStyleName)
1494 needed += WideCharToMultiByte(CP_ACP, 0,
1495 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1496 NULL, 0, NULL, NULL);
1497 if(lpOTMW->otmpFullName)
1498 needed += WideCharToMultiByte(CP_ACP, 0,
1499 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1500 NULL, 0, NULL, NULL);
1507 if(needed > cbData) {
1513 lpOTM->otmSize = needed;
1514 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1515 lpOTM->otmFiller = 0;
1516 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1517 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1518 lpOTM->otmfsType = lpOTMW->otmfsType;
1519 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1520 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1521 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1522 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1523 lpOTM->otmAscent = lpOTMW->otmAscent;
1524 lpOTM->otmDescent = lpOTMW->otmDescent;
1525 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1526 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1527 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1528 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1529 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1530 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1531 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1532 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1533 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1534 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1535 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1536 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1537 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1538 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1539 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1540 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1543 ptr = (char*)(lpOTM + 1);
1544 left = needed - sizeof(*lpOTM);
1546 if(lpOTMW->otmpFamilyName) {
1547 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1548 len = WideCharToMultiByte(CP_ACP, 0,
1549 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1550 ptr, left, NULL, NULL);
1554 lpOTM->otmpFamilyName = 0;
1556 if(lpOTMW->otmpFaceName) {
1557 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1558 len = WideCharToMultiByte(CP_ACP, 0,
1559 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1560 ptr, left, NULL, NULL);
1564 lpOTM->otmpFaceName = 0;
1566 if(lpOTMW->otmpStyleName) {
1567 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1568 len = WideCharToMultiByte(CP_ACP, 0,
1569 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1570 ptr, left, NULL, NULL);
1574 lpOTM->otmpStyleName = 0;
1576 if(lpOTMW->otmpFullName) {
1577 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1578 len = WideCharToMultiByte(CP_ACP, 0,
1579 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1580 ptr, left, NULL, NULL);
1583 lpOTM->otmpFullName = 0;
1590 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1591 HeapFree(GetProcessHeap(), 0, lpOTMW);
1597 /***********************************************************************
1598 * GetOutlineTextMetricsW [GDI32.@]
1600 UINT WINAPI GetOutlineTextMetricsW(
1601 HDC hdc, /* [in] Handle of device context */
1602 UINT cbData, /* [in] Size of metric data array */
1603 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1605 DC *dc = DC_GetDCPtr( hdc );
1608 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1612 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1614 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1615 but really this should just be a return 0. */
1617 ret = sizeof(*lpOTM);
1622 memset(lpOTM, 0, ret);
1623 lpOTM->otmSize = sizeof(*lpOTM);
1624 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1626 Further fill of the structure not implemented,
1627 Needs real values for the structure members
1632 GDI_ReleaseObj(hdc);
1637 /***********************************************************************
1638 * GetCharWidth (GDI.350)
1640 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1643 BOOL retVal = FALSE;
1645 if( firstChar != lastChar )
1647 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1648 sizeof(INT)*(1 + (lastChar - firstChar)));
1651 LPINT obuf32 = buf32;
1654 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1657 for (i = firstChar; i <= lastChar; i++)
1658 *buffer++ = *buf32++;
1660 HeapFree(GetProcessHeap(), 0, obuf32);
1663 else /* happens quite often to warrant a special treatment */
1666 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1673 /***********************************************************************
1674 * GetCharWidthW (GDI32.@)
1675 * GetCharWidth32W (GDI32.@)
1677 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1682 DC * dc = DC_GetDCPtr( hdc );
1683 if (!dc) return FALSE;
1686 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1687 else if (dc->funcs->pGetCharWidth)
1688 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1692 /* convert device units to logical */
1694 extra = dc->vportExtX >> 1;
1695 for( i = firstChar; i <= lastChar; i++, buffer++ )
1696 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1699 GDI_ReleaseObj( hdc );
1704 /***********************************************************************
1705 * GetCharWidthA (GDI32.@)
1706 * GetCharWidth32A (GDI32.@)
1708 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1711 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1716 if(count <= 0) return FALSE;
1718 str = HeapAlloc(GetProcessHeap(), 0, count);
1719 for(i = 0; i < count; i++)
1720 str[i] = (BYTE)(firstChar + i);
1722 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1724 for(i = 0; i < wlen; i++)
1726 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1734 HeapFree(GetProcessHeap(), 0, str);
1735 HeapFree(GetProcessHeap(), 0, wstr);
1741 /* FIXME: all following APIs ******************************************/
1744 /***********************************************************************
1745 * SetMapperFlags (GDI.349)
1747 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1749 return SetMapperFlags( hDC, dwFlag );
1753 /***********************************************************************
1754 * SetMapperFlags (GDI32.@)
1756 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1758 DC *dc = DC_GetDCPtr( hDC );
1761 if(dc->funcs->pSetMapperFlags)
1762 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1764 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1765 GDI_ReleaseObj( hDC );
1769 /***********************************************************************
1770 * GetAspectRatioFilterEx (GDI.486)
1772 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1774 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1778 /***********************************************************************
1779 * GetAspectRatioFilterEx (GDI32.@)
1781 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1783 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1787 /***********************************************************************
1788 * GetCharABCWidths (GDI.307)
1790 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1793 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1796 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1797 HeapFree(GetProcessHeap(),0,abc32);
1801 for (i=firstChar;i<=lastChar;i++) {
1802 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1803 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1804 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1806 HeapFree(GetProcessHeap(),0,abc32);
1811 /***********************************************************************
1812 * GetCharABCWidthsA (GDI32.@)
1814 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1817 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1822 if(count <= 0) return FALSE;
1824 str = HeapAlloc(GetProcessHeap(), 0, count);
1825 for(i = 0; i < count; i++)
1826 str[i] = (BYTE)(firstChar + i);
1828 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1830 for(i = 0; i < wlen; i++)
1832 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1840 HeapFree(GetProcessHeap(), 0, str);
1841 HeapFree(GetProcessHeap(), 0, wstr);
1847 /******************************************************************************
1848 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1851 * hdc [I] Handle of device context
1852 * firstChar [I] First character in range to query
1853 * lastChar [I] Last character in range to query
1854 * abc [O] Address of character-width structure
1857 * Only works with TrueType fonts
1863 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1866 DC *dc = DC_GetDCPtr(hdc);
1872 for (i=firstChar;i<=lastChar;i++) {
1873 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1874 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1875 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1876 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1880 GDI_ReleaseObj(hdc);
1885 /***********************************************************************
1886 * GetGlyphOutline (GDI.309)
1888 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1889 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1890 LPVOID lpBuffer, const MAT2 *lpmat2 )
1892 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1893 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1894 return (DWORD)-1; /* failure */
1898 /***********************************************************************
1899 * GetGlyphOutlineA (GDI32.@)
1901 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1902 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1903 LPVOID lpBuffer, const MAT2 *lpmat2 )
1909 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1910 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1914 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1917 HeapFree(GetProcessHeap(), 0, p);
1921 /***********************************************************************
1922 * GetGlyphOutlineW (GDI32.@)
1924 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1925 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1926 LPVOID lpBuffer, const MAT2 *lpmat2 )
1928 DC *dc = DC_GetDCPtr(hdc);
1931 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1932 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1934 if(!dc) return GDI_ERROR;
1937 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1938 cbBuffer, lpBuffer, lpmat2);
1942 GDI_ReleaseObj(hdc);
1946 /***********************************************************************
1947 * CreateScalableFontResource (GDI.310)
1949 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1950 LPCSTR lpszResourceFile,
1951 LPCSTR fontFile, LPCSTR path )
1953 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1957 /***********************************************************************
1958 * CreateScalableFontResourceA (GDI32.@)
1960 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1961 LPCSTR lpszResourceFile,
1962 LPCSTR lpszFontFile,
1963 LPCSTR lpszCurrentPath )
1965 /* fHidden=1 - only visible for the calling app, read-only, not
1966 * enumbered with EnumFonts/EnumFontFamilies
1967 * lpszCurrentPath can be NULL
1969 FIXME("(%ld,%s,%s,%s): stub\n",
1970 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1971 debugstr_a(lpszCurrentPath) );
1972 return FALSE; /* create failed */
1975 /***********************************************************************
1976 * CreateScalableFontResourceW (GDI32.@)
1978 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1979 LPCWSTR lpszResourceFile,
1980 LPCWSTR lpszFontFile,
1981 LPCWSTR lpszCurrentPath )
1983 FIXME("(%ld,%p,%p,%p): stub\n",
1984 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1985 return FALSE; /* create failed */
1989 /*************************************************************************
1990 * GetRasterizerCaps (GDI.313)
1992 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1994 return GetRasterizerCaps( lprs, cbNumBytes );
1998 /*************************************************************************
1999 * GetRasterizerCaps (GDI32.@)
2001 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2003 lprs->nSize = sizeof(RASTERIZER_STATUS);
2004 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2005 lprs->nLanguageID = 0;
2010 /*************************************************************************
2011 * GetKerningPairs (GDI.332)
2014 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
2015 LPKERNINGPAIR16 lpKerningPairs )
2017 /* At this time kerning is ignored (set to 0) */
2019 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2021 for (i = 0; i < cPairs; i++)
2022 lpKerningPairs[i].iKernAmount = 0;
2023 /* FIXME: Should this function call SetLastError (0)? This is yet another
2024 * Microsoft function that can return 0 on success or failure
2031 /*************************************************************************
2032 * GetKerningPairsA (GDI32.@)
2034 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2035 LPKERNINGPAIR lpKerningPairs )
2038 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2039 for (i = 0; i < cPairs; i++)
2040 lpKerningPairs[i].iKernAmount = 0;
2045 /*************************************************************************
2046 * GetKerningPairsW (GDI32.@)
2048 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2049 LPKERNINGPAIR lpKerningPairs )
2051 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
2054 /*************************************************************************
2055 * TranslateCharsetInfo [GDI32.@]
2056 * TranslateCharsetInfo [USER32.@]
2058 * Fills a CHARSETINFO structure for a character set, code page, or
2059 * font. This allows making the correspondance between different labelings
2060 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2061 * of the same encoding.
2063 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2064 * only one codepage should be set in *lpSrc.
2067 * TRUE on success, FALSE on failure.
2070 BOOL WINAPI TranslateCharsetInfo(
2071 LPDWORD lpSrc, /* [in]
2072 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2073 if flags == TCI_SRCCHARSET: a character set value
2074 if flags == TCI_SRCCODEPAGE: a code page value
2076 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2077 DWORD flags /* [in] determines interpretation of lpSrc */
2081 case TCI_SRCFONTSIG:
2082 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2084 case TCI_SRCCODEPAGE:
2085 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2087 case TCI_SRCCHARSET:
2088 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2093 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2094 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2098 /*************************************************************************
2099 * GetFontLanguageInfo (GDI32.@)
2101 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
2102 /* return value 0 is correct for most cases anyway */
2103 FIXME("(%x):stub!\n", hdc);
2107 /*************************************************************************
2108 * GetFontLanguageInfo (GDI.616)
2110 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2111 /* return value 0 is correct for most cases anyway */
2112 FIXME("(%x):stub!\n",hdc);
2116 /*************************************************************************
2117 * GetFontData [GDI32.@] Retrieve data for TrueType font
2121 * success: Number of bytes returned
2122 * failure: GDI_ERROR
2126 * Calls SetLastError()
2129 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2130 LPVOID buffer, DWORD length)
2132 DC *dc = DC_GetDCPtr(hdc);
2133 DWORD ret = GDI_ERROR;
2135 if(!dc) return GDI_ERROR;
2138 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2140 GDI_ReleaseObj(hdc);
2144 /*************************************************************************
2145 * GetFontData [GDI.311]
2148 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2149 LPVOID lpvBuffer, DWORD cbData)
2151 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2154 /*************************************************************************
2155 * GetGlyphIndicesA [GDI32.@]
2157 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2158 LPWORD pgi, DWORD flags)
2164 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2165 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2167 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2168 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2169 HeapFree(GetProcessHeap(), 0, lpstrW);
2174 /*************************************************************************
2175 * GetGlyphIndicesW [GDI32.@]
2177 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2178 LPWORD pgi, DWORD flags)
2180 DC *dc = DC_GetDCPtr(hdc);
2181 DWORD ret = GDI_ERROR;
2183 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2184 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2186 if(!dc) return GDI_ERROR;
2189 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2191 GDI_ReleaseObj(hdc);
2195 /*************************************************************************
2196 * GetCharacterPlacementA [GDI32.@]
2199 * the web browser control of ie4 calls this with dwFlags=0
2202 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2203 INT nMaxExtent, GCP_RESULTSA *lpResults,
2208 GCP_RESULTSW resultsW;
2212 TRACE("%s, %d, %d, 0x%08lx\n",
2213 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2215 /* both structs are equal in size */
2216 memcpy(&resultsW, lpResults, sizeof(resultsW));
2218 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2219 if(lpResults->lpOutString)
2220 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2222 resultsW.lpOutString = NULL;
2224 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2226 if(lpResults->lpOutString)
2227 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2228 lpResults->lpOutString, uCount, NULL, NULL );
2230 HeapFree(GetProcessHeap(), 0, lpStringW);
2231 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2236 /*************************************************************************
2237 * GetCharacterPlacementW [GDI32.@]
2240 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2241 INT nMaxExtent, GCP_RESULTSW *lpResults,
2248 TRACE("%s, %d, %d, 0x%08lx\n",
2249 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2251 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2252 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2253 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2254 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2255 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2257 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2258 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2259 if(lpResults->lpClass) FIXME("classes not implemented\n");
2261 /* FIXME: reordering not implemented */
2262 /* copy will do if the GCP_REORDER flag is not set */
2263 if(lpResults->lpOutString)
2264 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2266 nSet = (UINT)uCount;
2267 if(nSet > lpResults->nGlyphs)
2268 nSet = lpResults->nGlyphs;
2270 /* return number of initialized fields */
2271 lpResults->nGlyphs = nSet;
2273 if(lpResults->lpOrder)
2275 for(i = 0; i < nSet; i++)
2276 lpResults->lpOrder[i] = i;
2279 if (lpResults->lpDx)
2282 for (i = 0; i < nSet; i++)
2284 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2285 lpResults->lpDx[i]= c;
2289 if(lpResults->lpGlyphs)
2290 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2292 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2293 ret = MAKELONG(size.cx, size.cy);
2298 /*************************************************************************
2299 * GetCharABCWidthsFloatA [GDI32.@]
2301 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2304 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2308 /*************************************************************************
2309 * GetCharABCWidthsFloatW [GDI32.@]
2311 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2312 UINT iLastChar, LPABCFLOAT lpABCF)
2314 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2318 /*************************************************************************
2319 * GetCharWidthFloatA [GDI32.@]
2321 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2322 UINT iLastChar, PFLOAT pxBuffer)
2324 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2328 /*************************************************************************
2329 * GetCharWidthFloatW [GDI32.@]
2331 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2332 UINT iLastChar, PFLOAT pxBuffer)
2334 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2339 /***********************************************************************
2341 * Font Resource API *
2343 ***********************************************************************/
2344 /***********************************************************************
2345 * AddFontResource (GDI.119)
2347 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2349 * FIXME: Load header and find the best-matching font in the fontList;
2350 * fixup dfPoints if all metrics are identical, otherwise create
2351 * new fontAlias. When soft font support is ready this will
2352 * simply create a new fontResource ('filename' will go into
2353 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2356 INT16 WINAPI AddFontResource16( LPCSTR filename )
2358 return AddFontResourceA( filename );
2362 /***********************************************************************
2363 * AddFontResourceA (GDI32.@)
2365 INT WINAPI AddFontResourceA( LPCSTR str )
2367 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2368 "this font manually.\n", debugstr_a(str));
2373 /***********************************************************************
2374 * AddFontResourceW (GDI32.@)
2376 INT WINAPI AddFontResourceW( LPCWSTR str )
2378 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2379 "this font manually.\n", debugstr_w(str));
2383 /***********************************************************************
2384 * RemoveFontResource (GDI.136)
2386 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2388 FIXME("(%s): stub\n", debugstr_a(str));
2393 /***********************************************************************
2394 * RemoveFontResourceA (GDI32.@)
2396 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2398 /* This is how it should look like */
2400 fontResource** ppfr;
2401 BOOL32 retVal = FALSE;
2403 EnterCriticalSection( &crtsc_fonts_X11 );
2404 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2405 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2407 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2408 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2410 if( (*ppfr)->fo_count )
2411 (*ppfr)->fr_flags |= FR_REMOVED;
2413 XFONT_RemoveFontResource( ppfr );
2417 LeaveCriticalSection( &crtsc_fonts_X11 );
2420 FIXME("(%s): stub\n", debugstr_a(str));
2425 /***********************************************************************
2426 * RemoveFontResourceW (GDI32.@)
2428 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2430 FIXME("(%s): stub\n", debugstr_w(str) );