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 { VIETNAMESE_CHARSET, 1258, FS(8)},
102 /* reserved by ANSI */
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 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
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 );
1108 ret = WineEngGetTextFace(dc->gdiFont, count, name);
1109 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1113 lstrcpynW( name, font->logfont.lfFaceName, count );
1114 ret = strlenW(name);
1116 else ret = strlenW(font->logfont.lfFaceName) + 1;
1117 GDI_ReleaseObj( dc->hFont );
1119 GDI_ReleaseObj( hdc );
1124 /***********************************************************************
1125 * GetTextExtent (GDI.91)
1127 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1130 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1131 return MAKELONG( size.cx, size.cy );
1135 /***********************************************************************
1136 * GetTextExtentPoint (GDI.471)
1138 * FIXME: Should this have a bug for compatibility?
1139 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1140 * bugs (-> MSDN KB q147647.txt).
1142 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1147 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1148 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1149 size->cx = size32.cx;
1150 size->cy = size32.cy;
1155 /***********************************************************************
1156 * GetTextExtentPoint32A (GDI32.@)
1158 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1163 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1166 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1167 HeapFree( GetProcessHeap(), 0, p );
1170 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1171 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1176 /***********************************************************************
1177 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1179 * Computes width and height of the specified string.
1185 BOOL WINAPI GetTextExtentPoint32W(
1186 HDC hdc, /* [in] Handle of device context */
1187 LPCWSTR str, /* [in] Address of text string */
1188 INT count, /* [in] Number of characters in string */
1189 LPSIZE size) /* [out] Address of structure for string size */
1192 DC * dc = DC_GetDCPtr( hdc );
1193 if (!dc) return FALSE;
1196 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1197 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1198 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1200 else if(dc->funcs->pGetTextExtentPoint)
1201 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1203 GDI_ReleaseObj( hdc );
1205 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1206 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1210 /***********************************************************************
1211 * GetTextExtentPointI [GDI32.@]
1213 * Computes width and height of the array of glyph indices.
1219 BOOL WINAPI GetTextExtentPointI(
1220 HDC hdc, /* [in] Handle of device context */
1221 const WORD *indices, /* [in] Address of glyph index array */
1222 INT count, /* [in] Number of glyphs in array */
1223 LPSIZE size) /* [out] Address of structure for string size */
1226 DC * dc = DC_GetDCPtr( hdc );
1227 if (!dc) return FALSE;
1230 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1231 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1232 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1234 else if(dc->funcs->pGetTextExtentPoint) {
1235 FIXME("calling GetTextExtentPoint\n");
1236 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1239 GDI_ReleaseObj( hdc );
1241 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1242 hdc, indices, count, size, size->cx, size->cy );
1247 /***********************************************************************
1248 * GetTextExtentPointA (GDI32.@)
1250 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1253 TRACE("not bug compatible.\n");
1254 return GetTextExtentPoint32A( hdc, str, count, size );
1257 /***********************************************************************
1258 * GetTextExtentPointW (GDI32.@)
1260 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1263 TRACE("not bug compatible.\n");
1264 return GetTextExtentPoint32W( hdc, str, count, size );
1268 /***********************************************************************
1269 * GetTextExtentExPointA (GDI32.@)
1271 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1272 INT maxExt, LPINT lpnFit,
1273 LPINT alpDx, LPSIZE size )
1277 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1278 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1279 HeapFree( GetProcessHeap(), 0, p );
1284 /***********************************************************************
1285 * GetTextExtentExPointW (GDI32.@)
1287 * Return the size of the string as it would be if it was output properly by
1290 * This should include
1291 * - Intercharacter spacing
1292 * - justification spacing (not yet done)
1293 * - kerning? see below
1295 * Kerning. Since kerning would be carried out by the rendering code it should
1296 * be done by the driver. However they don't support it yet. Also I am not
1297 * yet persuaded that (certainly under Win95) any kerning is actually done.
1299 * str: According to MSDN this should be null-terminated. That is not true; a
1300 * null will not terminate it early.
1301 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1302 * than count. I have seen it be either the size of the full string or
1303 * 1 less than the size of the full string. I have not seen it bear any
1304 * resemblance to the portion that would fit.
1305 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1306 * trailing intercharacter spacing and any trailing justification.
1309 * Currently we do this by measuring each character etc. We should do it by
1310 * passing the request to the driver, perhaps by extending the
1311 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1312 * thinking about kerning issues and rounding issues in the justification.
1315 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1316 INT maxExt, LPINT lpnFit,
1317 LPINT alpDx, LPSIZE size )
1319 int index, nFit, extent;
1323 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1325 size->cx = size->cy = nFit = extent = 0;
1326 for(index = 0; index < count; index++)
1328 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1329 /* GetTextExtentPoint includes intercharacter spacing. */
1330 /* FIXME - justification needs doing yet. Remember that the base
1331 * data will not be in logical coordinates.
1334 if( !lpnFit || extent <= maxExt )
1335 /* It is allowed to be equal. */
1338 if( alpDx ) alpDx[index] = extent;
1340 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1344 if(lpnFit) *lpnFit = nFit;
1347 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1353 /***********************************************************************
1354 * GetTextMetrics (GDI.93)
1356 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1360 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1361 FONT_TextMetricWTo16( &tm32, metrics );
1366 /***********************************************************************
1367 * GetTextMetricsA (GDI32.@)
1369 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1373 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1374 FONT_TextMetricWToA( &tm32, metrics );
1378 /***********************************************************************
1379 * GetTextMetricsW (GDI32.@)
1381 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1384 DC * dc = DC_GetDCPtr( hdc );
1385 if (!dc) return FALSE;
1388 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1389 else if (dc->funcs->pGetTextMetrics)
1390 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1394 /* device layer returns values in device units
1395 * therefore we have to convert them to logical */
1397 #define WDPTOLP(x) ((x<0)? \
1398 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1399 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1400 #define HDPTOLP(y) ((y<0)? \
1401 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1402 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1404 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1405 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1406 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1407 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1408 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1409 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1410 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1411 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1414 TRACE("text metrics:\n"
1415 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1416 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1417 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1418 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1419 " PitchAndFamily = %02x\n"
1420 " --------------------\n"
1421 " InternalLeading = %li\n"
1425 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1426 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1427 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1428 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1429 metrics->tmPitchAndFamily,
1430 metrics->tmInternalLeading,
1433 metrics->tmHeight );
1435 GDI_ReleaseObj( hdc );
1440 /***********************************************************************
1441 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1444 * lpOTM should be LPOUTLINETEXTMETRIC
1447 * Success: Non-zero or size of required buffer
1450 UINT16 WINAPI GetOutlineTextMetrics16(
1451 HDC16 hdc, /* [in] Handle of device context */
1452 UINT16 cbData, /* [in] Size of metric data array */
1453 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1455 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1460 /***********************************************************************
1461 * GetOutlineTextMetricsA (GDI32.@)
1462 * Gets metrics for TrueType fonts.
1466 * Success: Non-zero or size of required buffer
1469 UINT WINAPI GetOutlineTextMetricsA(
1470 HDC hdc, /* [in] Handle of device context */
1471 UINT cbData, /* [in] Size of metric data array */
1472 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1474 char buf[512], *ptr;
1476 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1479 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1480 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1482 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1483 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1486 needed = sizeof(OUTLINETEXTMETRICA);
1487 if(lpOTMW->otmpFamilyName)
1488 needed += WideCharToMultiByte(CP_ACP, 0,
1489 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1490 NULL, 0, NULL, NULL);
1491 if(lpOTMW->otmpFaceName)
1492 needed += WideCharToMultiByte(CP_ACP, 0,
1493 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1494 NULL, 0, NULL, NULL);
1495 if(lpOTMW->otmpStyleName)
1496 needed += WideCharToMultiByte(CP_ACP, 0,
1497 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1498 NULL, 0, NULL, NULL);
1499 if(lpOTMW->otmpFullName)
1500 needed += WideCharToMultiByte(CP_ACP, 0,
1501 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1502 NULL, 0, NULL, NULL);
1509 if(needed > cbData) {
1515 lpOTM->otmSize = needed;
1516 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1517 lpOTM->otmFiller = 0;
1518 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1519 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1520 lpOTM->otmfsType = lpOTMW->otmfsType;
1521 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1522 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1523 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1524 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1525 lpOTM->otmAscent = lpOTMW->otmAscent;
1526 lpOTM->otmDescent = lpOTMW->otmDescent;
1527 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1528 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1529 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1530 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1531 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1532 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1533 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1534 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1535 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1536 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1537 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1538 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1539 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1540 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1541 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1542 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1545 ptr = (char*)(lpOTM + 1);
1546 left = needed - sizeof(*lpOTM);
1548 if(lpOTMW->otmpFamilyName) {
1549 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1550 len = WideCharToMultiByte(CP_ACP, 0,
1551 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1552 ptr, left, NULL, NULL);
1556 lpOTM->otmpFamilyName = 0;
1558 if(lpOTMW->otmpFaceName) {
1559 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1560 len = WideCharToMultiByte(CP_ACP, 0,
1561 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1562 ptr, left, NULL, NULL);
1566 lpOTM->otmpFaceName = 0;
1568 if(lpOTMW->otmpStyleName) {
1569 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1570 len = WideCharToMultiByte(CP_ACP, 0,
1571 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1572 ptr, left, NULL, NULL);
1576 lpOTM->otmpStyleName = 0;
1578 if(lpOTMW->otmpFullName) {
1579 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1580 len = WideCharToMultiByte(CP_ACP, 0,
1581 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1582 ptr, left, NULL, NULL);
1585 lpOTM->otmpFullName = 0;
1592 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1593 HeapFree(GetProcessHeap(), 0, lpOTMW);
1599 /***********************************************************************
1600 * GetOutlineTextMetricsW [GDI32.@]
1602 UINT WINAPI GetOutlineTextMetricsW(
1603 HDC hdc, /* [in] Handle of device context */
1604 UINT cbData, /* [in] Size of metric data array */
1605 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1607 DC *dc = DC_GetDCPtr( hdc );
1610 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1614 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1616 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1617 but really this should just be a return 0. */
1619 ret = sizeof(*lpOTM);
1624 memset(lpOTM, 0, ret);
1625 lpOTM->otmSize = sizeof(*lpOTM);
1626 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1628 Further fill of the structure not implemented,
1629 Needs real values for the structure members
1634 GDI_ReleaseObj(hdc);
1639 /***********************************************************************
1640 * GetCharWidth (GDI.350)
1642 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1645 BOOL retVal = FALSE;
1647 if( firstChar != lastChar )
1649 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1650 sizeof(INT)*(1 + (lastChar - firstChar)));
1653 LPINT obuf32 = buf32;
1656 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1659 for (i = firstChar; i <= lastChar; i++)
1660 *buffer++ = *buf32++;
1662 HeapFree(GetProcessHeap(), 0, obuf32);
1665 else /* happens quite often to warrant a special treatment */
1668 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1675 /***********************************************************************
1676 * GetCharWidthW (GDI32.@)
1677 * GetCharWidth32W (GDI32.@)
1679 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1684 DC * dc = DC_GetDCPtr( hdc );
1685 if (!dc) return FALSE;
1688 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1689 else if (dc->funcs->pGetCharWidth)
1690 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1694 /* convert device units to logical */
1696 extra = dc->vportExtX >> 1;
1697 for( i = firstChar; i <= lastChar; i++, buffer++ )
1698 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1701 GDI_ReleaseObj( hdc );
1706 /***********************************************************************
1707 * GetCharWidthA (GDI32.@)
1708 * GetCharWidth32A (GDI32.@)
1710 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1713 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1718 if(count <= 0) return FALSE;
1720 str = HeapAlloc(GetProcessHeap(), 0, count);
1721 for(i = 0; i < count; i++)
1722 str[i] = (BYTE)(firstChar + i);
1724 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1726 for(i = 0; i < wlen; i++)
1728 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1736 HeapFree(GetProcessHeap(), 0, str);
1737 HeapFree(GetProcessHeap(), 0, wstr);
1743 /* FIXME: all following APIs ******************************************/
1746 /***********************************************************************
1747 * SetMapperFlags (GDI.349)
1749 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1751 return SetMapperFlags( hDC, dwFlag );
1755 /***********************************************************************
1756 * SetMapperFlags (GDI32.@)
1758 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1760 DC *dc = DC_GetDCPtr( hDC );
1763 if(dc->funcs->pSetMapperFlags)
1764 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1766 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1767 GDI_ReleaseObj( hDC );
1771 /***********************************************************************
1772 * GetAspectRatioFilterEx (GDI.486)
1774 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1776 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1780 /***********************************************************************
1781 * GetAspectRatioFilterEx (GDI32.@)
1783 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1785 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1789 /***********************************************************************
1790 * GetCharABCWidths (GDI.307)
1792 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1795 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1798 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1799 HeapFree(GetProcessHeap(),0,abc32);
1803 for (i=firstChar;i<=lastChar;i++) {
1804 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1805 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1806 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1808 HeapFree(GetProcessHeap(),0,abc32);
1813 /***********************************************************************
1814 * GetCharABCWidthsA (GDI32.@)
1816 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1819 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1824 if(count <= 0) return FALSE;
1826 str = HeapAlloc(GetProcessHeap(), 0, count);
1827 for(i = 0; i < count; i++)
1828 str[i] = (BYTE)(firstChar + i);
1830 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1832 for(i = 0; i < wlen; i++)
1834 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1842 HeapFree(GetProcessHeap(), 0, str);
1843 HeapFree(GetProcessHeap(), 0, wstr);
1849 /******************************************************************************
1850 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1853 * hdc [I] Handle of device context
1854 * firstChar [I] First character in range to query
1855 * lastChar [I] Last character in range to query
1856 * abc [O] Address of character-width structure
1859 * Only works with TrueType fonts
1865 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1868 DC *dc = DC_GetDCPtr(hdc);
1874 for (i=firstChar;i<=lastChar;i++) {
1875 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1876 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1877 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1878 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1882 GDI_ReleaseObj(hdc);
1887 /***********************************************************************
1888 * GetGlyphOutline (GDI.309)
1890 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1891 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1892 LPVOID lpBuffer, const MAT2 *lpmat2 )
1894 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1895 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1896 return (DWORD)-1; /* failure */
1900 /***********************************************************************
1901 * GetGlyphOutlineA (GDI32.@)
1903 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1904 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1905 LPVOID lpBuffer, const MAT2 *lpmat2 )
1911 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1912 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1916 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1919 HeapFree(GetProcessHeap(), 0, p);
1923 /***********************************************************************
1924 * GetGlyphOutlineW (GDI32.@)
1926 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1927 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1928 LPVOID lpBuffer, const MAT2 *lpmat2 )
1930 DC *dc = DC_GetDCPtr(hdc);
1933 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1934 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1936 if(!dc) return GDI_ERROR;
1939 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1940 cbBuffer, lpBuffer, lpmat2);
1944 GDI_ReleaseObj(hdc);
1948 /***********************************************************************
1949 * CreateScalableFontResource (GDI.310)
1951 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1952 LPCSTR lpszResourceFile,
1953 LPCSTR fontFile, LPCSTR path )
1955 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1959 /***********************************************************************
1960 * CreateScalableFontResourceA (GDI32.@)
1962 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1963 LPCSTR lpszResourceFile,
1964 LPCSTR lpszFontFile,
1965 LPCSTR lpszCurrentPath )
1967 /* fHidden=1 - only visible for the calling app, read-only, not
1968 * enumbered with EnumFonts/EnumFontFamilies
1969 * lpszCurrentPath can be NULL
1971 FIXME("(%ld,%s,%s,%s): stub\n",
1972 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1973 debugstr_a(lpszCurrentPath) );
1974 return FALSE; /* create failed */
1977 /***********************************************************************
1978 * CreateScalableFontResourceW (GDI32.@)
1980 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1981 LPCWSTR lpszResourceFile,
1982 LPCWSTR lpszFontFile,
1983 LPCWSTR lpszCurrentPath )
1985 FIXME("(%ld,%p,%p,%p): stub\n",
1986 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1987 return FALSE; /* create failed */
1991 /*************************************************************************
1992 * GetRasterizerCaps (GDI.313)
1994 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1996 return GetRasterizerCaps( lprs, cbNumBytes );
2000 /*************************************************************************
2001 * GetRasterizerCaps (GDI32.@)
2003 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2005 lprs->nSize = sizeof(RASTERIZER_STATUS);
2006 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2007 lprs->nLanguageID = 0;
2012 /*************************************************************************
2013 * GetKerningPairs (GDI.332)
2016 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
2017 LPKERNINGPAIR16 lpKerningPairs )
2019 /* At this time kerning is ignored (set to 0) */
2021 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2023 for (i = 0; i < cPairs; i++)
2024 lpKerningPairs[i].iKernAmount = 0;
2025 /* FIXME: Should this function call SetLastError (0)? This is yet another
2026 * Microsoft function that can return 0 on success or failure
2033 /*************************************************************************
2034 * GetKerningPairsA (GDI32.@)
2036 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2037 LPKERNINGPAIR lpKerningPairs )
2040 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2041 for (i = 0; i < cPairs; i++)
2042 lpKerningPairs[i].iKernAmount = 0;
2047 /*************************************************************************
2048 * GetKerningPairsW (GDI32.@)
2050 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2051 LPKERNINGPAIR lpKerningPairs )
2053 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
2056 /*************************************************************************
2057 * TranslateCharsetInfo [GDI32.@]
2058 * TranslateCharsetInfo [USER32.@]
2060 * Fills a CHARSETINFO structure for a character set, code page, or
2061 * font. This allows making the correspondance between different labelings
2062 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2063 * of the same encoding.
2065 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2066 * only one codepage should be set in *lpSrc.
2069 * TRUE on success, FALSE on failure.
2072 BOOL WINAPI TranslateCharsetInfo(
2073 LPDWORD lpSrc, /* [in]
2074 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2075 if flags == TCI_SRCCHARSET: a character set value
2076 if flags == TCI_SRCCODEPAGE: a code page value
2078 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2079 DWORD flags /* [in] determines interpretation of lpSrc */
2083 case TCI_SRCFONTSIG:
2084 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2086 case TCI_SRCCODEPAGE:
2087 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2089 case TCI_SRCCHARSET:
2090 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2095 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2096 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2100 /*************************************************************************
2101 * GetFontLanguageInfo (GDI32.@)
2103 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
2105 FONTSIGNATURE fontsig;
2106 static const DWORD GCP_DBCS_MASK=0x003F0000,
2107 GCP_DIACRITIC_MASK=0x00000000,
2108 FLI_GLYPHS_MASK=0x00000000,
2109 GCP_GLYPHSHAPE_MASK=0x00000040,
2110 GCP_KASHIDA_MASK=0x00000000,
2111 GCP_LIGATE_MASK=0x00000000,
2112 GCP_USEKERNING_MASK=0x00000000,
2113 GCP_REORDER_MASK=0x00000060;
2117 GetTextCharsetInfo( hdc, &fontsig, 0 );
2118 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
2120 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
2123 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
2124 result|=GCP_DIACRITIC;
2126 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
2129 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
2130 result|=GCP_GLYPHSHAPE;
2132 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
2133 result|=GCP_KASHIDA;
2135 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
2138 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
2139 result|=GCP_USEKERNING;
2141 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
2142 result|=GCP_REORDER;
2147 /*************************************************************************
2148 * GetFontLanguageInfo (GDI.616)
2150 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2151 /* return value 0 is correct for most cases anyway */
2152 FIXME("(%x):stub!\n",hdc);
2156 /*************************************************************************
2157 * GetFontData [GDI32.@] Retrieve data for TrueType font
2161 * success: Number of bytes returned
2162 * failure: GDI_ERROR
2166 * Calls SetLastError()
2169 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2170 LPVOID buffer, DWORD length)
2172 DC *dc = DC_GetDCPtr(hdc);
2173 DWORD ret = GDI_ERROR;
2175 if(!dc) return GDI_ERROR;
2178 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2180 GDI_ReleaseObj(hdc);
2184 /*************************************************************************
2185 * GetFontData [GDI.311]
2188 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2189 LPVOID lpvBuffer, DWORD cbData)
2191 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2194 /*************************************************************************
2195 * GetGlyphIndicesA [GDI32.@]
2197 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2198 LPWORD pgi, DWORD flags)
2204 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2205 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2207 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2208 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2209 HeapFree(GetProcessHeap(), 0, lpstrW);
2214 /*************************************************************************
2215 * GetGlyphIndicesW [GDI32.@]
2217 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2218 LPWORD pgi, DWORD flags)
2220 DC *dc = DC_GetDCPtr(hdc);
2221 DWORD ret = GDI_ERROR;
2223 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2224 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2226 if(!dc) return GDI_ERROR;
2229 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2231 GDI_ReleaseObj(hdc);
2235 /*************************************************************************
2236 * GetCharacterPlacementA [GDI32.@]
2239 * the web browser control of ie4 calls this with dwFlags=0
2242 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2243 INT nMaxExtent, GCP_RESULTSA *lpResults,
2248 GCP_RESULTSW resultsW;
2252 TRACE("%s, %d, %d, 0x%08lx\n",
2253 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2255 /* both structs are equal in size */
2256 memcpy(&resultsW, lpResults, sizeof(resultsW));
2258 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2259 if(lpResults->lpOutString)
2260 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2262 resultsW.lpOutString = NULL;
2264 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2266 if(lpResults->lpOutString) {
2267 if(font_cp != CP_SYMBOL)
2268 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2269 lpResults->lpOutString, uCount, NULL, NULL );
2271 for(i = 0; i < uCount; i++)
2272 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
2275 HeapFree(GetProcessHeap(), 0, lpStringW);
2276 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2281 /*************************************************************************
2282 * GetCharacterPlacementW [GDI32.@]
2284 * Retrieve information about a string. This includes the width, reordering,
2285 * Glyphing and so on.
2289 * The width and height of the string if succesful, 0 if failed.
2293 * All flags except GCP_REORDER are not yet implemented.
2294 * Reordering is not 100% complient to the Windows BiDi method.
2295 * Caret positioning is not yet implemented.
2296 * Classes are not yet implemented.
2300 GetCharacterPlacementW(
2301 HDC hdc, /* Device context for which the rendering is to be done */
2302 LPCWSTR lpString, /* The string for which information is to be returned */
2303 INT uCount, /* Number of WORDS in string. */
2304 INT nMaxExtent, /* Maximum extent the string is to take (in HDC logical units) */
2305 GCP_RESULTSW *lpResults, /* A pointer to a GCP_RESULTSW struct */
2306 DWORD dwFlags /* Flags specifying how to process the string */
2313 TRACE("%s, %d, %d, 0x%08lx\n",
2314 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2316 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2317 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2318 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2319 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2320 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2322 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2323 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2324 if(lpResults->lpClass) FIXME("classes not implemented\n");
2326 nSet = (UINT)uCount;
2327 if(nSet > lpResults->nGlyphs)
2328 nSet = lpResults->nGlyphs;
2330 /* return number of initialized fields */
2331 lpResults->nGlyphs = nSet;
2335 /* Treat the case where no special handling was requested in a fastpath way */
2336 /* copy will do if the GCP_REORDER flag is not set */
2337 if(lpResults->lpOutString)
2338 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2340 if(lpResults->lpOrder)
2342 for(i = 0; i < nSet; i++)
2343 lpResults->lpOrder[i] = i;
2350 /* Keep a static table that translates the C2 types to something meaningful */
2351 /* 1 - left to right
2352 * -1 - right to left
2355 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
2357 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2358 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
2360 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2365 /* Fill in the order array with directionality values */
2366 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2368 /* The complete and correct (at list according to MS) BiDi algorythm is not
2369 * yet implemented here. Instead, we just make sure that consecutive runs of
2370 * the same direction (or neutral) are ordered correctly
2372 for( i=0; i<uCount; i+=run_end )
2374 for( run_end=1; i+run_end<uCount &&
2375 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2376 chardir[pwCharType[i+run_end]]==0); ++run_end )
2379 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2382 if(lpResults->lpOutString)
2385 for( j=0; j<run_end; j++ )
2387 lpResults->lpOutString[i+j]=lpString[i+j];
2391 if(lpResults->lpOrder)
2394 for( j=0; j<run_end; j++ )
2395 lpResults->lpOrder[i+j] = i+j;
2400 if(lpResults->lpOutString)
2403 for( j=0; j<run_end; j++ )
2405 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2409 if(lpResults->lpOrder)
2412 for( j=0; j<run_end; j++ )
2413 lpResults->lpOrder[i+j] = i+run_end-j-1;
2418 HeapFree(GetProcessHeap(), 0, pwCharType);
2421 /* FIXME: Will use the placement chars */
2422 if (lpResults->lpDx)
2425 for (i = 0; i < nSet; i++)
2427 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2428 lpResults->lpDx[i]= c;
2432 if(lpResults->lpGlyphs)
2433 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2435 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2436 ret = MAKELONG(size.cx, size.cy);
2441 /*************************************************************************
2442 * GetCharABCWidthsFloatA [GDI32.@]
2444 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2447 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2451 /*************************************************************************
2452 * GetCharABCWidthsFloatW [GDI32.@]
2454 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2455 UINT iLastChar, LPABCFLOAT lpABCF)
2457 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2461 /*************************************************************************
2462 * GetCharWidthFloatA [GDI32.@]
2464 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2465 UINT iLastChar, PFLOAT pxBuffer)
2467 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2471 /*************************************************************************
2472 * GetCharWidthFloatW [GDI32.@]
2474 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2475 UINT iLastChar, PFLOAT pxBuffer)
2477 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2482 /***********************************************************************
2484 * Font Resource API *
2486 ***********************************************************************/
2487 /***********************************************************************
2488 * AddFontResource (GDI.119)
2490 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2493 INT16 WINAPI AddFontResource16( LPCSTR filename )
2495 return AddFontResourceA( filename );
2498 /***********************************************************************
2499 * AddFontResourceA (GDI32.@)
2501 INT WINAPI AddFontResourceA( LPCSTR str )
2503 return AddFontResourceExA( str, 0, NULL);
2506 /***********************************************************************
2507 * AddFontResourceW (GDI32.@)
2509 INT WINAPI AddFontResourceW( LPCWSTR str )
2511 return AddFontResourceExW(str, 0, NULL);
2515 /***********************************************************************
2516 * AddFontResourceExA (GDI32.@)
2518 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2520 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2521 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2524 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2525 ret = AddFontResourceExW(strW, fl, pdv);
2526 HeapFree(GetProcessHeap(), 0, strW);
2530 /***********************************************************************
2531 * AddFontResourceExW (GDI32.@)
2533 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2535 return WineEngAddFontResourceEx(str, fl, pdv);
2538 /***********************************************************************
2539 * RemoveFontResource (GDI.136)
2541 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2543 return RemoveFontResourceA(str);
2546 /***********************************************************************
2547 * RemoveFontResourceA (GDI32.@)
2549 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2551 return RemoveFontResourceExA(str, 0, 0);
2554 /***********************************************************************
2555 * RemoveFontResourceW (GDI32.@)
2557 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2559 return RemoveFontResourceExW(str, 0, 0);
2562 /***********************************************************************
2563 * RemoveFontResourceExA (GDI32.@)
2565 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2567 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2568 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2571 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2572 ret = RemoveFontResourceExW(strW, fl, pdv);
2573 HeapFree(GetProcessHeap(), 0, strW);
2577 /***********************************************************************
2578 * RemoveFontResourceExW (GDI32.@)
2580 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2582 return WineEngRemoveFontResourceEx(str, fl, pdv);