4 * Copyright 1993 Alexandre Julliard
6 * Copyright 2002,2003 Shachar Shemesh
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wine/port.h"
36 #include "wine/unicode.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(font);
40 WINE_DECLARE_DEBUG_CHANNEL(gdi);
42 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
43 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
44 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
45 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
46 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
48 static const struct gdi_obj_funcs font_funcs =
50 FONT_SelectObject, /* pSelectObject */
51 FONT_GetObject16, /* pGetObject16 */
52 FONT_GetObjectA, /* pGetObjectA */
53 FONT_GetObjectW, /* pGetObjectW */
54 NULL, /* pUnrealizeObject */
55 FONT_DeleteObject /* pDeleteObject */
58 #define ENUM_UNICODE 0x00000001
59 #define ENUM_CALLED 0x00000002
69 LPLOGFONT16 lpLogFontParam;
70 FONTENUMPROC16 lpEnumFunc;
73 LPNEWTEXTMETRICEX16 lpTextMetric;
74 LPENUMLOGFONTEX16 lpLogFont;
85 LPLOGFONTW lpLogFontParam;
86 FONTENUMPROCW lpEnumFunc;
95 * For TranslateCharsetInfo
97 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
98 #define MAXTCIINDEX 32
99 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
101 { ANSI_CHARSET, 1252, FS(0)},
102 { EASTEUROPE_CHARSET, 1250, FS(1)},
103 { RUSSIAN_CHARSET, 1251, FS(2)},
104 { GREEK_CHARSET, 1253, FS(3)},
105 { TURKISH_CHARSET, 1254, FS(4)},
106 { HEBREW_CHARSET, 1255, FS(5)},
107 { ARABIC_CHARSET, 1256, FS(6)},
108 { BALTIC_CHARSET, 1257, FS(7)},
109 { VIETNAMESE_CHARSET, 1258, FS(8)},
110 /* reserved by ANSI */
111 { DEFAULT_CHARSET, 0, FS(0)},
112 { DEFAULT_CHARSET, 0, FS(0)},
113 { DEFAULT_CHARSET, 0, FS(0)},
114 { DEFAULT_CHARSET, 0, FS(0)},
115 { DEFAULT_CHARSET, 0, FS(0)},
116 { DEFAULT_CHARSET, 0, FS(0)},
117 { DEFAULT_CHARSET, 0, FS(0)},
119 { THAI_CHARSET, 874, FS(16)},
120 { SHIFTJIS_CHARSET, 932, FS(17)},
121 { GB2312_CHARSET, 936, FS(18)},
122 { HANGEUL_CHARSET, 949, FS(19)},
123 { CHINESEBIG5_CHARSET, 950, FS(20)},
124 { JOHAB_CHARSET, 1361, FS(21)},
125 /* reserved for alternate ANSI and OEM */
126 { DEFAULT_CHARSET, 0, FS(0)},
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
129 { DEFAULT_CHARSET, 0, FS(0)},
130 { DEFAULT_CHARSET, 0, FS(0)},
131 { DEFAULT_CHARSET, 0, FS(0)},
132 { DEFAULT_CHARSET, 0, FS(0)},
133 { DEFAULT_CHARSET, 0, FS(0)},
134 /* reserved for system */
135 { DEFAULT_CHARSET, 0, FS(0)},
136 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
139 /***********************************************************************
140 * LOGFONT conversion functions.
142 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
144 font16->lfHeight = font32->lfHeight;
145 font16->lfWidth = font32->lfWidth;
146 font16->lfEscapement = font32->lfEscapement;
147 font16->lfOrientation = font32->lfOrientation;
148 font16->lfWeight = font32->lfWeight;
149 font16->lfItalic = font32->lfItalic;
150 font16->lfUnderline = font32->lfUnderline;
151 font16->lfStrikeOut = font32->lfStrikeOut;
152 font16->lfCharSet = font32->lfCharSet;
153 font16->lfOutPrecision = font32->lfOutPrecision;
154 font16->lfClipPrecision = font32->lfClipPrecision;
155 font16->lfQuality = font32->lfQuality;
156 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
157 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
158 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
159 font16->lfFaceName[LF_FACESIZE-1] = 0;
162 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
164 font32->lfHeight = font16->lfHeight;
165 font32->lfWidth = font16->lfWidth;
166 font32->lfEscapement = font16->lfEscapement;
167 font32->lfOrientation = font16->lfOrientation;
168 font32->lfWeight = font16->lfWeight;
169 font32->lfItalic = font16->lfItalic;
170 font32->lfUnderline = font16->lfUnderline;
171 font32->lfStrikeOut = font16->lfStrikeOut;
172 font32->lfCharSet = font16->lfCharSet;
173 font32->lfOutPrecision = font16->lfOutPrecision;
174 font32->lfClipPrecision = font16->lfClipPrecision;
175 font32->lfQuality = font16->lfQuality;
176 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
177 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
178 font32->lfFaceName[LF_FACESIZE-1] = 0;
181 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
183 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
184 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
188 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
190 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
191 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
192 LF_FACESIZE, NULL, NULL);
195 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
197 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
200 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
201 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
203 font16->elfStyle, LF_FACESIZE, NULL, NULL );
204 font16->elfStyle[LF_FACESIZE-1] = '\0';
205 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
206 font16->elfScript, LF_FACESIZE, NULL, NULL );
207 font16->elfScript[LF_FACESIZE-1] = '\0';
210 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
212 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
215 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
216 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
218 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
219 fontA->elfStyle[LF_FACESIZE-1] = '\0';
220 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
221 fontA->elfScript, LF_FACESIZE, NULL, NULL );
222 fontA->elfScript[LF_FACESIZE-1] = '\0';
225 /***********************************************************************
226 * TEXTMETRIC conversion functions.
228 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
230 ptmA->tmHeight = ptmW->tmHeight;
231 ptmA->tmAscent = ptmW->tmAscent;
232 ptmA->tmDescent = ptmW->tmDescent;
233 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
234 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
235 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
236 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
237 ptmA->tmWeight = ptmW->tmWeight;
238 ptmA->tmOverhang = ptmW->tmOverhang;
239 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
240 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
241 ptmA->tmFirstChar = ptmW->tmFirstChar > 255 ? 255 : ptmW->tmFirstChar;
242 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
243 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
244 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : ptmW->tmBreakChar;
245 ptmA->tmItalic = ptmW->tmItalic;
246 ptmA->tmUnderlined = ptmW->tmUnderlined;
247 ptmA->tmStruckOut = ptmW->tmStruckOut;
248 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
249 ptmA->tmCharSet = ptmW->tmCharSet;
253 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
255 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
256 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
257 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
258 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
259 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
260 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
261 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
262 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
263 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
264 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
265 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
266 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
267 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
268 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
269 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
270 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
271 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
272 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
273 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
274 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
275 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
276 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
277 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
278 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
279 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
282 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
284 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
285 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
286 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
287 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
288 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
289 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
292 /***********************************************************************
293 * CreateFontIndirectA (GDI32.@)
295 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
300 FONT_LogFontAToW( plfA, &lfW );
301 return CreateFontIndirectW( &lfW );
303 return CreateFontIndirectW( NULL );
307 /***********************************************************************
308 * CreateFontIndirectW (GDI32.@)
310 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
317 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
318 (HGDIOBJ *)&hFont, &font_funcs )))
320 static const WCHAR ItalicW[] = {' ','I','t','a','l','i','c','\0'};
321 static const WCHAR BoldW[] = {' ','B','o','l','d','\0'};
322 WCHAR *pFaceNameItalicSuffix, *pFaceNameBoldSuffix;
323 WCHAR* pFaceNameSuffix = NULL;
325 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
327 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
328 plf->lfHeight, plf->lfWidth,
329 plf->lfEscapement, plf->lfOrientation,
330 plf->lfPitchAndFamily,
331 plf->lfOutPrecision, plf->lfClipPrecision,
332 plf->lfQuality, plf->lfCharSet,
333 debugstr_w(plf->lfFaceName),
334 plf->lfWeight > 400 ? "Bold" : "",
335 plf->lfItalic ? "Italic" : "", hFont);
337 if (plf->lfEscapement != plf->lfOrientation) {
338 /* this should really depend on whether GM_ADVANCED is set */
339 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
340 WARN("orientation angle %f set to "
341 "escapement angle %f for new font %p\n",
342 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
345 pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
346 if (pFaceNameItalicSuffix) {
347 fontPtr->logfont.lfItalic = TRUE;
348 pFaceNameSuffix = pFaceNameItalicSuffix;
351 pFaceNameBoldSuffix = strstrW(fontPtr->logfont.lfFaceName, BoldW);
352 if (pFaceNameBoldSuffix) {
353 if (fontPtr->logfont.lfWeight < FW_BOLD) {
354 fontPtr->logfont.lfWeight = FW_BOLD;
356 if (!pFaceNameSuffix ||
357 (pFaceNameBoldSuffix < pFaceNameSuffix)) {
358 pFaceNameSuffix = pFaceNameBoldSuffix;
362 if (pFaceNameSuffix) *pFaceNameSuffix = 0;
364 GDI_ReleaseObj( hFont );
367 else WARN("(NULL) => NULL\n");
372 /*************************************************************************
373 * CreateFontA (GDI32.@)
375 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
376 INT orient, INT weight, DWORD italic,
377 DWORD underline, DWORD strikeout, DWORD charset,
378 DWORD outpres, DWORD clippres, DWORD quality,
379 DWORD pitch, LPCSTR name )
383 logfont.lfHeight = height;
384 logfont.lfWidth = width;
385 logfont.lfEscapement = esc;
386 logfont.lfOrientation = orient;
387 logfont.lfWeight = weight;
388 logfont.lfItalic = italic;
389 logfont.lfUnderline = underline;
390 logfont.lfStrikeOut = strikeout;
391 logfont.lfCharSet = charset;
392 logfont.lfOutPrecision = outpres;
393 logfont.lfClipPrecision = clippres;
394 logfont.lfQuality = quality;
395 logfont.lfPitchAndFamily = pitch;
398 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
400 logfont.lfFaceName[0] = '\0';
402 return CreateFontIndirectA( &logfont );
405 /*************************************************************************
406 * CreateFontW (GDI32.@)
408 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
409 INT orient, INT weight, DWORD italic,
410 DWORD underline, DWORD strikeout, DWORD charset,
411 DWORD outpres, DWORD clippres, DWORD quality,
412 DWORD pitch, LPCWSTR name )
416 logfont.lfHeight = height;
417 logfont.lfWidth = width;
418 logfont.lfEscapement = esc;
419 logfont.lfOrientation = orient;
420 logfont.lfWeight = weight;
421 logfont.lfItalic = italic;
422 logfont.lfUnderline = underline;
423 logfont.lfStrikeOut = strikeout;
424 logfont.lfCharSet = charset;
425 logfont.lfOutPrecision = outpres;
426 logfont.lfClipPrecision = clippres;
427 logfont.lfQuality = quality;
428 logfont.lfPitchAndFamily = pitch;
431 lstrcpynW(logfont.lfFaceName, name,
432 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
434 logfont.lfFaceName[0] = '\0';
436 return CreateFontIndirectW( &logfont );
440 /***********************************************************************
443 * If the driver supports vector fonts we create a gdi font first and
444 * then call the driver to give it a chance to supply its own device
445 * font. If the driver wants to do this it returns TRUE and we can
446 * delete the gdi font, if the driver wants to use the gdi font it
447 * should return FALSE, to signal an error return GDI_ERROR. For
448 * drivers that don't support vector fonts they must supply their own
451 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
454 DC *dc = DC_GetDCPtr( hdc );
458 if (dc->hFont != handle || dc->gdiFont == NULL)
460 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
461 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
464 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
466 if (ret && dc->gdiFont) dc->gdiFont = 0;
468 if (ret == HGDI_ERROR)
469 ret = 0; /* SelectObject returns 0 on error */
475 GDI_ReleaseObj( hdc );
480 /***********************************************************************
483 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
488 FONT_LogFontWTo16( &font->logfont, &lf16 );
490 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
491 memcpy( buffer, &lf16, count );
495 /***********************************************************************
498 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
505 FONT_LogFontWToA( &font->logfont, &lfA );
507 if (count > sizeof(lfA)) count = sizeof(lfA);
508 memcpy( buffer, &lfA, count );
512 /***********************************************************************
515 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
519 return sizeof(LOGFONTW);
520 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
521 memcpy( buffer, &font->logfont, count );
526 /***********************************************************************
529 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
531 WineEngDestroyFontInstance( handle );
532 return GDI_FreeObject( handle, obj );
536 /***********************************************************************
537 * FONT_EnumInstance16
539 * Called by the device driver layer to pass font info
540 * down to the application.
542 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
543 DWORD fType, LPARAM lp )
545 fontEnum16 *pfe = (fontEnum16*)lp;
549 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
550 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
555 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
556 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
557 pfe->dwFlags |= ENUM_CALLED;
558 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
560 args[6] = SELECTOROF(pfe->segLogFont);
561 args[5] = OFFSETOF(pfe->segLogFont);
562 args[4] = SELECTOROF(pfe->segTextMetric);
563 args[3] = OFFSETOF(pfe->segTextMetric);
565 args[1] = HIWORD(pfe->lpData);
566 args[0] = LOWORD(pfe->lpData);
567 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
568 ret = LOWORD(result);
570 /* get the lock again and make sure the DC is still valid */
571 dc = DC_GetDCPtr( pfe->hdc );
572 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
574 if (dc) GDI_ReleaseObj( pfe->hdc );
575 pfe->hdc = 0; /* make sure we don't try to release it later on */
582 /***********************************************************************
585 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
586 DWORD fType, LPARAM lp )
588 fontEnum32 *pfe = (fontEnum32*)lp;
592 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
593 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
594 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
596 /* convert font metrics */
597 ENUMLOGFONTEXA logfont;
598 NEWTEXTMETRICEXA tmA;
600 pfe->dwFlags |= ENUM_CALLED;
601 if (!(pfe->dwFlags & ENUM_UNICODE))
603 FONT_EnumLogFontExWToA( plf, &logfont);
604 FONT_NewTextMetricExWToA( ptm, &tmA );
605 plf = (LPENUMLOGFONTEXW)&logfont;
606 ptm = (NEWTEXTMETRICEXW *)&tmA;
608 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
610 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
612 /* get the lock again and make sure the DC is still valid */
613 dc = DC_GetDCPtr( pfe->hdc );
614 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
616 if (dc) GDI_ReleaseObj( pfe->hdc );
617 pfe->hdc = 0; /* make sure we don't try to release it later on */
624 /***********************************************************************
625 * EnumFontFamiliesEx (GDI.613)
627 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
628 FONTENUMPROC16 efproc, LPARAM lParam,
633 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
634 NEWTEXTMETRICEX16 tm16;
635 ENUMLOGFONTEX16 lf16;
640 FONT_LogFont16ToW(plf, &lfW);
642 fe16.hdc = HDC_32(hDC);
644 fe16.physDev = dc->physDev;
645 fe16.lpLogFontParam = plf;
646 fe16.lpEnumFunc = efproc;
647 fe16.lpData = lParam;
648 fe16.lpTextMetric = &tm16;
649 fe16.lpLogFont = &lf16;
650 fe16.segTextMetric = MapLS( &tm16 );
651 fe16.segLogFont = MapLS( &lf16 );
654 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
656 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
663 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
664 fe16.dwFlags &= ~ENUM_CALLED;
665 if (ret && dc->funcs->pEnumDeviceFonts) {
666 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
667 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
671 UnMapLS( fe16.segTextMetric );
672 UnMapLS( fe16.segLogFont );
673 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
677 /***********************************************************************
678 * FONT_EnumFontFamiliesEx
680 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
681 FONTENUMPROCW efproc,
682 LPARAM lParam, DWORD dwUnicode)
685 DC *dc = DC_GetDCPtr( hDC );
691 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
693 fe32.lpLogFontParam = plf;
694 fe32.lpEnumFunc = efproc;
695 fe32.lpData = lParam;
696 fe32.dwFlags = dwUnicode;
699 fe32.physDev = dc->physDev;
701 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
703 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
710 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
711 fe32.dwFlags &= ~ENUM_CALLED;
712 if (ret && dc->funcs->pEnumDeviceFonts) {
713 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
714 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
718 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
722 /***********************************************************************
723 * EnumFontFamiliesExW (GDI32.@)
725 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
726 FONTENUMPROCW efproc,
727 LPARAM lParam, DWORD dwFlags )
729 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
732 /***********************************************************************
733 * EnumFontFamiliesExA (GDI32.@)
735 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
736 FONTENUMPROCA efproc,
737 LPARAM lParam, DWORD dwFlags)
740 FONT_LogFontAToW( plf, &lfW );
742 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
745 /***********************************************************************
746 * EnumFontFamilies (GDI.330)
748 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
749 FONTENUMPROC16 efproc, LPARAM lpData )
753 lf.lfCharSet = DEFAULT_CHARSET;
754 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
755 else lf.lfFaceName[0] = '\0';
757 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
760 /***********************************************************************
761 * EnumFontFamiliesA (GDI32.@)
763 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
764 FONTENUMPROCA efproc, LPARAM lpData )
768 lf.lfCharSet = DEFAULT_CHARSET;
769 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
770 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
772 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
775 /***********************************************************************
776 * EnumFontFamiliesW (GDI32.@)
778 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
779 FONTENUMPROCW efproc, LPARAM lpData )
783 lf.lfCharSet = DEFAULT_CHARSET;
784 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
785 else lf.lfFaceName[0] = 0;
787 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
790 /***********************************************************************
793 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
796 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
799 /***********************************************************************
800 * EnumFontsA (GDI32.@)
802 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
805 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
808 /***********************************************************************
809 * EnumFontsW (GDI32.@)
811 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
814 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
818 /***********************************************************************
819 * GetTextCharacterExtra (GDI32.@)
821 INT WINAPI GetTextCharacterExtra( HDC hdc )
824 DC *dc = DC_GetDCPtr( hdc );
825 if (!dc) return 0x80000000;
827 GDI_ReleaseObj( hdc );
832 /***********************************************************************
833 * SetTextCharacterExtra (GDI32.@)
835 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
838 DC * dc = DC_GetDCPtr( hdc );
839 if (!dc) return 0x80000000;
840 if (dc->funcs->pSetTextCharacterExtra)
841 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
844 prev = dc->charExtra;
845 dc->charExtra = extra;
847 GDI_ReleaseObj( hdc );
852 /***********************************************************************
853 * SetTextJustification (GDI32.@)
855 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
858 DC * dc = DC_GetDCPtr( hdc );
859 if (!dc) return FALSE;
860 if (dc->funcs->pSetTextJustification)
861 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
864 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
865 if (!extra) breaks = 0;
866 dc->breakTotalExtra = extra;
867 dc->breakCount = breaks;
870 dc->breakExtra = extra / breaks;
871 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
879 GDI_ReleaseObj( hdc );
884 /***********************************************************************
885 * GetTextFaceA (GDI32.@)
887 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
889 INT res = GetTextFaceW(hdc, 0, NULL);
890 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
891 GetTextFaceW( hdc, res, nameW );
895 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
900 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
901 HeapFree( GetProcessHeap(), 0, nameW );
905 /***********************************************************************
906 * GetTextFaceW (GDI32.@)
908 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
913 DC * dc = DC_GetDCPtr( hdc );
917 ret = WineEngGetTextFace(dc->gdiFont, count, name);
918 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
922 lstrcpynW( name, font->logfont.lfFaceName, count );
925 else ret = strlenW(font->logfont.lfFaceName) + 1;
926 GDI_ReleaseObj( dc->hFont );
928 GDI_ReleaseObj( hdc );
933 /***********************************************************************
934 * GetTextExtentPoint32A (GDI32.@)
936 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
941 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
944 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
945 HeapFree( GetProcessHeap(), 0, p );
948 TRACE("(%p %s %d %p): returning %ld x %ld\n",
949 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
954 /***********************************************************************
955 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
957 * Computes width and height of the specified string.
963 BOOL WINAPI GetTextExtentPoint32W(
964 HDC hdc, /* [in] Handle of device context */
965 LPCWSTR str, /* [in] Address of text string */
966 INT count, /* [in] Number of characters in string */
967 LPSIZE size) /* [out] Address of structure for string size */
970 DC * dc = DC_GetDCPtr( hdc );
971 if (!dc) return FALSE;
974 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
975 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
976 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
978 else if(dc->funcs->pGetTextExtentPoint)
979 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
981 GDI_ReleaseObj( hdc );
983 TRACE("(%p %s %d %p): returning %ld x %ld\n",
984 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
988 /***********************************************************************
989 * GetTextExtentPointI [GDI32.@]
991 * Computes width and height of the array of glyph indices.
997 BOOL WINAPI GetTextExtentPointI(
998 HDC hdc, /* [in] Handle of device context */
999 const WORD *indices, /* [in] Address of glyph index array */
1000 INT count, /* [in] Number of glyphs in array */
1001 LPSIZE size) /* [out] Address of structure for string size */
1004 DC * dc = DC_GetDCPtr( hdc );
1005 if (!dc) return FALSE;
1008 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1009 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1010 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1012 else if(dc->funcs->pGetTextExtentPoint) {
1013 FIXME("calling GetTextExtentPoint\n");
1014 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1017 GDI_ReleaseObj( hdc );
1019 TRACE("(%p %p %d %p): returning %ld x %ld\n",
1020 hdc, indices, count, size, size->cx, size->cy );
1025 /***********************************************************************
1026 * GetTextExtentPointA (GDI32.@)
1028 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1031 TRACE("not bug compatible.\n");
1032 return GetTextExtentPoint32A( hdc, str, count, size );
1035 /***********************************************************************
1036 * GetTextExtentPointW (GDI32.@)
1038 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1041 TRACE("not bug compatible.\n");
1042 return GetTextExtentPoint32W( hdc, str, count, size );
1046 /***********************************************************************
1047 * GetTextExtentExPointA (GDI32.@)
1049 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1050 INT maxExt, LPINT lpnFit,
1051 LPINT alpDx, LPSIZE size )
1055 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1056 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1057 HeapFree( GetProcessHeap(), 0, p );
1062 /***********************************************************************
1063 * GetTextExtentExPointW (GDI32.@)
1065 * Return the size of the string as it would be if it was output properly by
1068 * This should include
1069 * - Intercharacter spacing
1070 * - justification spacing (not yet done)
1071 * - kerning? see below
1073 * Kerning. Since kerning would be carried out by the rendering code it should
1074 * be done by the driver. However they don't support it yet. Also I am not
1075 * yet persuaded that (certainly under Win95) any kerning is actually done.
1077 * str: According to MSDN this should be null-terminated. That is not true; a
1078 * null will not terminate it early.
1079 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1080 * than count. I have seen it be either the size of the full string or
1081 * 1 less than the size of the full string. I have not seen it bear any
1082 * resemblance to the portion that would fit.
1083 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1084 * trailing intercharacter spacing and any trailing justification.
1087 * Currently we do this by measuring each character etc. We should do it by
1088 * passing the request to the driver, perhaps by extending the
1089 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1090 * thinking about kerning issues and rounding issues in the justification.
1093 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1094 INT maxExt, LPINT lpnFit,
1095 LPINT alpDx, LPSIZE size )
1097 int index, nFit, extent;
1101 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1103 size->cx = size->cy = nFit = extent = 0;
1104 for(index = 0; index < count; index++)
1106 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1107 /* GetTextExtentPoint includes intercharacter spacing. */
1108 /* FIXME - justification needs doing yet. Remember that the base
1109 * data will not be in logical coordinates.
1112 if( !lpnFit || extent <= maxExt )
1113 /* It is allowed to be equal. */
1116 if( alpDx ) alpDx[index] = extent;
1118 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1122 if(lpnFit) *lpnFit = nFit;
1125 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1131 /***********************************************************************
1132 * GetTextMetricsA (GDI32.@)
1134 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1138 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1139 FONT_TextMetricWToA( &tm32, metrics );
1143 /***********************************************************************
1144 * GetTextMetricsW (GDI32.@)
1146 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1149 DC * dc = DC_GetDCPtr( hdc );
1150 if (!dc) return FALSE;
1153 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1154 else if (dc->funcs->pGetTextMetrics)
1155 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1159 /* device layer returns values in device units
1160 * therefore we have to convert them to logical */
1162 #define WDPTOLP(x) ((x<0)? \
1163 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1164 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1165 #define HDPTOLP(y) ((y<0)? \
1166 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1167 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1169 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1170 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1171 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1172 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1173 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1174 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1175 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1176 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1180 TRACE("text metrics:\n"
1181 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1182 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1183 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1184 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1185 " PitchAndFamily = %02x\n"
1186 " --------------------\n"
1187 " InternalLeading = %li\n"
1191 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1192 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1193 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1194 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1195 metrics->tmPitchAndFamily,
1196 metrics->tmInternalLeading,
1199 metrics->tmHeight );
1201 GDI_ReleaseObj( hdc );
1206 /***********************************************************************
1207 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1210 * lpOTM should be LPOUTLINETEXTMETRIC
1213 * Success: Non-zero or size of required buffer
1216 UINT16 WINAPI GetOutlineTextMetrics16(
1217 HDC16 hdc, /* [in] Handle of device context */
1218 UINT16 cbData, /* [in] Size of metric data array */
1219 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1221 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1226 /***********************************************************************
1227 * GetOutlineTextMetricsA (GDI32.@)
1228 * Gets metrics for TrueType fonts.
1232 * Success: Non-zero or size of required buffer
1235 UINT WINAPI GetOutlineTextMetricsA(
1236 HDC hdc, /* [in] Handle of device context */
1237 UINT cbData, /* [in] Size of metric data array */
1238 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1240 char buf[512], *ptr;
1242 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1245 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1246 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1248 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1249 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1252 needed = sizeof(OUTLINETEXTMETRICA);
1253 if(lpOTMW->otmpFamilyName)
1254 needed += WideCharToMultiByte(CP_ACP, 0,
1255 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1256 NULL, 0, NULL, NULL);
1257 if(lpOTMW->otmpFaceName)
1258 needed += WideCharToMultiByte(CP_ACP, 0,
1259 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1260 NULL, 0, NULL, NULL);
1261 if(lpOTMW->otmpStyleName)
1262 needed += WideCharToMultiByte(CP_ACP, 0,
1263 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1264 NULL, 0, NULL, NULL);
1265 if(lpOTMW->otmpFullName)
1266 needed += WideCharToMultiByte(CP_ACP, 0,
1267 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1268 NULL, 0, NULL, NULL);
1275 if(needed > cbData) {
1281 lpOTM->otmSize = needed;
1282 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1283 lpOTM->otmFiller = 0;
1284 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1285 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1286 lpOTM->otmfsType = lpOTMW->otmfsType;
1287 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1288 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1289 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1290 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1291 lpOTM->otmAscent = lpOTMW->otmAscent;
1292 lpOTM->otmDescent = lpOTMW->otmDescent;
1293 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1294 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1295 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1296 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1297 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1298 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1299 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1300 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1301 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1302 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1303 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1304 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1305 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1306 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1307 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1308 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1311 ptr = (char*)(lpOTM + 1);
1312 left = needed - sizeof(*lpOTM);
1314 if(lpOTMW->otmpFamilyName) {
1315 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1316 len = WideCharToMultiByte(CP_ACP, 0,
1317 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1318 ptr, left, NULL, NULL);
1322 lpOTM->otmpFamilyName = 0;
1324 if(lpOTMW->otmpFaceName) {
1325 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1326 len = WideCharToMultiByte(CP_ACP, 0,
1327 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1328 ptr, left, NULL, NULL);
1332 lpOTM->otmpFaceName = 0;
1334 if(lpOTMW->otmpStyleName) {
1335 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1336 len = WideCharToMultiByte(CP_ACP, 0,
1337 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1338 ptr, left, NULL, NULL);
1342 lpOTM->otmpStyleName = 0;
1344 if(lpOTMW->otmpFullName) {
1345 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1346 len = WideCharToMultiByte(CP_ACP, 0,
1347 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1348 ptr, left, NULL, NULL);
1351 lpOTM->otmpFullName = 0;
1358 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1359 HeapFree(GetProcessHeap(), 0, lpOTMW);
1365 /***********************************************************************
1366 * GetOutlineTextMetricsW [GDI32.@]
1368 UINT WINAPI GetOutlineTextMetricsW(
1369 HDC hdc, /* [in] Handle of device context */
1370 UINT cbData, /* [in] Size of metric data array */
1371 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1373 DC *dc = DC_GetDCPtr( hdc );
1376 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1380 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1381 if(ret && ret <= cbData) {
1382 #define WDPTOLP(x) ((x<0)? \
1383 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1384 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1385 #define HDPTOLP(y) ((y<0)? \
1386 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1387 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1389 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1390 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1391 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1392 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1393 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1394 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1395 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1396 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1397 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1398 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1399 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1400 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1401 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1402 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1403 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1404 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1405 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1406 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1407 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1408 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1409 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1410 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1411 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1412 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1413 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1414 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1415 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1416 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1417 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1418 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1419 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1420 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1426 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1427 but really this should just be a return 0. */
1429 ret = sizeof(*lpOTM);
1434 memset(lpOTM, 0, ret);
1435 lpOTM->otmSize = sizeof(*lpOTM);
1436 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1438 Further fill of the structure not implemented,
1439 Needs real values for the structure members
1444 GDI_ReleaseObj(hdc);
1449 /***********************************************************************
1450 * GetCharWidthW (GDI32.@)
1451 * GetCharWidth32W (GDI32.@)
1453 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1458 DC * dc = DC_GetDCPtr( hdc );
1459 if (!dc) return FALSE;
1462 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1463 else if (dc->funcs->pGetCharWidth)
1464 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1468 /* convert device units to logical */
1469 for( i = firstChar; i <= lastChar; i++, buffer++ )
1470 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1473 GDI_ReleaseObj( hdc );
1478 /***********************************************************************
1479 * GetCharWidthA (GDI32.@)
1480 * GetCharWidth32A (GDI32.@)
1482 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1485 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1490 if(count <= 0) return FALSE;
1492 str = HeapAlloc(GetProcessHeap(), 0, count);
1493 for(i = 0; i < count; i++)
1494 str[i] = (BYTE)(firstChar + i);
1496 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1498 for(i = 0; i < wlen; i++)
1500 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1508 HeapFree(GetProcessHeap(), 0, str);
1509 HeapFree(GetProcessHeap(), 0, wstr);
1515 /* FIXME: all following APIs ******************************************/
1518 /***********************************************************************
1519 * SetMapperFlags (GDI32.@)
1521 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1523 DC *dc = DC_GetDCPtr( hDC );
1526 if(dc->funcs->pSetMapperFlags)
1527 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1529 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1530 GDI_ReleaseObj( hDC );
1534 /***********************************************************************
1535 * GetAspectRatioFilterEx (GDI.486)
1537 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1539 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1543 /***********************************************************************
1544 * GetAspectRatioFilterEx (GDI32.@)
1546 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1548 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1553 /***********************************************************************
1554 * GetCharABCWidthsA (GDI32.@)
1556 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1559 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1564 if(count <= 0) return FALSE;
1566 str = HeapAlloc(GetProcessHeap(), 0, count);
1567 for(i = 0; i < count; i++)
1568 str[i] = (BYTE)(firstChar + i);
1570 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1572 for(i = 0; i < wlen; i++)
1574 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1582 HeapFree(GetProcessHeap(), 0, str);
1583 HeapFree(GetProcessHeap(), 0, wstr);
1589 /******************************************************************************
1590 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1593 * hdc [I] Handle of device context
1594 * firstChar [I] First character in range to query
1595 * lastChar [I] Last character in range to query
1596 * abc [O] Address of character-width structure
1599 * Only works with TrueType fonts
1605 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1608 DC *dc = DC_GetDCPtr(hdc);
1614 for (i=firstChar;i<=lastChar;i++) {
1615 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1616 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1617 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1618 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1622 GDI_ReleaseObj(hdc);
1627 /***********************************************************************
1628 * GetGlyphOutline (GDI.309)
1630 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1631 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1632 LPVOID lpBuffer, const MAT2 *lpmat2 )
1634 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1635 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1636 return (DWORD)-1; /* failure */
1640 /***********************************************************************
1641 * GetGlyphOutlineA (GDI32.@)
1643 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1644 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1645 LPVOID lpBuffer, const MAT2 *lpmat2 )
1651 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1652 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1656 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1659 HeapFree(GetProcessHeap(), 0, p);
1663 /***********************************************************************
1664 * GetGlyphOutlineW (GDI32.@)
1666 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1667 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1668 LPVOID lpBuffer, const MAT2 *lpmat2 )
1670 DC *dc = DC_GetDCPtr(hdc);
1673 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1674 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1676 if(!dc) return GDI_ERROR;
1679 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1680 cbBuffer, lpBuffer, lpmat2);
1684 GDI_ReleaseObj(hdc);
1689 /***********************************************************************
1690 * CreateScalableFontResourceA (GDI32.@)
1692 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1693 LPCSTR lpszResourceFile,
1694 LPCSTR lpszFontFile,
1695 LPCSTR lpszCurrentPath )
1699 /* fHidden=1 - only visible for the calling app, read-only, not
1700 * enumbered with EnumFonts/EnumFontFamilies
1701 * lpszCurrentPath can be NULL
1703 FIXME("(%ld,%s,%s,%s): stub\n",
1704 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1705 debugstr_a(lpszCurrentPath) );
1707 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1708 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1710 SetLastError(ERROR_FILE_EXISTS);
1713 return FALSE; /* create failed */
1716 /***********************************************************************
1717 * CreateScalableFontResourceW (GDI32.@)
1719 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1720 LPCWSTR lpszResourceFile,
1721 LPCWSTR lpszFontFile,
1722 LPCWSTR lpszCurrentPath )
1724 FIXME("(%ld,%p,%p,%p): stub\n",
1725 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1726 return FALSE; /* create failed */
1730 /*************************************************************************
1731 * GetRasterizerCaps (GDI32.@)
1733 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1735 lprs->nSize = sizeof(RASTERIZER_STATUS);
1736 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1737 lprs->nLanguageID = 0;
1742 /*************************************************************************
1743 * GetKerningPairsA (GDI32.@)
1745 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1746 LPKERNINGPAIR lpKerningPairs )
1748 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1752 /*************************************************************************
1753 * GetKerningPairsW (GDI32.@)
1755 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1756 LPKERNINGPAIR lpKerningPairs )
1759 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1760 for (i = 0; i < cPairs; i++)
1761 lpKerningPairs[i].iKernAmount = 0;
1765 /*************************************************************************
1766 * TranslateCharsetInfo [GDI32.@]
1768 * Fills a CHARSETINFO structure for a character set, code page, or
1769 * font. This allows making the correspondance between different labelings
1770 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1771 * of the same encoding.
1773 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1774 * only one codepage should be set in *lpSrc.
1777 * TRUE on success, FALSE on failure.
1780 BOOL WINAPI TranslateCharsetInfo(
1781 LPDWORD lpSrc, /* [in]
1782 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1783 if flags == TCI_SRCCHARSET: a character set value
1784 if flags == TCI_SRCCODEPAGE: a code page value
1786 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1787 DWORD flags /* [in] determines interpretation of lpSrc */
1791 case TCI_SRCFONTSIG:
1792 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1794 case TCI_SRCCODEPAGE:
1795 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1797 case TCI_SRCCHARSET:
1798 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1803 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1804 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1808 /*************************************************************************
1809 * GetFontLanguageInfo (GDI32.@)
1811 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1813 FONTSIGNATURE fontsig;
1814 static const DWORD GCP_DBCS_MASK=0x003F0000,
1815 GCP_DIACRITIC_MASK=0x00000000,
1816 FLI_GLYPHS_MASK=0x00000000,
1817 GCP_GLYPHSHAPE_MASK=0x00000040,
1818 GCP_KASHIDA_MASK=0x00000000,
1819 GCP_LIGATE_MASK=0x00000000,
1820 GCP_USEKERNING_MASK=0x00000000,
1821 GCP_REORDER_MASK=0x00000060;
1825 GetTextCharsetInfo( hdc, &fontsig, 0 );
1826 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1828 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1831 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1832 result|=GCP_DIACRITIC;
1834 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1837 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1838 result|=GCP_GLYPHSHAPE;
1840 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1841 result|=GCP_KASHIDA;
1843 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1846 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1847 result|=GCP_USEKERNING;
1849 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1850 result|=GCP_REORDER;
1856 /*************************************************************************
1857 * GetFontData [GDI32.@] Retrieve data for TrueType font
1861 * success: Number of bytes returned
1862 * failure: GDI_ERROR
1866 * Calls SetLastError()
1869 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1870 LPVOID buffer, DWORD length)
1872 DC *dc = DC_GetDCPtr(hdc);
1873 DWORD ret = GDI_ERROR;
1875 if(!dc) return GDI_ERROR;
1878 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1880 GDI_ReleaseObj(hdc);
1884 /*************************************************************************
1885 * GetGlyphIndicesA [GDI32.@]
1887 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1888 LPWORD pgi, DWORD flags)
1894 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1895 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1897 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1898 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1899 HeapFree(GetProcessHeap(), 0, lpstrW);
1904 /*************************************************************************
1905 * GetGlyphIndicesW [GDI32.@]
1907 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1908 LPWORD pgi, DWORD flags)
1910 DC *dc = DC_GetDCPtr(hdc);
1911 DWORD ret = GDI_ERROR;
1913 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1914 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1916 if(!dc) return GDI_ERROR;
1919 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1921 GDI_ReleaseObj(hdc);
1925 /*************************************************************************
1926 * GetCharacterPlacementA [GDI32.@]
1929 * the web browser control of ie4 calls this with dwFlags=0
1932 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1933 INT nMaxExtent, GCP_RESULTSA *lpResults,
1938 GCP_RESULTSW resultsW;
1942 TRACE("%s, %d, %d, 0x%08lx\n",
1943 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1945 /* both structs are equal in size */
1946 memcpy(&resultsW, lpResults, sizeof(resultsW));
1948 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1949 if(lpResults->lpOutString)
1950 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1952 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1954 if(lpResults->lpOutString) {
1955 if(font_cp != CP_SYMBOL)
1956 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1957 lpResults->lpOutString, uCount, NULL, NULL );
1959 for(i = 0; i < uCount; i++)
1960 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1963 HeapFree(GetProcessHeap(), 0, lpStringW);
1964 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1969 /*************************************************************************
1970 * GetCharacterPlacementW [GDI32.@]
1972 * Retrieve information about a string. This includes the width, reordering,
1973 * Glyphing and so on.
1977 * The width and height of the string if successful, 0 if failed.
1981 * All flags except GCP_REORDER are not yet implemented.
1982 * Reordering is not 100% complient to the Windows BiDi method.
1983 * Caret positioning is not yet implemented.
1984 * Classes are not yet implemented.
1988 GetCharacterPlacementW(
1989 HDC hdc, /* [in] Device context for which the rendering is to be done */
1990 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1991 INT uCount, /* [in] Number of WORDS in string. */
1992 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1993 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1994 DWORD dwFlags /* [in] Flags specifying how to process the string */
2001 TRACE("%s, %d, %d, 0x%08lx\n",
2002 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2004 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2005 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2006 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2007 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2008 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2010 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2011 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2012 if(lpResults->lpClass) FIXME("classes not implemented\n");
2014 nSet = (UINT)uCount;
2015 if(nSet > lpResults->nGlyphs)
2016 nSet = lpResults->nGlyphs;
2018 /* return number of initialized fields */
2019 lpResults->nGlyphs = nSet;
2021 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
2023 /* Treat the case where no special handling was requested in a fastpath way */
2024 /* copy will do if the GCP_REORDER flag is not set */
2025 if(lpResults->lpOutString)
2026 strncpyW( lpResults->lpOutString, lpString, nSet );
2028 if(lpResults->lpOrder)
2030 for(i = 0; i < nSet; i++)
2031 lpResults->lpOrder[i] = i;
2035 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2036 nSet, lpResults->lpOrder );
2039 /* FIXME: Will use the placement chars */
2040 if (lpResults->lpDx)
2043 for (i = 0; i < nSet; i++)
2045 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2046 lpResults->lpDx[i]= c;
2050 if(lpResults->lpGlyphs)
2051 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2053 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2054 ret = MAKELONG(size.cx, size.cy);
2059 /*************************************************************************
2060 * GetCharABCWidthsFloatA [GDI32.@]
2062 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2065 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2069 /*************************************************************************
2070 * GetCharABCWidthsFloatW [GDI32.@]
2072 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2073 UINT iLastChar, LPABCFLOAT lpABCF)
2075 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2079 /*************************************************************************
2080 * GetCharWidthFloatA [GDI32.@]
2082 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2083 UINT iLastChar, PFLOAT pxBuffer)
2085 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2089 /*************************************************************************
2090 * GetCharWidthFloatW [GDI32.@]
2092 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2093 UINT iLastChar, PFLOAT pxBuffer)
2095 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2100 /***********************************************************************
2102 * Font Resource API *
2104 ***********************************************************************/
2106 /***********************************************************************
2107 * AddFontResourceA (GDI32.@)
2109 INT WINAPI AddFontResourceA( LPCSTR str )
2111 return AddFontResourceExA( str, 0, NULL);
2114 /***********************************************************************
2115 * AddFontResourceW (GDI32.@)
2117 INT WINAPI AddFontResourceW( LPCWSTR str )
2119 return AddFontResourceExW(str, 0, NULL);
2123 /***********************************************************************
2124 * AddFontResourceExA (GDI32.@)
2126 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2128 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2129 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2132 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2133 ret = AddFontResourceExW(strW, fl, pdv);
2134 HeapFree(GetProcessHeap(), 0, strW);
2138 /***********************************************************************
2139 * AddFontResourceExW (GDI32.@)
2141 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2143 return WineEngAddFontResourceEx(str, fl, pdv);
2146 /***********************************************************************
2147 * RemoveFontResourceA (GDI32.@)
2149 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2151 return RemoveFontResourceExA(str, 0, 0);
2154 /***********************************************************************
2155 * RemoveFontResourceW (GDI32.@)
2157 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2159 return RemoveFontResourceExW(str, 0, 0);
2162 /***********************************************************************
2163 * RemoveFontResourceExA (GDI32.@)
2165 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2167 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2168 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2171 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2172 ret = RemoveFontResourceExW(strW, fl, pdv);
2173 HeapFree(GetProcessHeap(), 0, strW);
2177 /***********************************************************************
2178 * RemoveFontResourceExW (GDI32.@)
2180 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2182 return WineEngRemoveFontResourceEx(str, fl, pdv);
2185 /***********************************************************************
2186 * GetTextCharset (GDI32.@)
2188 UINT WINAPI GetTextCharset(HDC hdc)
2190 /* MSDN docs say this is equivalent */
2191 return GetTextCharsetInfo(hdc, NULL, 0);
2194 /***********************************************************************
2195 * GetTextCharsetInfo (GDI32.@)
2197 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2199 UINT ret = DEFAULT_CHARSET;
2200 DC *dc = DC_GetDCPtr(hdc);
2205 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2207 GDI_ReleaseObj(hdc);
2210 if (ret == DEFAULT_CHARSET && fs)
2211 memset(fs, 0, sizeof(FONTSIGNATURE));