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 "gdi_private.h"
37 #include "wine/unicode.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(font);
41 WINE_DECLARE_DEBUG_CHANNEL(gdi);
43 /* Device -> World size conversion */
45 /* Performs a device to world transformation on the specified width (which
46 * is in integer format).
48 static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
52 /* Perform operation with floating point */
53 floatWidth = (FLOAT)width * dc->xformVport2World.eM11;
54 /* Round to integers */
55 return GDI_ROUND(floatWidth);
58 /* Performs a device to world transformation on the specified size (which
59 * is in integer format).
61 static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
65 /* Perform operation with floating point */
66 floatHeight = (FLOAT)height * dc->xformVport2World.eM22;
67 /* Round to integers */
68 return GDI_ROUND(floatHeight);
72 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
73 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
74 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
75 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
76 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
78 static const struct gdi_obj_funcs font_funcs =
80 FONT_SelectObject, /* pSelectObject */
81 FONT_GetObject16, /* pGetObject16 */
82 FONT_GetObjectA, /* pGetObjectA */
83 FONT_GetObjectW, /* pGetObjectW */
84 NULL, /* pUnrealizeObject */
85 FONT_DeleteObject /* pDeleteObject */
88 #define ENUM_UNICODE 0x00000001
89 #define ENUM_CALLED 0x00000002
99 LPLOGFONT16 lpLogFontParam;
100 FONTENUMPROC16 lpEnumFunc;
103 LPNEWTEXTMETRICEX16 lpTextMetric;
104 LPENUMLOGFONTEX16 lpLogFont;
105 SEGPTR segTextMetric;
115 LPLOGFONTW lpLogFontParam;
116 FONTENUMPROCW lpEnumFunc;
125 * For TranslateCharsetInfo
127 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
128 #define MAXTCIINDEX 32
129 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
131 { ANSI_CHARSET, 1252, FS(0)},
132 { EASTEUROPE_CHARSET, 1250, FS(1)},
133 { RUSSIAN_CHARSET, 1251, FS(2)},
134 { GREEK_CHARSET, 1253, FS(3)},
135 { TURKISH_CHARSET, 1254, FS(4)},
136 { HEBREW_CHARSET, 1255, FS(5)},
137 { ARABIC_CHARSET, 1256, FS(6)},
138 { BALTIC_CHARSET, 1257, FS(7)},
139 { VIETNAMESE_CHARSET, 1258, FS(8)},
140 /* reserved by ANSI */
141 { DEFAULT_CHARSET, 0, FS(0)},
142 { DEFAULT_CHARSET, 0, FS(0)},
143 { DEFAULT_CHARSET, 0, FS(0)},
144 { DEFAULT_CHARSET, 0, FS(0)},
145 { DEFAULT_CHARSET, 0, FS(0)},
146 { DEFAULT_CHARSET, 0, FS(0)},
147 { DEFAULT_CHARSET, 0, FS(0)},
149 { THAI_CHARSET, 874, FS(16)},
150 { SHIFTJIS_CHARSET, 932, FS(17)},
151 { GB2312_CHARSET, 936, FS(18)},
152 { HANGEUL_CHARSET, 949, FS(19)},
153 { CHINESEBIG5_CHARSET, 950, FS(20)},
154 { JOHAB_CHARSET, 1361, FS(21)},
155 /* reserved for alternate ANSI and OEM */
156 { DEFAULT_CHARSET, 0, FS(0)},
157 { DEFAULT_CHARSET, 0, FS(0)},
158 { DEFAULT_CHARSET, 0, FS(0)},
159 { DEFAULT_CHARSET, 0, FS(0)},
160 { DEFAULT_CHARSET, 0, FS(0)},
161 { DEFAULT_CHARSET, 0, FS(0)},
162 { DEFAULT_CHARSET, 0, FS(0)},
163 { DEFAULT_CHARSET, 0, FS(0)},
164 /* reserved for system */
165 { DEFAULT_CHARSET, 0, FS(0)},
166 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
169 /***********************************************************************
170 * LOGFONT conversion functions.
172 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
174 font16->lfHeight = font32->lfHeight;
175 font16->lfWidth = font32->lfWidth;
176 font16->lfEscapement = font32->lfEscapement;
177 font16->lfOrientation = font32->lfOrientation;
178 font16->lfWeight = font32->lfWeight;
179 font16->lfItalic = font32->lfItalic;
180 font16->lfUnderline = font32->lfUnderline;
181 font16->lfStrikeOut = font32->lfStrikeOut;
182 font16->lfCharSet = font32->lfCharSet;
183 font16->lfOutPrecision = font32->lfOutPrecision;
184 font16->lfClipPrecision = font32->lfClipPrecision;
185 font16->lfQuality = font32->lfQuality;
186 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
187 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
188 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
189 font16->lfFaceName[LF_FACESIZE-1] = 0;
192 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
194 font32->lfHeight = font16->lfHeight;
195 font32->lfWidth = font16->lfWidth;
196 font32->lfEscapement = font16->lfEscapement;
197 font32->lfOrientation = font16->lfOrientation;
198 font32->lfWeight = font16->lfWeight;
199 font32->lfItalic = font16->lfItalic;
200 font32->lfUnderline = font16->lfUnderline;
201 font32->lfStrikeOut = font16->lfStrikeOut;
202 font32->lfCharSet = font16->lfCharSet;
203 font32->lfOutPrecision = font16->lfOutPrecision;
204 font32->lfClipPrecision = font16->lfClipPrecision;
205 font32->lfQuality = font16->lfQuality;
206 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
207 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
208 font32->lfFaceName[LF_FACESIZE-1] = 0;
211 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
213 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
214 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
218 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
220 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
221 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
222 LF_FACESIZE, NULL, NULL);
225 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
227 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
229 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
230 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
231 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
232 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
233 font16->elfStyle, LF_FACESIZE, NULL, NULL );
234 font16->elfStyle[LF_FACESIZE-1] = '\0';
235 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
236 font16->elfScript, LF_FACESIZE, NULL, NULL );
237 font16->elfScript[LF_FACESIZE-1] = '\0';
240 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
242 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
244 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
245 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
246 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
247 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
248 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
249 fontA->elfStyle[LF_FACESIZE-1] = '\0';
250 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
251 fontA->elfScript, LF_FACESIZE, NULL, NULL );
252 fontA->elfScript[LF_FACESIZE-1] = '\0';
255 /***********************************************************************
256 * TEXTMETRIC conversion functions.
258 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
260 ptmA->tmHeight = ptmW->tmHeight;
261 ptmA->tmAscent = ptmW->tmAscent;
262 ptmA->tmDescent = ptmW->tmDescent;
263 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
264 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
265 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
266 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
267 ptmA->tmWeight = ptmW->tmWeight;
268 ptmA->tmOverhang = ptmW->tmOverhang;
269 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
270 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
271 ptmA->tmFirstChar = ptmW->tmFirstChar > 255 ? 255 : ptmW->tmFirstChar;
272 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
273 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
274 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : ptmW->tmBreakChar;
275 ptmA->tmItalic = ptmW->tmItalic;
276 ptmA->tmUnderlined = ptmW->tmUnderlined;
277 ptmA->tmStruckOut = ptmW->tmStruckOut;
278 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
279 ptmA->tmCharSet = ptmW->tmCharSet;
283 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
285 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
286 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
287 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
288 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
289 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
290 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
291 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
292 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
293 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
294 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
295 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
296 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
297 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
298 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
299 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
300 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
301 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
302 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
303 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
304 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
305 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
306 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
307 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
308 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
309 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
312 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
314 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
315 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
316 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
317 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
318 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
319 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
322 /***********************************************************************
323 * CreateFontIndirectA (GDI32.@)
325 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
330 FONT_LogFontAToW( plfA, &lfW );
331 return CreateFontIndirectW( &lfW );
333 return CreateFontIndirectW( NULL );
337 /***********************************************************************
338 * CreateFontIndirectW (GDI32.@)
340 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
347 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
348 (HGDIOBJ *)&hFont, &font_funcs )))
350 static const WCHAR ItalicW[] = {' ','I','t','a','l','i','c','\0'};
351 static const WCHAR BoldW[] = {' ','B','o','l','d','\0'};
352 WCHAR *pFaceNameItalicSuffix, *pFaceNameBoldSuffix;
353 WCHAR* pFaceNameSuffix = NULL;
355 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
357 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s %s => %p\n",
358 plf->lfHeight, plf->lfWidth,
359 plf->lfEscapement, plf->lfOrientation,
360 plf->lfPitchAndFamily,
361 plf->lfOutPrecision, plf->lfClipPrecision,
362 plf->lfQuality, plf->lfCharSet,
363 debugstr_w(plf->lfFaceName),
364 plf->lfWeight > 400 ? "Bold" : "",
365 plf->lfItalic ? "Italic" : "",
366 plf->lfUnderline ? "Underline" : "", hFont);
368 if (plf->lfEscapement != plf->lfOrientation) {
369 /* this should really depend on whether GM_ADVANCED is set */
370 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
371 WARN("orientation angle %f set to "
372 "escapement angle %f for new font %p\n",
373 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
376 pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
377 if (pFaceNameItalicSuffix) {
378 fontPtr->logfont.lfItalic = TRUE;
379 pFaceNameSuffix = pFaceNameItalicSuffix;
382 pFaceNameBoldSuffix = strstrW(fontPtr->logfont.lfFaceName, BoldW);
383 if (pFaceNameBoldSuffix) {
384 if (fontPtr->logfont.lfWeight < FW_BOLD) {
385 fontPtr->logfont.lfWeight = FW_BOLD;
387 if (!pFaceNameSuffix ||
388 (pFaceNameBoldSuffix < pFaceNameSuffix)) {
389 pFaceNameSuffix = pFaceNameBoldSuffix;
393 if (pFaceNameSuffix) *pFaceNameSuffix = 0;
395 GDI_ReleaseObj( hFont );
398 else WARN("(NULL) => NULL\n");
403 /*************************************************************************
404 * CreateFontA (GDI32.@)
406 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
407 INT orient, INT weight, DWORD italic,
408 DWORD underline, DWORD strikeout, DWORD charset,
409 DWORD outpres, DWORD clippres, DWORD quality,
410 DWORD pitch, LPCSTR name )
414 logfont.lfHeight = height;
415 logfont.lfWidth = width;
416 logfont.lfEscapement = esc;
417 logfont.lfOrientation = orient;
418 logfont.lfWeight = weight;
419 logfont.lfItalic = italic;
420 logfont.lfUnderline = underline;
421 logfont.lfStrikeOut = strikeout;
422 logfont.lfCharSet = charset;
423 logfont.lfOutPrecision = outpres;
424 logfont.lfClipPrecision = clippres;
425 logfont.lfQuality = quality;
426 logfont.lfPitchAndFamily = pitch;
429 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
431 logfont.lfFaceName[0] = '\0';
433 return CreateFontIndirectA( &logfont );
436 /*************************************************************************
437 * CreateFontW (GDI32.@)
439 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
440 INT orient, INT weight, DWORD italic,
441 DWORD underline, DWORD strikeout, DWORD charset,
442 DWORD outpres, DWORD clippres, DWORD quality,
443 DWORD pitch, LPCWSTR name )
447 logfont.lfHeight = height;
448 logfont.lfWidth = width;
449 logfont.lfEscapement = esc;
450 logfont.lfOrientation = orient;
451 logfont.lfWeight = weight;
452 logfont.lfItalic = italic;
453 logfont.lfUnderline = underline;
454 logfont.lfStrikeOut = strikeout;
455 logfont.lfCharSet = charset;
456 logfont.lfOutPrecision = outpres;
457 logfont.lfClipPrecision = clippres;
458 logfont.lfQuality = quality;
459 logfont.lfPitchAndFamily = pitch;
462 lstrcpynW(logfont.lfFaceName, name,
463 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
465 logfont.lfFaceName[0] = '\0';
467 return CreateFontIndirectW( &logfont );
471 /***********************************************************************
474 * If the driver supports vector fonts we create a gdi font first and
475 * then call the driver to give it a chance to supply its own device
476 * font. If the driver wants to do this it returns TRUE and we can
477 * delete the gdi font, if the driver wants to use the gdi font it
478 * should return FALSE, to signal an error return GDI_ERROR. For
479 * drivers that don't support vector fonts they must supply their own
482 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
485 DC *dc = DC_GetDCPtr( hdc );
489 if (dc->hFont != handle || dc->gdiFont == NULL)
491 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
492 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
495 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
497 if (ret && dc->gdiFont) dc->gdiFont = 0;
499 if (ret == HGDI_ERROR)
500 ret = 0; /* SelectObject returns 0 on error */
506 GDI_ReleaseObj( hdc );
511 /***********************************************************************
514 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
519 FONT_LogFontWTo16( &font->logfont, &lf16 );
521 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
522 memcpy( buffer, &lf16, count );
526 /***********************************************************************
529 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
536 FONT_LogFontWToA( &font->logfont, &lfA );
538 if (count > sizeof(lfA)) count = sizeof(lfA);
539 memcpy( buffer, &lfA, count );
543 /***********************************************************************
546 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
550 return sizeof(LOGFONTW);
551 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
552 memcpy( buffer, &font->logfont, count );
557 /***********************************************************************
560 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
562 WineEngDestroyFontInstance( handle );
563 return GDI_FreeObject( handle, obj );
567 /***********************************************************************
568 * FONT_EnumInstance16
570 * Called by the device driver layer to pass font info
571 * down to the application.
573 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
574 * We have to use other types because of the FONTENUMPROCW definition.
576 static INT CALLBACK FONT_EnumInstance16( const LOGFONTW *plf, const TEXTMETRICW *ptm,
577 DWORD fType, LPARAM lp )
579 fontEnum16 *pfe = (fontEnum16*)lp;
583 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
584 pfe->lpLogFontParam->lfCharSet == plf->lfCharSet )
589 FONT_EnumLogFontExWTo16((const ENUMLOGFONTEXW *)plf, pfe->lpLogFont);
590 FONT_NewTextMetricExWTo16((const NEWTEXTMETRICEXW *)ptm, pfe->lpTextMetric);
591 pfe->dwFlags |= ENUM_CALLED;
592 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
594 args[6] = SELECTOROF(pfe->segLogFont);
595 args[5] = OFFSETOF(pfe->segLogFont);
596 args[4] = SELECTOROF(pfe->segTextMetric);
597 args[3] = OFFSETOF(pfe->segTextMetric);
599 args[1] = HIWORD(pfe->lpData);
600 args[0] = LOWORD(pfe->lpData);
601 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
602 ret = LOWORD(result);
604 /* get the lock again and make sure the DC is still valid */
605 dc = DC_GetDCPtr( pfe->hdc );
606 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
608 if (dc) GDI_ReleaseObj( pfe->hdc );
609 pfe->hdc = 0; /* make sure we don't try to release it later on */
616 /***********************************************************************
619 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
620 * We have to use other types because of the FONTENUMPROCW definition.
622 static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *ptm,
623 DWORD fType, LPARAM lp )
625 fontEnum32 *pfe = (fontEnum32*)lp;
629 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
630 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
631 pfe->lpLogFontParam->lfCharSet == plf->lfCharSet )
633 /* convert font metrics */
634 ENUMLOGFONTEXA logfont;
635 NEWTEXTMETRICEXA tmA;
637 pfe->dwFlags |= ENUM_CALLED;
638 if (!(pfe->dwFlags & ENUM_UNICODE))
640 FONT_EnumLogFontExWToA( (const ENUMLOGFONTEXW *)plf, &logfont);
641 FONT_NewTextMetricExWToA( (const NEWTEXTMETRICEXW *)ptm, &tmA );
642 plf = (LOGFONTW *)&logfont.elfLogFont;
643 ptm = (TEXTMETRICW *)&tmA;
645 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
647 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
649 /* get the lock again and make sure the DC is still valid */
650 dc = DC_GetDCPtr( pfe->hdc );
651 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
653 if (dc) GDI_ReleaseObj( pfe->hdc );
654 pfe->hdc = 0; /* make sure we don't try to release it later on */
661 /***********************************************************************
662 * EnumFontFamiliesEx (GDI.613)
664 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
665 FONTENUMPROC16 efproc, LPARAM lParam,
670 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
671 NEWTEXTMETRICEX16 tm16;
672 ENUMLOGFONTEX16 lf16;
677 FONT_LogFont16ToW(plf, &lfW);
679 fe16.hdc = HDC_32(hDC);
681 fe16.physDev = dc->physDev;
682 fe16.lpLogFontParam = plf;
683 fe16.lpEnumFunc = efproc;
684 fe16.lpData = lParam;
685 fe16.lpTextMetric = &tm16;
686 fe16.lpLogFont = &lf16;
687 fe16.segTextMetric = MapLS( &tm16 );
688 fe16.segLogFont = MapLS( &lf16 );
691 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
693 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
700 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
701 fe16.dwFlags &= ~ENUM_CALLED;
702 if (ret && dc->funcs->pEnumDeviceFonts) {
703 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
704 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
708 UnMapLS( fe16.segTextMetric );
709 UnMapLS( fe16.segLogFont );
710 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
714 /***********************************************************************
715 * FONT_EnumFontFamiliesEx
717 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
718 FONTENUMPROCW efproc,
719 LPARAM lParam, DWORD dwUnicode)
722 DC *dc = DC_GetDCPtr( hDC );
728 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
730 fe32.lpLogFontParam = plf;
731 fe32.lpEnumFunc = efproc;
732 fe32.lpData = lParam;
733 fe32.dwFlags = dwUnicode;
736 fe32.physDev = dc->physDev;
738 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
740 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
747 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
748 fe32.dwFlags &= ~ENUM_CALLED;
749 if (ret && dc->funcs->pEnumDeviceFonts) {
750 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
751 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
755 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
759 /***********************************************************************
760 * EnumFontFamiliesExW (GDI32.@)
762 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
763 FONTENUMPROCW efproc,
764 LPARAM lParam, DWORD dwFlags )
766 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
769 /***********************************************************************
770 * EnumFontFamiliesExA (GDI32.@)
772 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
773 FONTENUMPROCA efproc,
774 LPARAM lParam, DWORD dwFlags)
777 FONT_LogFontAToW( plf, &lfW );
779 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
782 /***********************************************************************
783 * EnumFontFamilies (GDI.330)
785 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
786 FONTENUMPROC16 efproc, LPARAM lpData )
790 lf.lfCharSet = DEFAULT_CHARSET;
791 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
792 else lf.lfFaceName[0] = '\0';
794 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
797 /***********************************************************************
798 * EnumFontFamiliesA (GDI32.@)
800 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
801 FONTENUMPROCA efproc, LPARAM lpData )
805 lf.lfCharSet = DEFAULT_CHARSET;
806 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
807 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
809 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
812 /***********************************************************************
813 * EnumFontFamiliesW (GDI32.@)
815 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
816 FONTENUMPROCW efproc, LPARAM lpData )
820 lf.lfCharSet = DEFAULT_CHARSET;
821 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
822 else lf.lfFaceName[0] = 0;
824 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
827 /***********************************************************************
830 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
833 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
836 /***********************************************************************
837 * EnumFontsA (GDI32.@)
839 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
842 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
845 /***********************************************************************
846 * EnumFontsW (GDI32.@)
848 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
851 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
855 /***********************************************************************
856 * GetTextCharacterExtra (GDI32.@)
858 INT WINAPI GetTextCharacterExtra( HDC hdc )
861 DC *dc = DC_GetDCPtr( hdc );
862 if (!dc) return 0x80000000;
864 GDI_ReleaseObj( hdc );
869 /***********************************************************************
870 * SetTextCharacterExtra (GDI32.@)
872 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
875 DC * dc = DC_GetDCPtr( hdc );
876 if (!dc) return 0x80000000;
877 if (dc->funcs->pSetTextCharacterExtra)
878 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
881 prev = dc->charExtra;
882 dc->charExtra = extra;
884 GDI_ReleaseObj( hdc );
889 /***********************************************************************
890 * SetTextJustification (GDI32.@)
892 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
895 DC * dc = DC_GetDCPtr( hdc );
896 if (!dc) return FALSE;
897 if (dc->funcs->pSetTextJustification)
898 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
901 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
902 if (!extra) breaks = 0;
903 dc->breakTotalExtra = extra;
904 dc->breakCount = breaks;
907 dc->breakExtra = extra / breaks;
908 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
916 GDI_ReleaseObj( hdc );
921 /***********************************************************************
922 * GetTextFaceA (GDI32.@)
924 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
926 INT res = GetTextFaceW(hdc, 0, NULL);
927 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
928 GetTextFaceW( hdc, res, nameW );
932 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
937 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
938 HeapFree( GetProcessHeap(), 0, nameW );
942 /***********************************************************************
943 * GetTextFaceW (GDI32.@)
945 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
950 DC * dc = DC_GetDCPtr( hdc );
954 ret = WineEngGetTextFace(dc->gdiFont, count, name);
955 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
959 lstrcpynW( name, font->logfont.lfFaceName, count );
962 else ret = strlenW(font->logfont.lfFaceName) + 1;
963 GDI_ReleaseObj( dc->hFont );
965 GDI_ReleaseObj( hdc );
970 /***********************************************************************
971 * GetTextExtentPoint32A (GDI32.@)
973 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
978 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
981 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
982 HeapFree( GetProcessHeap(), 0, p );
985 TRACE("(%p %s %d %p): returning %ld x %ld\n",
986 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
991 /***********************************************************************
992 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
994 * Computes width and height of the specified string.
1000 BOOL WINAPI GetTextExtentPoint32W(
1001 HDC hdc, /* [in] Handle of device context */
1002 LPCWSTR str, /* [in] Address of text string */
1003 INT count, /* [in] Number of characters in string */
1004 LPSIZE size) /* [out] Address of structure for string size */
1007 DC * dc = DC_GetDCPtr( hdc );
1008 if (!dc) return FALSE;
1011 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1012 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1013 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1014 size->cx += count * dc->charExtra;
1016 else if(dc->funcs->pGetTextExtentPoint)
1017 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1019 GDI_ReleaseObj( hdc );
1021 TRACE("(%p %s %d %p): returning %ld x %ld\n",
1022 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1026 /***********************************************************************
1027 * GetTextExtentPointI [GDI32.@]
1029 * Computes width and height of the array of glyph indices.
1035 BOOL WINAPI GetTextExtentPointI(
1036 HDC hdc, /* [in] Handle of device context */
1037 const WORD *indices, /* [in] Address of glyph index array */
1038 INT count, /* [in] Number of glyphs in array */
1039 LPSIZE size) /* [out] Address of structure for string size */
1042 DC * dc = DC_GetDCPtr( hdc );
1043 if (!dc) return FALSE;
1046 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1047 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1048 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1049 size->cx += count * dc->charExtra;
1051 else if(dc->funcs->pGetTextExtentPoint) {
1052 FIXME("calling GetTextExtentPoint\n");
1053 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1056 GDI_ReleaseObj( hdc );
1058 TRACE("(%p %p %d %p): returning %ld x %ld\n",
1059 hdc, indices, count, size, size->cx, size->cy );
1064 /***********************************************************************
1065 * GetTextExtentPointA (GDI32.@)
1067 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1070 TRACE("not bug compatible.\n");
1071 return GetTextExtentPoint32A( hdc, str, count, size );
1074 /***********************************************************************
1075 * GetTextExtentPointW (GDI32.@)
1077 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1080 TRACE("not bug compatible.\n");
1081 return GetTextExtentPoint32W( hdc, str, count, size );
1085 /***********************************************************************
1086 * GetTextExtentExPointA (GDI32.@)
1088 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1089 INT maxExt, LPINT lpnFit,
1090 LPINT alpDx, LPSIZE size )
1094 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1095 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1096 if (lpnFit) *lpnFit = WideCharToMultiByte(CP_ACP,0,p,*lpnFit,NULL,0,NULL,NULL);
1097 HeapFree( GetProcessHeap(), 0, p );
1102 /***********************************************************************
1103 * GetTextExtentExPointW (GDI32.@)
1105 * Return the size of the string as it would be if it was output properly by
1108 * This should include
1109 * - Intercharacter spacing
1110 * - justification spacing (not yet done)
1111 * - kerning? see below
1113 * Kerning. Since kerning would be carried out by the rendering code it should
1114 * be done by the driver. However they don't support it yet. Also I am not
1115 * yet persuaded that (certainly under Win95) any kerning is actually done.
1117 * str: According to MSDN this should be null-terminated. That is not true; a
1118 * null will not terminate it early.
1119 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1120 * than count. I have seen it be either the size of the full string or
1121 * 1 less than the size of the full string. I have not seen it bear any
1122 * resemblance to the portion that would fit.
1123 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1124 * trailing intercharacter spacing and any trailing justification.
1127 * Currently we do this by measuring each character etc. We should do it by
1128 * passing the request to the driver, perhaps by extending the
1129 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1130 * thinking about kerning issues and rounding issues in the justification.
1133 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1134 INT maxExt, LPINT lpnFit,
1135 LPINT alpDx, LPSIZE size )
1137 int index, nFit, extent;
1141 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1143 size->cx = size->cy = nFit = extent = 0;
1144 for(index = 0; index < count; index++)
1146 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1147 /* GetTextExtentPoint includes intercharacter spacing. */
1148 /* FIXME - justification needs doing yet. Remember that the base
1149 * data will not be in logical coordinates.
1152 if( !lpnFit || extent <= maxExt )
1153 /* It is allowed to be equal. */
1156 if( alpDx ) alpDx[index] = extent;
1158 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1162 if(lpnFit) *lpnFit = nFit;
1165 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1171 /***********************************************************************
1172 * GetTextMetricsA (GDI32.@)
1174 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1178 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1179 FONT_TextMetricWToA( &tm32, metrics );
1183 /***********************************************************************
1184 * GetTextMetricsW (GDI32.@)
1186 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1189 DC * dc = DC_GetDCPtr( hdc );
1190 if (!dc) return FALSE;
1193 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1194 else if (dc->funcs->pGetTextMetrics)
1195 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1199 /* device layer returns values in device units
1200 * therefore we have to convert them to logical */
1202 #define WDPTOLP(x) ((x<0)? \
1203 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1204 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1205 #define HDPTOLP(y) ((y<0)? \
1206 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1207 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1209 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1210 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1211 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1212 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1213 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1214 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1215 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1216 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1220 TRACE("text metrics:\n"
1221 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1222 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1223 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1224 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1225 " PitchAndFamily = %02x\n"
1226 " --------------------\n"
1227 " InternalLeading = %li\n"
1231 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1232 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1233 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1234 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1235 metrics->tmPitchAndFamily,
1236 metrics->tmInternalLeading,
1239 metrics->tmHeight );
1241 GDI_ReleaseObj( hdc );
1246 /***********************************************************************
1247 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1250 * lpOTM should be LPOUTLINETEXTMETRIC
1253 * Success: Non-zero or size of required buffer
1256 UINT16 WINAPI GetOutlineTextMetrics16(
1257 HDC16 hdc, /* [in] Handle of device context */
1258 UINT16 cbData, /* [in] Size of metric data array */
1259 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1261 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1266 /***********************************************************************
1267 * GetOutlineTextMetricsA (GDI32.@)
1268 * Gets metrics for TrueType fonts.
1271 * If the supplied buffer isn't big enough Windows partially fills it up to
1272 * its given length and returns that length.
1275 * Success: Non-zero or size of required buffer
1278 UINT WINAPI GetOutlineTextMetricsA(
1279 HDC hdc, /* [in] Handle of device context */
1280 UINT cbData, /* [in] Size of metric data array */
1281 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1283 char buf[512], *ptr;
1285 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1286 OUTLINETEXTMETRICA *output = lpOTM;
1289 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1291 if(ret > sizeof(buf))
1292 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1293 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1295 needed = sizeof(OUTLINETEXTMETRICA);
1296 if(lpOTMW->otmpFamilyName)
1297 needed += WideCharToMultiByte(CP_ACP, 0,
1298 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1299 NULL, 0, NULL, NULL);
1300 if(lpOTMW->otmpFaceName)
1301 needed += WideCharToMultiByte(CP_ACP, 0,
1302 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1303 NULL, 0, NULL, NULL);
1304 if(lpOTMW->otmpStyleName)
1305 needed += WideCharToMultiByte(CP_ACP, 0,
1306 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1307 NULL, 0, NULL, NULL);
1308 if(lpOTMW->otmpFullName)
1309 needed += WideCharToMultiByte(CP_ACP, 0,
1310 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1311 NULL, 0, NULL, NULL);
1318 TRACE("needed = %d\n", needed);
1320 /* Since the supplied buffer isn't big enough, we'll alloc one
1321 that is and memcpy the first cbData bytes into the lpOTM at
1323 output = HeapAlloc(GetProcessHeap(), 0, needed);
1325 ret = output->otmSize = min(needed, cbData);
1326 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &output->otmTextMetrics );
1327 output->otmFiller = 0;
1328 output->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1329 output->otmfsSelection = lpOTMW->otmfsSelection;
1330 output->otmfsType = lpOTMW->otmfsType;
1331 output->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1332 output->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1333 output->otmItalicAngle = lpOTMW->otmItalicAngle;
1334 output->otmEMSquare = lpOTMW->otmEMSquare;
1335 output->otmAscent = lpOTMW->otmAscent;
1336 output->otmDescent = lpOTMW->otmDescent;
1337 output->otmLineGap = lpOTMW->otmLineGap;
1338 output->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1339 output->otmsXHeight = lpOTMW->otmsXHeight;
1340 output->otmrcFontBox = lpOTMW->otmrcFontBox;
1341 output->otmMacAscent = lpOTMW->otmMacAscent;
1342 output->otmMacDescent = lpOTMW->otmMacDescent;
1343 output->otmMacLineGap = lpOTMW->otmMacLineGap;
1344 output->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1345 output->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1346 output->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1347 output->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1348 output->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1349 output->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1350 output->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1351 output->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1352 output->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1355 ptr = (char*)(output + 1);
1356 left = needed - sizeof(*output);
1358 if(lpOTMW->otmpFamilyName) {
1359 output->otmpFamilyName = (LPSTR)(ptr - (char*)output);
1360 len = WideCharToMultiByte(CP_ACP, 0,
1361 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1362 ptr, left, NULL, NULL);
1366 output->otmpFamilyName = 0;
1368 if(lpOTMW->otmpFaceName) {
1369 output->otmpFaceName = (LPSTR)(ptr - (char*)output);
1370 len = WideCharToMultiByte(CP_ACP, 0,
1371 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1372 ptr, left, NULL, NULL);
1376 output->otmpFaceName = 0;
1378 if(lpOTMW->otmpStyleName) {
1379 output->otmpStyleName = (LPSTR)(ptr - (char*)output);
1380 len = WideCharToMultiByte(CP_ACP, 0,
1381 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1382 ptr, left, NULL, NULL);
1386 output->otmpStyleName = 0;
1388 if(lpOTMW->otmpFullName) {
1389 output->otmpFullName = (LPSTR)(ptr - (char*)output);
1390 len = WideCharToMultiByte(CP_ACP, 0,
1391 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1392 ptr, left, NULL, NULL);
1395 output->otmpFullName = 0;
1399 if(output != lpOTM) {
1400 memcpy(lpOTM, output, cbData);
1401 HeapFree(GetProcessHeap(), 0, output);
1405 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1406 HeapFree(GetProcessHeap(), 0, lpOTMW);
1412 /***********************************************************************
1413 * GetOutlineTextMetricsW [GDI32.@]
1415 UINT WINAPI GetOutlineTextMetricsW(
1416 HDC hdc, /* [in] Handle of device context */
1417 UINT cbData, /* [in] Size of metric data array */
1418 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1420 DC *dc = DC_GetDCPtr( hdc );
1421 OUTLINETEXTMETRICW *output = lpOTM;
1424 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1428 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, output);
1431 output = HeapAlloc(GetProcessHeap(), 0, ret);
1432 WineEngGetOutlineTextMetrics(dc->gdiFont, ret, output);
1435 #define WDPTOLP(x) ((x<0)? \
1436 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1437 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1438 #define HDPTOLP(y) ((y<0)? \
1439 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1440 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1442 output->otmTextMetrics.tmHeight = HDPTOLP(output->otmTextMetrics.tmHeight);
1443 output->otmTextMetrics.tmAscent = HDPTOLP(output->otmTextMetrics.tmAscent);
1444 output->otmTextMetrics.tmDescent = HDPTOLP(output->otmTextMetrics.tmDescent);
1445 output->otmTextMetrics.tmInternalLeading = HDPTOLP(output->otmTextMetrics.tmInternalLeading);
1446 output->otmTextMetrics.tmExternalLeading = HDPTOLP(output->otmTextMetrics.tmExternalLeading);
1447 output->otmTextMetrics.tmAveCharWidth = WDPTOLP(output->otmTextMetrics.tmAveCharWidth);
1448 output->otmTextMetrics.tmMaxCharWidth = WDPTOLP(output->otmTextMetrics.tmMaxCharWidth);
1449 output->otmTextMetrics.tmOverhang = WDPTOLP(output->otmTextMetrics.tmOverhang);
1450 output->otmAscent = HDPTOLP(output->otmAscent);
1451 output->otmDescent = HDPTOLP(output->otmDescent);
1452 output->otmLineGap = HDPTOLP(output->otmLineGap);
1453 output->otmsCapEmHeight = HDPTOLP(output->otmsCapEmHeight);
1454 output->otmsXHeight = HDPTOLP(output->otmsXHeight);
1455 output->otmrcFontBox.top = HDPTOLP(output->otmrcFontBox.top);
1456 output->otmrcFontBox.bottom = HDPTOLP(output->otmrcFontBox.bottom);
1457 output->otmrcFontBox.left = WDPTOLP(output->otmrcFontBox.left);
1458 output->otmrcFontBox.right = WDPTOLP(output->otmrcFontBox.right);
1459 output->otmMacAscent = HDPTOLP(output->otmMacAscent);
1460 output->otmMacDescent = HDPTOLP(output->otmMacDescent);
1461 output->otmMacLineGap = HDPTOLP(output->otmMacLineGap);
1462 output->otmptSubscriptSize.x = WDPTOLP(output->otmptSubscriptSize.x);
1463 output->otmptSubscriptSize.y = HDPTOLP(output->otmptSubscriptSize.y);
1464 output->otmptSubscriptOffset.x = WDPTOLP(output->otmptSubscriptOffset.x);
1465 output->otmptSubscriptOffset.y = HDPTOLP(output->otmptSubscriptOffset.y);
1466 output->otmptSuperscriptSize.x = WDPTOLP(output->otmptSuperscriptSize.x);
1467 output->otmptSuperscriptSize.y = HDPTOLP(output->otmptSuperscriptSize.y);
1468 output->otmptSuperscriptOffset.x = WDPTOLP(output->otmptSuperscriptOffset.x);
1469 output->otmptSuperscriptOffset.y = HDPTOLP(output->otmptSuperscriptOffset.y);
1470 output->otmsStrikeoutSize = HDPTOLP(output->otmsStrikeoutSize);
1471 output->otmsStrikeoutPosition = HDPTOLP(output->otmsStrikeoutPosition);
1472 output->otmsUnderscoreSize = HDPTOLP(output->otmsUnderscoreSize);
1473 output->otmsUnderscorePosition = HDPTOLP(output->otmsUnderscorePosition);
1476 if(output != lpOTM) {
1477 memcpy(lpOTM, output, cbData);
1478 HeapFree(GetProcessHeap(), 0, output);
1484 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1485 but really this should just be a return 0. */
1487 ret = sizeof(*lpOTM);
1492 memset(lpOTM, 0, ret);
1493 lpOTM->otmSize = sizeof(*lpOTM);
1494 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1496 Further fill of the structure not implemented,
1497 Needs real values for the structure members
1502 GDI_ReleaseObj(hdc);
1507 /***********************************************************************
1508 * GetCharWidthW (GDI32.@)
1509 * GetCharWidth32W (GDI32.@)
1511 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1516 DC * dc = DC_GetDCPtr( hdc );
1517 if (!dc) return FALSE;
1520 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1521 else if (dc->funcs->pGetCharWidth)
1522 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1526 /* convert device units to logical */
1527 for( i = firstChar; i <= lastChar; i++, buffer++ )
1528 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1531 GDI_ReleaseObj( hdc );
1536 /***********************************************************************
1537 * GetCharWidthA (GDI32.@)
1538 * GetCharWidth32A (GDI32.@)
1540 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1543 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1548 if(count <= 0) return FALSE;
1550 str = HeapAlloc(GetProcessHeap(), 0, count);
1551 for(i = 0; i < count; i++)
1552 str[i] = (BYTE)(firstChar + i);
1554 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1556 for(i = 0; i < wlen; i++)
1558 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1566 HeapFree(GetProcessHeap(), 0, str);
1567 HeapFree(GetProcessHeap(), 0, wstr);
1573 /* FIXME: all following APIs ******************************************/
1576 /***********************************************************************
1577 * SetMapperFlags (GDI32.@)
1579 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1581 DC *dc = DC_GetDCPtr( hDC );
1584 if(dc->funcs->pSetMapperFlags)
1585 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1587 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1588 GDI_ReleaseObj( hDC );
1592 /***********************************************************************
1593 * GetAspectRatioFilterEx (GDI.486)
1595 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1597 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1601 /***********************************************************************
1602 * GetAspectRatioFilterEx (GDI32.@)
1604 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1606 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1611 /***********************************************************************
1612 * GetCharABCWidthsA (GDI32.@)
1614 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1617 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1622 if(count <= 0) return FALSE;
1624 str = HeapAlloc(GetProcessHeap(), 0, count);
1625 for(i = 0; i < count; i++)
1626 str[i] = (BYTE)(firstChar + i);
1628 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1630 for(i = 0; i < wlen; i++)
1632 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1640 HeapFree(GetProcessHeap(), 0, str);
1641 HeapFree(GetProcessHeap(), 0, wstr);
1647 /******************************************************************************
1648 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1651 * hdc [I] Handle of device context
1652 * firstChar [I] First character in range to query
1653 * lastChar [I] Last character in range to query
1654 * abc [O] Address of character-width structure
1657 * Only works with TrueType fonts
1663 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1666 DC *dc = DC_GetDCPtr(hdc);
1672 for (i=firstChar;i<=lastChar;i++) {
1673 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1674 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1675 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1676 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1680 GDI_ReleaseObj(hdc);
1685 /***********************************************************************
1686 * GetGlyphOutline (GDI.309)
1688 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1689 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1690 LPVOID lpBuffer, const MAT2 *lpmat2 )
1692 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1693 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1694 return (DWORD)-1; /* failure */
1698 /***********************************************************************
1699 * GetGlyphOutlineA (GDI32.@)
1701 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1702 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1703 LPVOID lpBuffer, const MAT2 *lpmat2 )
1709 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1710 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1714 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1717 HeapFree(GetProcessHeap(), 0, p);
1721 /***********************************************************************
1722 * GetGlyphOutlineW (GDI32.@)
1724 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1725 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1726 LPVOID lpBuffer, const MAT2 *lpmat2 )
1728 DC *dc = DC_GetDCPtr(hdc);
1731 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1732 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1734 if(!dc) return GDI_ERROR;
1737 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1738 cbBuffer, lpBuffer, lpmat2);
1742 GDI_ReleaseObj(hdc);
1747 /***********************************************************************
1748 * CreateScalableFontResourceA (GDI32.@)
1750 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1751 LPCSTR lpszResourceFile,
1752 LPCSTR lpszFontFile,
1753 LPCSTR lpszCurrentPath )
1757 /* fHidden=1 - only visible for the calling app, read-only, not
1758 * enumbered with EnumFonts/EnumFontFamilies
1759 * lpszCurrentPath can be NULL
1761 FIXME("(%ld,%s,%s,%s): stub\n",
1762 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1763 debugstr_a(lpszCurrentPath) );
1765 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1766 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1768 SetLastError(ERROR_FILE_EXISTS);
1771 return FALSE; /* create failed */
1774 /***********************************************************************
1775 * CreateScalableFontResourceW (GDI32.@)
1777 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1778 LPCWSTR lpszResourceFile,
1779 LPCWSTR lpszFontFile,
1780 LPCWSTR lpszCurrentPath )
1782 FIXME("(%ld,%p,%p,%p): stub\n",
1783 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1784 return FALSE; /* create failed */
1788 /*************************************************************************
1789 * GetRasterizerCaps (GDI32.@)
1791 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1793 lprs->nSize = sizeof(RASTERIZER_STATUS);
1794 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1795 lprs->nLanguageID = 0;
1800 /*************************************************************************
1801 * GetKerningPairsA (GDI32.@)
1803 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1804 LPKERNINGPAIR lpKerningPairs )
1806 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1810 /*************************************************************************
1811 * GetKerningPairsW (GDI32.@)
1813 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1814 LPKERNINGPAIR lpKerningPairs )
1817 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1818 for (i = 0; i < cPairs; i++)
1819 lpKerningPairs[i].iKernAmount = 0;
1823 /*************************************************************************
1824 * TranslateCharsetInfo [GDI32.@]
1826 * Fills a CHARSETINFO structure for a character set, code page, or
1827 * font. This allows making the correspondance between different labelings
1828 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1829 * of the same encoding.
1831 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1832 * only one codepage should be set in *lpSrc.
1835 * TRUE on success, FALSE on failure.
1838 BOOL WINAPI TranslateCharsetInfo(
1839 LPDWORD lpSrc, /* [in]
1840 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1841 if flags == TCI_SRCCHARSET: a character set value
1842 if flags == TCI_SRCCODEPAGE: a code page value
1844 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1845 DWORD flags /* [in] determines interpretation of lpSrc */
1849 case TCI_SRCFONTSIG:
1850 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1852 case TCI_SRCCODEPAGE:
1853 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1855 case TCI_SRCCHARSET:
1856 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1861 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1862 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1866 /*************************************************************************
1867 * GetFontLanguageInfo (GDI32.@)
1869 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1871 FONTSIGNATURE fontsig;
1872 static const DWORD GCP_DBCS_MASK=0x003F0000,
1873 GCP_DIACRITIC_MASK=0x00000000,
1874 FLI_GLYPHS_MASK=0x00000000,
1875 GCP_GLYPHSHAPE_MASK=0x00000040,
1876 GCP_KASHIDA_MASK=0x00000000,
1877 GCP_LIGATE_MASK=0x00000000,
1878 GCP_USEKERNING_MASK=0x00000000,
1879 GCP_REORDER_MASK=0x00000060;
1883 GetTextCharsetInfo( hdc, &fontsig, 0 );
1884 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1886 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1889 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1890 result|=GCP_DIACRITIC;
1892 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1895 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1896 result|=GCP_GLYPHSHAPE;
1898 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1899 result|=GCP_KASHIDA;
1901 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1904 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1905 result|=GCP_USEKERNING;
1907 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1908 result|=GCP_REORDER;
1914 /*************************************************************************
1915 * GetFontData [GDI32.@] Retrieve data for TrueType font
1919 * success: Number of bytes returned
1920 * failure: GDI_ERROR
1924 * Calls SetLastError()
1927 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1928 LPVOID buffer, DWORD length)
1930 DC *dc = DC_GetDCPtr(hdc);
1931 DWORD ret = GDI_ERROR;
1933 if(!dc) return GDI_ERROR;
1936 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1938 GDI_ReleaseObj(hdc);
1942 /*************************************************************************
1943 * GetGlyphIndicesA [GDI32.@]
1945 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1946 LPWORD pgi, DWORD flags)
1952 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1953 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1955 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1956 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1957 HeapFree(GetProcessHeap(), 0, lpstrW);
1962 /*************************************************************************
1963 * GetGlyphIndicesW [GDI32.@]
1965 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1966 LPWORD pgi, DWORD flags)
1968 DC *dc = DC_GetDCPtr(hdc);
1969 DWORD ret = GDI_ERROR;
1971 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1972 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1974 if(!dc) return GDI_ERROR;
1977 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1979 GDI_ReleaseObj(hdc);
1983 /*************************************************************************
1984 * GetCharacterPlacementA [GDI32.@]
1987 * the web browser control of ie4 calls this with dwFlags=0
1990 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1991 INT nMaxExtent, GCP_RESULTSA *lpResults,
1996 GCP_RESULTSW resultsW;
2000 TRACE("%s, %d, %d, 0x%08lx\n",
2001 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2003 /* both structs are equal in size */
2004 memcpy(&resultsW, lpResults, sizeof(resultsW));
2006 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2007 if(lpResults->lpOutString)
2008 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
2010 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2012 if(lpResults->lpOutString) {
2013 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2014 lpResults->lpOutString, uCount, NULL, NULL );
2017 HeapFree(GetProcessHeap(), 0, lpStringW);
2018 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2023 /*************************************************************************
2024 * GetCharacterPlacementW [GDI32.@]
2026 * Retrieve information about a string. This includes the width, reordering,
2027 * Glyphing and so on.
2031 * The width and height of the string if successful, 0 if failed.
2035 * All flags except GCP_REORDER are not yet implemented.
2036 * Reordering is not 100% complient to the Windows BiDi method.
2037 * Caret positioning is not yet implemented for BiDi.
2038 * Classes are not yet implemented.
2042 GetCharacterPlacementW(
2043 HDC hdc, /* [in] Device context for which the rendering is to be done */
2044 LPCWSTR lpString, /* [in] The string for which information is to be returned */
2045 INT uCount, /* [in] Number of WORDS in string. */
2046 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
2047 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
2048 DWORD dwFlags /* [in] Flags specifying how to process the string */
2055 TRACE("%s, %d, %d, 0x%08lx\n",
2056 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2058 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2059 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2060 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2061 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2062 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2064 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2065 if(lpResults->lpClass) FIXME("classes not implemented\n");
2066 if (lpResults->lpCaretPos && (dwFlags & GCP_REORDER))
2067 FIXME("Caret positions for complex scripts not implemented\n");
2069 nSet = (UINT)uCount;
2070 if(nSet > lpResults->nGlyphs)
2071 nSet = lpResults->nGlyphs;
2073 /* return number of initialized fields */
2074 lpResults->nGlyphs = nSet;
2076 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
2078 /* Treat the case where no special handling was requested in a fastpath way */
2079 /* copy will do if the GCP_REORDER flag is not set */
2080 if(lpResults->lpOutString)
2081 strncpyW( lpResults->lpOutString, lpString, nSet );
2083 if(lpResults->lpOrder)
2085 for(i = 0; i < nSet; i++)
2086 lpResults->lpOrder[i] = i;
2090 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2091 nSet, lpResults->lpOrder );
2094 /* FIXME: Will use the placement chars */
2095 if (lpResults->lpDx)
2098 for (i = 0; i < nSet; i++)
2100 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2101 lpResults->lpDx[i]= c;
2105 if (lpResults->lpCaretPos && !(dwFlags & GCP_REORDER))
2109 lpResults->lpCaretPos[0] = 0;
2110 for (i = 1; i < nSet; i++)
2111 if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
2112 lpResults->lpCaretPos[i] = (pos += size.cx);
2115 if(lpResults->lpGlyphs)
2116 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2118 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2119 ret = MAKELONG(size.cx, size.cy);
2124 /*************************************************************************
2125 * GetCharABCWidthsFloatA [GDI32.@]
2127 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2130 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2134 /*************************************************************************
2135 * GetCharABCWidthsFloatW [GDI32.@]
2137 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2138 UINT iLastChar, LPABCFLOAT lpABCF)
2140 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2144 /*************************************************************************
2145 * GetCharWidthFloatA [GDI32.@]
2147 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2148 UINT iLastChar, PFLOAT pxBuffer)
2150 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2154 /*************************************************************************
2155 * GetCharWidthFloatW [GDI32.@]
2157 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2158 UINT iLastChar, PFLOAT pxBuffer)
2160 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2165 /***********************************************************************
2167 * Font Resource API *
2169 ***********************************************************************/
2171 /***********************************************************************
2172 * AddFontResourceA (GDI32.@)
2174 INT WINAPI AddFontResourceA( LPCSTR str )
2176 return AddFontResourceExA( str, 0, NULL);
2179 /***********************************************************************
2180 * AddFontResourceW (GDI32.@)
2182 INT WINAPI AddFontResourceW( LPCWSTR str )
2184 return AddFontResourceExW(str, 0, NULL);
2188 /***********************************************************************
2189 * AddFontResourceExA (GDI32.@)
2191 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2193 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2194 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2197 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2198 ret = AddFontResourceExW(strW, fl, pdv);
2199 HeapFree(GetProcessHeap(), 0, strW);
2203 /***********************************************************************
2204 * AddFontResourceExW (GDI32.@)
2206 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2208 return WineEngAddFontResourceEx(str, fl, pdv);
2211 /***********************************************************************
2212 * RemoveFontResourceA (GDI32.@)
2214 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2216 return RemoveFontResourceExA(str, 0, 0);
2219 /***********************************************************************
2220 * RemoveFontResourceW (GDI32.@)
2222 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2224 return RemoveFontResourceExW(str, 0, 0);
2227 /***********************************************************************
2228 * RemoveFontResourceExA (GDI32.@)
2230 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2232 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2233 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2236 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2237 ret = RemoveFontResourceExW(strW, fl, pdv);
2238 HeapFree(GetProcessHeap(), 0, strW);
2242 /***********************************************************************
2243 * RemoveFontResourceExW (GDI32.@)
2245 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2247 return WineEngRemoveFontResourceEx(str, fl, pdv);
2250 /***********************************************************************
2251 * GetTextCharset (GDI32.@)
2253 UINT WINAPI GetTextCharset(HDC hdc)
2255 /* MSDN docs say this is equivalent */
2256 return GetTextCharsetInfo(hdc, NULL, 0);
2259 /***********************************************************************
2260 * GetTextCharsetInfo (GDI32.@)
2262 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2264 UINT ret = DEFAULT_CHARSET;
2265 DC *dc = DC_GetDCPtr(hdc);
2270 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2272 GDI_ReleaseObj(hdc);
2275 if (ret == DEFAULT_CHARSET && fs)
2276 memset(fs, 0, sizeof(FONTSIGNATURE));