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 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
322 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
323 plf->lfHeight, plf->lfWidth,
324 plf->lfEscapement, plf->lfOrientation,
325 plf->lfPitchAndFamily,
326 plf->lfOutPrecision, plf->lfClipPrecision,
327 plf->lfQuality, plf->lfCharSet,
328 debugstr_w(plf->lfFaceName),
329 plf->lfWeight > 400 ? "Bold" : "",
330 plf->lfItalic ? "Italic" : "", hFont);
332 if (plf->lfEscapement != plf->lfOrientation) {
333 /* this should really depend on whether GM_ADVANCED is set */
334 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
335 WARN("orientation angle %f set to "
336 "escapement angle %f for new font %p\n",
337 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
339 GDI_ReleaseObj( hFont );
342 else WARN("(NULL) => NULL\n");
347 /*************************************************************************
348 * CreateFontA (GDI32.@)
350 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
351 INT orient, INT weight, DWORD italic,
352 DWORD underline, DWORD strikeout, DWORD charset,
353 DWORD outpres, DWORD clippres, DWORD quality,
354 DWORD pitch, LPCSTR name )
358 logfont.lfHeight = height;
359 logfont.lfWidth = width;
360 logfont.lfEscapement = esc;
361 logfont.lfOrientation = orient;
362 logfont.lfWeight = weight;
363 logfont.lfItalic = italic;
364 logfont.lfUnderline = underline;
365 logfont.lfStrikeOut = strikeout;
366 logfont.lfCharSet = charset;
367 logfont.lfOutPrecision = outpres;
368 logfont.lfClipPrecision = clippres;
369 logfont.lfQuality = quality;
370 logfont.lfPitchAndFamily = pitch;
373 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
375 logfont.lfFaceName[0] = '\0';
377 return CreateFontIndirectA( &logfont );
380 /*************************************************************************
381 * CreateFontW (GDI32.@)
383 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
384 INT orient, INT weight, DWORD italic,
385 DWORD underline, DWORD strikeout, DWORD charset,
386 DWORD outpres, DWORD clippres, DWORD quality,
387 DWORD pitch, LPCWSTR name )
391 logfont.lfHeight = height;
392 logfont.lfWidth = width;
393 logfont.lfEscapement = esc;
394 logfont.lfOrientation = orient;
395 logfont.lfWeight = weight;
396 logfont.lfItalic = italic;
397 logfont.lfUnderline = underline;
398 logfont.lfStrikeOut = strikeout;
399 logfont.lfCharSet = charset;
400 logfont.lfOutPrecision = outpres;
401 logfont.lfClipPrecision = clippres;
402 logfont.lfQuality = quality;
403 logfont.lfPitchAndFamily = pitch;
406 lstrcpynW(logfont.lfFaceName, name,
407 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
409 logfont.lfFaceName[0] = '\0';
411 return CreateFontIndirectW( &logfont );
415 /***********************************************************************
418 * If the driver supports vector fonts we create a gdi font first and
419 * then call the driver to give it a chance to supply its own device
420 * font. If the driver wants to do this it returns TRUE and we can
421 * delete the gdi font, if the driver wants to use the gdi font it
422 * should return FALSE, to signal an error return GDI_ERROR. For
423 * drivers that don't support vector fonts they must supply their own
426 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
429 DC *dc = DC_GetDCPtr( hdc );
433 if (dc->hFont != handle || dc->gdiFont == NULL)
435 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
436 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
439 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
441 if (ret && dc->gdiFont) dc->gdiFont = 0;
443 if (ret == HGDI_ERROR)
444 ret = 0; /* SelectObject returns 0 on error */
450 GDI_ReleaseObj( hdc );
455 /***********************************************************************
458 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
463 FONT_LogFontWTo16( &font->logfont, &lf16 );
465 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
466 memcpy( buffer, &lf16, count );
470 /***********************************************************************
473 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
480 FONT_LogFontWToA( &font->logfont, &lfA );
482 if (count > sizeof(lfA)) count = sizeof(lfA);
483 memcpy( buffer, &lfA, count );
487 /***********************************************************************
490 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
494 return sizeof(LOGFONTW);
495 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
496 memcpy( buffer, &font->logfont, count );
501 /***********************************************************************
504 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
506 WineEngDestroyFontInstance( handle );
507 return GDI_FreeObject( handle, obj );
511 /***********************************************************************
512 * FONT_EnumInstance16
514 * Called by the device driver layer to pass font info
515 * down to the application.
517 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
518 DWORD fType, LPARAM lp )
520 fontEnum16 *pfe = (fontEnum16*)lp;
524 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
525 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
530 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
531 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
532 pfe->dwFlags |= ENUM_CALLED;
533 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
535 args[6] = SELECTOROF(pfe->segLogFont);
536 args[5] = OFFSETOF(pfe->segLogFont);
537 args[4] = SELECTOROF(pfe->segTextMetric);
538 args[3] = OFFSETOF(pfe->segTextMetric);
540 args[1] = HIWORD(pfe->lpData);
541 args[0] = LOWORD(pfe->lpData);
542 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
543 ret = LOWORD(result);
545 /* get the lock again and make sure the DC is still valid */
546 dc = DC_GetDCPtr( pfe->hdc );
547 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
549 if (dc) GDI_ReleaseObj( pfe->hdc );
550 pfe->hdc = 0; /* make sure we don't try to release it later on */
557 /***********************************************************************
560 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
561 DWORD fType, LPARAM lp )
563 fontEnum32 *pfe = (fontEnum32*)lp;
567 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
568 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
569 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
571 /* convert font metrics */
572 ENUMLOGFONTEXA logfont;
573 NEWTEXTMETRICEXA tmA;
575 pfe->dwFlags |= ENUM_CALLED;
576 if (!(pfe->dwFlags & ENUM_UNICODE))
578 FONT_EnumLogFontExWToA( plf, &logfont);
579 FONT_NewTextMetricExWToA( ptm, &tmA );
580 plf = (LPENUMLOGFONTEXW)&logfont;
581 ptm = (NEWTEXTMETRICEXW *)&tmA;
583 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
585 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
587 /* get the lock again and make sure the DC is still valid */
588 dc = DC_GetDCPtr( pfe->hdc );
589 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
591 if (dc) GDI_ReleaseObj( pfe->hdc );
592 pfe->hdc = 0; /* make sure we don't try to release it later on */
599 /***********************************************************************
600 * EnumFontFamiliesEx (GDI.613)
602 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
603 FONTENUMPROC16 efproc, LPARAM lParam,
608 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
609 NEWTEXTMETRICEX16 tm16;
610 ENUMLOGFONTEX16 lf16;
615 FONT_LogFont16ToW(plf, &lfW);
617 fe16.hdc = HDC_32(hDC);
619 fe16.physDev = dc->physDev;
620 fe16.lpLogFontParam = plf;
621 fe16.lpEnumFunc = efproc;
622 fe16.lpData = lParam;
623 fe16.lpTextMetric = &tm16;
624 fe16.lpLogFont = &lf16;
625 fe16.segTextMetric = MapLS( &tm16 );
626 fe16.segLogFont = MapLS( &lf16 );
629 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
631 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
638 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
639 fe16.dwFlags &= ~ENUM_CALLED;
640 if (ret && dc->funcs->pEnumDeviceFonts) {
641 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
642 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
646 UnMapLS( fe16.segTextMetric );
647 UnMapLS( fe16.segLogFont );
648 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
652 /***********************************************************************
653 * FONT_EnumFontFamiliesEx
655 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
656 FONTENUMPROCW efproc,
657 LPARAM lParam, DWORD dwUnicode)
660 DC *dc = DC_GetDCPtr( hDC );
666 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
668 fe32.lpLogFontParam = plf;
669 fe32.lpEnumFunc = efproc;
670 fe32.lpData = lParam;
671 fe32.dwFlags = dwUnicode;
674 fe32.physDev = dc->physDev;
676 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
678 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
685 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
686 fe32.dwFlags &= ~ENUM_CALLED;
687 if (ret && dc->funcs->pEnumDeviceFonts) {
688 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
689 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
693 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
697 /***********************************************************************
698 * EnumFontFamiliesExW (GDI32.@)
700 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
701 FONTENUMPROCW efproc,
702 LPARAM lParam, DWORD dwFlags )
704 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
707 /***********************************************************************
708 * EnumFontFamiliesExA (GDI32.@)
710 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
711 FONTENUMPROCA efproc,
712 LPARAM lParam, DWORD dwFlags)
715 FONT_LogFontAToW( plf, &lfW );
717 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
720 /***********************************************************************
721 * EnumFontFamilies (GDI.330)
723 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
724 FONTENUMPROC16 efproc, LPARAM lpData )
728 lf.lfCharSet = DEFAULT_CHARSET;
729 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
730 else lf.lfFaceName[0] = '\0';
732 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
735 /***********************************************************************
736 * EnumFontFamiliesA (GDI32.@)
738 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
739 FONTENUMPROCA efproc, LPARAM lpData )
743 lf.lfCharSet = DEFAULT_CHARSET;
744 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
745 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
747 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
750 /***********************************************************************
751 * EnumFontFamiliesW (GDI32.@)
753 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
754 FONTENUMPROCW efproc, LPARAM lpData )
758 lf.lfCharSet = DEFAULT_CHARSET;
759 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
760 else lf.lfFaceName[0] = 0;
762 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
765 /***********************************************************************
768 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
771 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
774 /***********************************************************************
775 * EnumFontsA (GDI32.@)
777 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
780 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
783 /***********************************************************************
784 * EnumFontsW (GDI32.@)
786 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
789 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
793 /***********************************************************************
794 * GetTextCharacterExtra (GDI32.@)
796 INT WINAPI GetTextCharacterExtra( HDC hdc )
799 DC *dc = DC_GetDCPtr( hdc );
800 if (!dc) return 0x80000000;
802 GDI_ReleaseObj( hdc );
807 /***********************************************************************
808 * SetTextCharacterExtra (GDI32.@)
810 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
813 DC * dc = DC_GetDCPtr( hdc );
814 if (!dc) return 0x80000000;
815 if (dc->funcs->pSetTextCharacterExtra)
816 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
819 prev = dc->charExtra;
820 dc->charExtra = extra;
822 GDI_ReleaseObj( hdc );
827 /***********************************************************************
828 * SetTextJustification (GDI32.@)
830 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
833 DC * dc = DC_GetDCPtr( hdc );
834 if (!dc) return FALSE;
835 if (dc->funcs->pSetTextJustification)
836 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
839 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
840 if (!extra) breaks = 0;
841 dc->breakTotalExtra = extra;
842 dc->breakCount = breaks;
845 dc->breakExtra = extra / breaks;
846 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
854 GDI_ReleaseObj( hdc );
859 /***********************************************************************
860 * GetTextFaceA (GDI32.@)
862 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
864 INT res = GetTextFaceW(hdc, 0, NULL);
865 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
866 GetTextFaceW( hdc, res, nameW );
870 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
875 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
876 HeapFree( GetProcessHeap(), 0, nameW );
880 /***********************************************************************
881 * GetTextFaceW (GDI32.@)
883 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
888 DC * dc = DC_GetDCPtr( hdc );
892 ret = WineEngGetTextFace(dc->gdiFont, count, name);
893 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
897 lstrcpynW( name, font->logfont.lfFaceName, count );
900 else ret = strlenW(font->logfont.lfFaceName) + 1;
901 GDI_ReleaseObj( dc->hFont );
903 GDI_ReleaseObj( hdc );
908 /***********************************************************************
909 * GetTextExtentPoint32A (GDI32.@)
911 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
916 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
919 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
920 HeapFree( GetProcessHeap(), 0, p );
923 TRACE("(%p %s %d %p): returning %ld x %ld\n",
924 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
929 /***********************************************************************
930 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
932 * Computes width and height of the specified string.
938 BOOL WINAPI GetTextExtentPoint32W(
939 HDC hdc, /* [in] Handle of device context */
940 LPCWSTR str, /* [in] Address of text string */
941 INT count, /* [in] Number of characters in string */
942 LPSIZE size) /* [out] Address of structure for string size */
945 DC * dc = DC_GetDCPtr( hdc );
946 if (!dc) return FALSE;
949 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
950 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
951 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
953 else if(dc->funcs->pGetTextExtentPoint)
954 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
956 GDI_ReleaseObj( hdc );
958 TRACE("(%p %s %d %p): returning %ld x %ld\n",
959 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
963 /***********************************************************************
964 * GetTextExtentPointI [GDI32.@]
966 * Computes width and height of the array of glyph indices.
972 BOOL WINAPI GetTextExtentPointI(
973 HDC hdc, /* [in] Handle of device context */
974 const WORD *indices, /* [in] Address of glyph index array */
975 INT count, /* [in] Number of glyphs in array */
976 LPSIZE size) /* [out] Address of structure for string size */
979 DC * dc = DC_GetDCPtr( hdc );
980 if (!dc) return FALSE;
983 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
984 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
985 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
987 else if(dc->funcs->pGetTextExtentPoint) {
988 FIXME("calling GetTextExtentPoint\n");
989 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
992 GDI_ReleaseObj( hdc );
994 TRACE("(%p %p %d %p): returning %ld x %ld\n",
995 hdc, indices, count, size, size->cx, size->cy );
1000 /***********************************************************************
1001 * GetTextExtentPointA (GDI32.@)
1003 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1006 TRACE("not bug compatible.\n");
1007 return GetTextExtentPoint32A( hdc, str, count, size );
1010 /***********************************************************************
1011 * GetTextExtentPointW (GDI32.@)
1013 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1016 TRACE("not bug compatible.\n");
1017 return GetTextExtentPoint32W( hdc, str, count, size );
1021 /***********************************************************************
1022 * GetTextExtentExPointA (GDI32.@)
1024 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1025 INT maxExt, LPINT lpnFit,
1026 LPINT alpDx, LPSIZE size )
1030 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1031 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1032 HeapFree( GetProcessHeap(), 0, p );
1037 /***********************************************************************
1038 * GetTextExtentExPointW (GDI32.@)
1040 * Return the size of the string as it would be if it was output properly by
1043 * This should include
1044 * - Intercharacter spacing
1045 * - justification spacing (not yet done)
1046 * - kerning? see below
1048 * Kerning. Since kerning would be carried out by the rendering code it should
1049 * be done by the driver. However they don't support it yet. Also I am not
1050 * yet persuaded that (certainly under Win95) any kerning is actually done.
1052 * str: According to MSDN this should be null-terminated. That is not true; a
1053 * null will not terminate it early.
1054 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1055 * than count. I have seen it be either the size of the full string or
1056 * 1 less than the size of the full string. I have not seen it bear any
1057 * resemblance to the portion that would fit.
1058 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1059 * trailing intercharacter spacing and any trailing justification.
1062 * Currently we do this by measuring each character etc. We should do it by
1063 * passing the request to the driver, perhaps by extending the
1064 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1065 * thinking about kerning issues and rounding issues in the justification.
1068 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1069 INT maxExt, LPINT lpnFit,
1070 LPINT alpDx, LPSIZE size )
1072 int index, nFit, extent;
1076 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1078 size->cx = size->cy = nFit = extent = 0;
1079 for(index = 0; index < count; index++)
1081 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1082 /* GetTextExtentPoint includes intercharacter spacing. */
1083 /* FIXME - justification needs doing yet. Remember that the base
1084 * data will not be in logical coordinates.
1087 if( !lpnFit || extent <= maxExt )
1088 /* It is allowed to be equal. */
1091 if( alpDx ) alpDx[index] = extent;
1093 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1097 if(lpnFit) *lpnFit = nFit;
1100 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1106 /***********************************************************************
1107 * GetTextMetricsA (GDI32.@)
1109 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1113 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1114 FONT_TextMetricWToA( &tm32, metrics );
1118 /***********************************************************************
1119 * GetTextMetricsW (GDI32.@)
1121 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1124 DC * dc = DC_GetDCPtr( hdc );
1125 if (!dc) return FALSE;
1128 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1129 else if (dc->funcs->pGetTextMetrics)
1130 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1134 /* device layer returns values in device units
1135 * therefore we have to convert them to logical */
1137 #define WDPTOLP(x) ((x<0)? \
1138 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1139 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1140 #define HDPTOLP(y) ((y<0)? \
1141 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1142 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1144 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1145 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1146 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1147 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1148 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1149 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1150 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1151 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1155 TRACE("text metrics:\n"
1156 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1157 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1158 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1159 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1160 " PitchAndFamily = %02x\n"
1161 " --------------------\n"
1162 " InternalLeading = %li\n"
1166 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1167 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1168 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1169 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1170 metrics->tmPitchAndFamily,
1171 metrics->tmInternalLeading,
1174 metrics->tmHeight );
1176 GDI_ReleaseObj( hdc );
1181 /***********************************************************************
1182 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1185 * lpOTM should be LPOUTLINETEXTMETRIC
1188 * Success: Non-zero or size of required buffer
1191 UINT16 WINAPI GetOutlineTextMetrics16(
1192 HDC16 hdc, /* [in] Handle of device context */
1193 UINT16 cbData, /* [in] Size of metric data array */
1194 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1196 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1201 /***********************************************************************
1202 * GetOutlineTextMetricsA (GDI32.@)
1203 * Gets metrics for TrueType fonts.
1207 * Success: Non-zero or size of required buffer
1210 UINT WINAPI GetOutlineTextMetricsA(
1211 HDC hdc, /* [in] Handle of device context */
1212 UINT cbData, /* [in] Size of metric data array */
1213 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1215 char buf[512], *ptr;
1217 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1220 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1221 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1223 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1224 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1227 needed = sizeof(OUTLINETEXTMETRICA);
1228 if(lpOTMW->otmpFamilyName)
1229 needed += WideCharToMultiByte(CP_ACP, 0,
1230 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1231 NULL, 0, NULL, NULL);
1232 if(lpOTMW->otmpFaceName)
1233 needed += WideCharToMultiByte(CP_ACP, 0,
1234 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1235 NULL, 0, NULL, NULL);
1236 if(lpOTMW->otmpStyleName)
1237 needed += WideCharToMultiByte(CP_ACP, 0,
1238 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1239 NULL, 0, NULL, NULL);
1240 if(lpOTMW->otmpFullName)
1241 needed += WideCharToMultiByte(CP_ACP, 0,
1242 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1243 NULL, 0, NULL, NULL);
1250 if(needed > cbData) {
1256 lpOTM->otmSize = needed;
1257 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1258 lpOTM->otmFiller = 0;
1259 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1260 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1261 lpOTM->otmfsType = lpOTMW->otmfsType;
1262 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1263 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1264 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1265 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1266 lpOTM->otmAscent = lpOTMW->otmAscent;
1267 lpOTM->otmDescent = lpOTMW->otmDescent;
1268 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1269 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1270 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1271 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1272 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1273 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1274 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1275 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1276 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1277 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1278 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1279 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1280 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1281 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1282 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1283 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1286 ptr = (char*)(lpOTM + 1);
1287 left = needed - sizeof(*lpOTM);
1289 if(lpOTMW->otmpFamilyName) {
1290 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1291 len = WideCharToMultiByte(CP_ACP, 0,
1292 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1293 ptr, left, NULL, NULL);
1297 lpOTM->otmpFamilyName = 0;
1299 if(lpOTMW->otmpFaceName) {
1300 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1301 len = WideCharToMultiByte(CP_ACP, 0,
1302 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1303 ptr, left, NULL, NULL);
1307 lpOTM->otmpFaceName = 0;
1309 if(lpOTMW->otmpStyleName) {
1310 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1311 len = WideCharToMultiByte(CP_ACP, 0,
1312 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1313 ptr, left, NULL, NULL);
1317 lpOTM->otmpStyleName = 0;
1319 if(lpOTMW->otmpFullName) {
1320 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1321 len = WideCharToMultiByte(CP_ACP, 0,
1322 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1323 ptr, left, NULL, NULL);
1326 lpOTM->otmpFullName = 0;
1333 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1334 HeapFree(GetProcessHeap(), 0, lpOTMW);
1340 /***********************************************************************
1341 * GetOutlineTextMetricsW [GDI32.@]
1343 UINT WINAPI GetOutlineTextMetricsW(
1344 HDC hdc, /* [in] Handle of device context */
1345 UINT cbData, /* [in] Size of metric data array */
1346 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1348 DC *dc = DC_GetDCPtr( hdc );
1351 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1355 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1356 if(ret && ret <= cbData) {
1357 #define WDPTOLP(x) ((x<0)? \
1358 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1359 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1360 #define HDPTOLP(y) ((y<0)? \
1361 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1362 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1364 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1365 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1366 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1367 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1368 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1369 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1370 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1371 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1372 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1373 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1374 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1375 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1376 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1377 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1378 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1379 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1380 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1381 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1382 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1383 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1384 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1385 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1386 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1387 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1388 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1389 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1390 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1391 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1392 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1393 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1394 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1395 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1401 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1402 but really this should just be a return 0. */
1404 ret = sizeof(*lpOTM);
1409 memset(lpOTM, 0, ret);
1410 lpOTM->otmSize = sizeof(*lpOTM);
1411 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1413 Further fill of the structure not implemented,
1414 Needs real values for the structure members
1419 GDI_ReleaseObj(hdc);
1424 /***********************************************************************
1425 * GetCharWidthW (GDI32.@)
1426 * GetCharWidth32W (GDI32.@)
1428 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1433 DC * dc = DC_GetDCPtr( hdc );
1434 if (!dc) return FALSE;
1437 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1438 else if (dc->funcs->pGetCharWidth)
1439 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1443 /* convert device units to logical */
1444 for( i = firstChar; i <= lastChar; i++, buffer++ )
1445 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1448 GDI_ReleaseObj( hdc );
1453 /***********************************************************************
1454 * GetCharWidthA (GDI32.@)
1455 * GetCharWidth32A (GDI32.@)
1457 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1460 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1465 if(count <= 0) return FALSE;
1467 str = HeapAlloc(GetProcessHeap(), 0, count);
1468 for(i = 0; i < count; i++)
1469 str[i] = (BYTE)(firstChar + i);
1471 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1473 for(i = 0; i < wlen; i++)
1475 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1483 HeapFree(GetProcessHeap(), 0, str);
1484 HeapFree(GetProcessHeap(), 0, wstr);
1490 /* FIXME: all following APIs ******************************************/
1493 /***********************************************************************
1494 * SetMapperFlags (GDI32.@)
1496 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1498 DC *dc = DC_GetDCPtr( hDC );
1501 if(dc->funcs->pSetMapperFlags)
1502 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1504 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1505 GDI_ReleaseObj( hDC );
1509 /***********************************************************************
1510 * GetAspectRatioFilterEx (GDI.486)
1512 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1514 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1518 /***********************************************************************
1519 * GetAspectRatioFilterEx (GDI32.@)
1521 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1523 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1528 /***********************************************************************
1529 * GetCharABCWidthsA (GDI32.@)
1531 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1534 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1539 if(count <= 0) return FALSE;
1541 str = HeapAlloc(GetProcessHeap(), 0, count);
1542 for(i = 0; i < count; i++)
1543 str[i] = (BYTE)(firstChar + i);
1545 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1547 for(i = 0; i < wlen; i++)
1549 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1557 HeapFree(GetProcessHeap(), 0, str);
1558 HeapFree(GetProcessHeap(), 0, wstr);
1564 /******************************************************************************
1565 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1568 * hdc [I] Handle of device context
1569 * firstChar [I] First character in range to query
1570 * lastChar [I] Last character in range to query
1571 * abc [O] Address of character-width structure
1574 * Only works with TrueType fonts
1580 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1583 DC *dc = DC_GetDCPtr(hdc);
1589 for (i=firstChar;i<=lastChar;i++) {
1590 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1591 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1592 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1593 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1597 GDI_ReleaseObj(hdc);
1602 /***********************************************************************
1603 * GetGlyphOutline (GDI.309)
1605 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1606 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1607 LPVOID lpBuffer, const MAT2 *lpmat2 )
1609 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1610 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1611 return (DWORD)-1; /* failure */
1615 /***********************************************************************
1616 * GetGlyphOutlineA (GDI32.@)
1618 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1619 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1620 LPVOID lpBuffer, const MAT2 *lpmat2 )
1626 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1627 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1631 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1634 HeapFree(GetProcessHeap(), 0, p);
1638 /***********************************************************************
1639 * GetGlyphOutlineW (GDI32.@)
1641 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1642 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1643 LPVOID lpBuffer, const MAT2 *lpmat2 )
1645 DC *dc = DC_GetDCPtr(hdc);
1648 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1649 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1651 if(!dc) return GDI_ERROR;
1654 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1655 cbBuffer, lpBuffer, lpmat2);
1659 GDI_ReleaseObj(hdc);
1664 /***********************************************************************
1665 * CreateScalableFontResourceA (GDI32.@)
1667 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1668 LPCSTR lpszResourceFile,
1669 LPCSTR lpszFontFile,
1670 LPCSTR lpszCurrentPath )
1674 /* fHidden=1 - only visible for the calling app, read-only, not
1675 * enumbered with EnumFonts/EnumFontFamilies
1676 * lpszCurrentPath can be NULL
1678 FIXME("(%ld,%s,%s,%s): stub\n",
1679 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1680 debugstr_a(lpszCurrentPath) );
1682 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1683 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1685 SetLastError(ERROR_FILE_EXISTS);
1688 return FALSE; /* create failed */
1691 /***********************************************************************
1692 * CreateScalableFontResourceW (GDI32.@)
1694 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1695 LPCWSTR lpszResourceFile,
1696 LPCWSTR lpszFontFile,
1697 LPCWSTR lpszCurrentPath )
1699 FIXME("(%ld,%p,%p,%p): stub\n",
1700 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1701 return FALSE; /* create failed */
1705 /*************************************************************************
1706 * GetRasterizerCaps (GDI32.@)
1708 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1710 lprs->nSize = sizeof(RASTERIZER_STATUS);
1711 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1712 lprs->nLanguageID = 0;
1717 /*************************************************************************
1718 * GetKerningPairsA (GDI32.@)
1720 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1721 LPKERNINGPAIR lpKerningPairs )
1723 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1727 /*************************************************************************
1728 * GetKerningPairsW (GDI32.@)
1730 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1731 LPKERNINGPAIR lpKerningPairs )
1734 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1735 for (i = 0; i < cPairs; i++)
1736 lpKerningPairs[i].iKernAmount = 0;
1740 /*************************************************************************
1741 * TranslateCharsetInfo [GDI32.@]
1743 * Fills a CHARSETINFO structure for a character set, code page, or
1744 * font. This allows making the correspondance between different labelings
1745 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1746 * of the same encoding.
1748 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1749 * only one codepage should be set in *lpSrc.
1752 * TRUE on success, FALSE on failure.
1755 BOOL WINAPI TranslateCharsetInfo(
1756 LPDWORD lpSrc, /* [in]
1757 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1758 if flags == TCI_SRCCHARSET: a character set value
1759 if flags == TCI_SRCCODEPAGE: a code page value
1761 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1762 DWORD flags /* [in] determines interpretation of lpSrc */
1766 case TCI_SRCFONTSIG:
1767 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1769 case TCI_SRCCODEPAGE:
1770 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1772 case TCI_SRCCHARSET:
1773 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1778 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1779 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1783 /*************************************************************************
1784 * GetFontLanguageInfo (GDI32.@)
1786 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1788 FONTSIGNATURE fontsig;
1789 static const DWORD GCP_DBCS_MASK=0x003F0000,
1790 GCP_DIACRITIC_MASK=0x00000000,
1791 FLI_GLYPHS_MASK=0x00000000,
1792 GCP_GLYPHSHAPE_MASK=0x00000040,
1793 GCP_KASHIDA_MASK=0x00000000,
1794 GCP_LIGATE_MASK=0x00000000,
1795 GCP_USEKERNING_MASK=0x00000000,
1796 GCP_REORDER_MASK=0x00000060;
1800 GetTextCharsetInfo( hdc, &fontsig, 0 );
1801 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1803 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1806 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1807 result|=GCP_DIACRITIC;
1809 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1812 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1813 result|=GCP_GLYPHSHAPE;
1815 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1816 result|=GCP_KASHIDA;
1818 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1821 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1822 result|=GCP_USEKERNING;
1824 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1825 result|=GCP_REORDER;
1831 /*************************************************************************
1832 * GetFontData [GDI32.@] Retrieve data for TrueType font
1836 * success: Number of bytes returned
1837 * failure: GDI_ERROR
1841 * Calls SetLastError()
1844 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1845 LPVOID buffer, DWORD length)
1847 DC *dc = DC_GetDCPtr(hdc);
1848 DWORD ret = GDI_ERROR;
1850 if(!dc) return GDI_ERROR;
1853 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1855 GDI_ReleaseObj(hdc);
1859 /*************************************************************************
1860 * GetGlyphIndicesA [GDI32.@]
1862 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1863 LPWORD pgi, DWORD flags)
1869 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1870 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1872 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1873 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1874 HeapFree(GetProcessHeap(), 0, lpstrW);
1879 /*************************************************************************
1880 * GetGlyphIndicesW [GDI32.@]
1882 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1883 LPWORD pgi, DWORD flags)
1885 DC *dc = DC_GetDCPtr(hdc);
1886 DWORD ret = GDI_ERROR;
1888 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1889 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1891 if(!dc) return GDI_ERROR;
1894 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1896 GDI_ReleaseObj(hdc);
1900 /*************************************************************************
1901 * GetCharacterPlacementA [GDI32.@]
1904 * the web browser control of ie4 calls this with dwFlags=0
1907 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1908 INT nMaxExtent, GCP_RESULTSA *lpResults,
1913 GCP_RESULTSW resultsW;
1917 TRACE("%s, %d, %d, 0x%08lx\n",
1918 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1920 /* both structs are equal in size */
1921 memcpy(&resultsW, lpResults, sizeof(resultsW));
1923 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1924 if(lpResults->lpOutString)
1925 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1927 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1929 if(lpResults->lpOutString) {
1930 if(font_cp != CP_SYMBOL)
1931 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1932 lpResults->lpOutString, uCount, NULL, NULL );
1934 for(i = 0; i < uCount; i++)
1935 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1938 HeapFree(GetProcessHeap(), 0, lpStringW);
1939 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1944 /*************************************************************************
1945 * GetCharacterPlacementW [GDI32.@]
1947 * Retrieve information about a string. This includes the width, reordering,
1948 * Glyphing and so on.
1952 * The width and height of the string if successful, 0 if failed.
1956 * All flags except GCP_REORDER are not yet implemented.
1957 * Reordering is not 100% complient to the Windows BiDi method.
1958 * Caret positioning is not yet implemented.
1959 * Classes are not yet implemented.
1963 GetCharacterPlacementW(
1964 HDC hdc, /* [in] Device context for which the rendering is to be done */
1965 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1966 INT uCount, /* [in] Number of WORDS in string. */
1967 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1968 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1969 DWORD dwFlags /* [in] Flags specifying how to process the string */
1976 TRACE("%s, %d, %d, 0x%08lx\n",
1977 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1979 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1980 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1981 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1982 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1983 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1985 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1986 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1987 if(lpResults->lpClass) FIXME("classes not implemented\n");
1989 nSet = (UINT)uCount;
1990 if(nSet > lpResults->nGlyphs)
1991 nSet = lpResults->nGlyphs;
1993 /* return number of initialized fields */
1994 lpResults->nGlyphs = nSet;
1996 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1998 /* Treat the case where no special handling was requested in a fastpath way */
1999 /* copy will do if the GCP_REORDER flag is not set */
2000 if(lpResults->lpOutString)
2001 strncpyW( lpResults->lpOutString, lpString, nSet );
2003 if(lpResults->lpOrder)
2005 for(i = 0; i < nSet; i++)
2006 lpResults->lpOrder[i] = i;
2010 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2011 nSet, lpResults->lpOrder );
2014 /* FIXME: Will use the placement chars */
2015 if (lpResults->lpDx)
2018 for (i = 0; i < nSet; i++)
2020 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2021 lpResults->lpDx[i]= c;
2025 if(lpResults->lpGlyphs)
2026 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2028 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2029 ret = MAKELONG(size.cx, size.cy);
2034 /*************************************************************************
2035 * GetCharABCWidthsFloatA [GDI32.@]
2037 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2040 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2044 /*************************************************************************
2045 * GetCharABCWidthsFloatW [GDI32.@]
2047 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2048 UINT iLastChar, LPABCFLOAT lpABCF)
2050 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2054 /*************************************************************************
2055 * GetCharWidthFloatA [GDI32.@]
2057 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2058 UINT iLastChar, PFLOAT pxBuffer)
2060 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2064 /*************************************************************************
2065 * GetCharWidthFloatW [GDI32.@]
2067 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2068 UINT iLastChar, PFLOAT pxBuffer)
2070 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2075 /***********************************************************************
2077 * Font Resource API *
2079 ***********************************************************************/
2081 /***********************************************************************
2082 * AddFontResourceA (GDI32.@)
2084 INT WINAPI AddFontResourceA( LPCSTR str )
2086 return AddFontResourceExA( str, 0, NULL);
2089 /***********************************************************************
2090 * AddFontResourceW (GDI32.@)
2092 INT WINAPI AddFontResourceW( LPCWSTR str )
2094 return AddFontResourceExW(str, 0, NULL);
2098 /***********************************************************************
2099 * AddFontResourceExA (GDI32.@)
2101 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2103 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2104 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2107 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2108 ret = AddFontResourceExW(strW, fl, pdv);
2109 HeapFree(GetProcessHeap(), 0, strW);
2113 /***********************************************************************
2114 * AddFontResourceExW (GDI32.@)
2116 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2118 return WineEngAddFontResourceEx(str, fl, pdv);
2121 /***********************************************************************
2122 * RemoveFontResourceA (GDI32.@)
2124 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2126 return RemoveFontResourceExA(str, 0, 0);
2129 /***********************************************************************
2130 * RemoveFontResourceW (GDI32.@)
2132 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2134 return RemoveFontResourceExW(str, 0, 0);
2137 /***********************************************************************
2138 * RemoveFontResourceExA (GDI32.@)
2140 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2142 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2143 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2146 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2147 ret = RemoveFontResourceExW(strW, fl, pdv);
2148 HeapFree(GetProcessHeap(), 0, strW);
2152 /***********************************************************************
2153 * RemoveFontResourceExW (GDI32.@)
2155 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2157 return WineEngRemoveFontResourceEx(str, fl, pdv);
2160 /***********************************************************************
2161 * GetTextCharset (GDI32.@)
2163 UINT WINAPI GetTextCharset(HDC hdc)
2165 /* MSDN docs say this is equivalent */
2166 return GetTextCharsetInfo(hdc, NULL, 0);
2169 /***********************************************************************
2170 * GetTextCharsetInfo (GDI32.@)
2172 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2174 UINT ret = DEFAULT_CHARSET;
2175 DC *dc = DC_GetDCPtr(hdc);
2180 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2182 GDI_ReleaseObj(hdc);
2185 if (ret == DEFAULT_CHARSET && fs)
2186 memset(fs, 0, sizeof(FONTSIGNATURE));