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"
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(font);
37 WINE_DECLARE_DEBUG_CHANNEL(gdi);
39 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
40 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
43 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
45 static const struct gdi_obj_funcs font_funcs =
47 FONT_SelectObject, /* pSelectObject */
48 FONT_GetObject16, /* pGetObject16 */
49 FONT_GetObjectA, /* pGetObjectA */
50 FONT_GetObjectW, /* pGetObjectW */
51 NULL, /* pUnrealizeObject */
52 FONT_DeleteObject /* pDeleteObject */
55 #define ENUM_UNICODE 0x00000001
56 #define ENUM_CALLED 0x00000002
66 LPLOGFONT16 lpLogFontParam;
67 FONTENUMPROC16 lpEnumFunc;
70 LPNEWTEXTMETRICEX16 lpTextMetric;
71 LPENUMLOGFONTEX16 lpLogFont;
82 LPLOGFONTW lpLogFontParam;
83 FONTENUMPROCW lpEnumFunc;
92 * For TranslateCharsetInfo
94 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
95 #define MAXTCIINDEX 32
96 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
98 { ANSI_CHARSET, 1252, FS(0)},
99 { EASTEUROPE_CHARSET, 1250, FS(1)},
100 { RUSSIAN_CHARSET, 1251, FS(2)},
101 { GREEK_CHARSET, 1253, FS(3)},
102 { TURKISH_CHARSET, 1254, FS(4)},
103 { HEBREW_CHARSET, 1255, FS(5)},
104 { ARABIC_CHARSET, 1256, FS(6)},
105 { BALTIC_CHARSET, 1257, FS(7)},
106 { VIETNAMESE_CHARSET, 1258, FS(8)},
107 /* reserved by ANSI */
108 { DEFAULT_CHARSET, 0, FS(0)},
109 { DEFAULT_CHARSET, 0, FS(0)},
110 { DEFAULT_CHARSET, 0, FS(0)},
111 { DEFAULT_CHARSET, 0, FS(0)},
112 { DEFAULT_CHARSET, 0, FS(0)},
113 { DEFAULT_CHARSET, 0, FS(0)},
114 { DEFAULT_CHARSET, 0, FS(0)},
116 { THAI_CHARSET, 874, FS(16)},
117 { SHIFTJIS_CHARSET, 932, FS(17)},
118 { GB2312_CHARSET, 936, FS(18)},
119 { HANGEUL_CHARSET, 949, FS(19)},
120 { CHINESEBIG5_CHARSET, 950, FS(20)},
121 { JOHAB_CHARSET, 1361, FS(21)},
122 /* reserved for alternate ANSI and OEM */
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
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 /* reserved for system */
132 { DEFAULT_CHARSET, 0, FS(0)},
133 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
136 /***********************************************************************
137 * LOGFONT conversion functions.
139 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
141 font16->lfHeight = font32->lfHeight;
142 font16->lfWidth = font32->lfWidth;
143 font16->lfEscapement = font32->lfEscapement;
144 font16->lfOrientation = font32->lfOrientation;
145 font16->lfWeight = font32->lfWeight;
146 font16->lfItalic = font32->lfItalic;
147 font16->lfUnderline = font32->lfUnderline;
148 font16->lfStrikeOut = font32->lfStrikeOut;
149 font16->lfCharSet = font32->lfCharSet;
150 font16->lfOutPrecision = font32->lfOutPrecision;
151 font16->lfClipPrecision = font32->lfClipPrecision;
152 font16->lfQuality = font32->lfQuality;
153 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
154 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
155 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
156 font16->lfFaceName[LF_FACESIZE-1] = 0;
159 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
161 font32->lfHeight = font16->lfHeight;
162 font32->lfWidth = font16->lfWidth;
163 font32->lfEscapement = font16->lfEscapement;
164 font32->lfOrientation = font16->lfOrientation;
165 font32->lfWeight = font16->lfWeight;
166 font32->lfItalic = font16->lfItalic;
167 font32->lfUnderline = font16->lfUnderline;
168 font32->lfStrikeOut = font16->lfStrikeOut;
169 font32->lfCharSet = font16->lfCharSet;
170 font32->lfOutPrecision = font16->lfOutPrecision;
171 font32->lfClipPrecision = font16->lfClipPrecision;
172 font32->lfQuality = font16->lfQuality;
173 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
174 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
175 font32->lfFaceName[LF_FACESIZE-1] = 0;
178 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
180 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
181 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
185 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
187 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
188 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
189 LF_FACESIZE, NULL, NULL);
192 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
194 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
196 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
197 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
198 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
200 font16->elfStyle, LF_FACESIZE, NULL, NULL );
201 font16->elfStyle[LF_FACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
203 font16->elfScript, LF_FACESIZE, NULL, NULL );
204 font16->elfScript[LF_FACESIZE-1] = '\0';
207 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
209 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
211 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
212 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
213 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
215 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
216 fontA->elfStyle[LF_FACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
218 fontA->elfScript, LF_FACESIZE, NULL, NULL );
219 fontA->elfScript[LF_FACESIZE-1] = '\0';
222 /***********************************************************************
223 * TEXTMETRIC conversion functions.
225 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
227 ptmA->tmHeight = ptmW->tmHeight;
228 ptmA->tmAscent = ptmW->tmAscent;
229 ptmA->tmDescent = ptmW->tmDescent;
230 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
231 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
232 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
233 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
234 ptmA->tmWeight = ptmW->tmWeight;
235 ptmA->tmOverhang = ptmW->tmOverhang;
236 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
237 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
238 ptmA->tmFirstChar = ptmW->tmFirstChar > 255 ? 255 : ptmW->tmFirstChar;
239 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
240 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
241 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : ptmW->tmBreakChar;
242 ptmA->tmItalic = ptmW->tmItalic;
243 ptmA->tmUnderlined = ptmW->tmUnderlined;
244 ptmA->tmStruckOut = ptmW->tmStruckOut;
245 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
246 ptmA->tmCharSet = ptmW->tmCharSet;
250 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
252 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
253 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
254 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
255 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
256 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
257 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
258 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
259 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
260 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
261 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
262 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
263 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
264 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
265 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
266 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
267 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
268 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
269 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
270 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
271 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
272 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
273 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
274 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
275 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
276 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
279 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
281 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
282 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
283 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
284 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
285 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
286 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
289 /***********************************************************************
290 * CreateFontIndirectA (GDI32.@)
292 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
297 FONT_LogFontAToW( plfA, &lfW );
298 return CreateFontIndirectW( &lfW );
300 return CreateFontIndirectW( NULL );
304 /***********************************************************************
305 * CreateFontIndirectW (GDI32.@)
307 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
314 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
315 (HGDIOBJ *)&hFont, &font_funcs )))
317 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
319 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
320 plf->lfHeight, plf->lfWidth,
321 plf->lfEscapement, plf->lfOrientation,
322 plf->lfPitchAndFamily,
323 plf->lfOutPrecision, plf->lfClipPrecision,
324 plf->lfQuality, plf->lfCharSet,
325 debugstr_w(plf->lfFaceName),
326 plf->lfWeight > 400 ? "Bold" : "",
327 plf->lfItalic ? "Italic" : "", hFont);
329 if (plf->lfEscapement != plf->lfOrientation) {
330 /* this should really depend on whether GM_ADVANCED is set */
331 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
332 WARN("orientation angle %f set to "
333 "escapement angle %f for new font %p\n",
334 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
336 GDI_ReleaseObj( hFont );
339 else WARN("(NULL) => NULL\n");
344 /*************************************************************************
345 * CreateFontA (GDI32.@)
347 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
348 INT orient, INT weight, DWORD italic,
349 DWORD underline, DWORD strikeout, DWORD charset,
350 DWORD outpres, DWORD clippres, DWORD quality,
351 DWORD pitch, LPCSTR name )
355 logfont.lfHeight = height;
356 logfont.lfWidth = width;
357 logfont.lfEscapement = esc;
358 logfont.lfOrientation = orient;
359 logfont.lfWeight = weight;
360 logfont.lfItalic = italic;
361 logfont.lfUnderline = underline;
362 logfont.lfStrikeOut = strikeout;
363 logfont.lfCharSet = charset;
364 logfont.lfOutPrecision = outpres;
365 logfont.lfClipPrecision = clippres;
366 logfont.lfQuality = quality;
367 logfont.lfPitchAndFamily = pitch;
370 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
372 logfont.lfFaceName[0] = '\0';
374 return CreateFontIndirectA( &logfont );
377 /*************************************************************************
378 * CreateFontW (GDI32.@)
380 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
381 INT orient, INT weight, DWORD italic,
382 DWORD underline, DWORD strikeout, DWORD charset,
383 DWORD outpres, DWORD clippres, DWORD quality,
384 DWORD pitch, LPCWSTR name )
388 logfont.lfHeight = height;
389 logfont.lfWidth = width;
390 logfont.lfEscapement = esc;
391 logfont.lfOrientation = orient;
392 logfont.lfWeight = weight;
393 logfont.lfItalic = italic;
394 logfont.lfUnderline = underline;
395 logfont.lfStrikeOut = strikeout;
396 logfont.lfCharSet = charset;
397 logfont.lfOutPrecision = outpres;
398 logfont.lfClipPrecision = clippres;
399 logfont.lfQuality = quality;
400 logfont.lfPitchAndFamily = pitch;
403 lstrcpynW(logfont.lfFaceName, name,
404 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
406 logfont.lfFaceName[0] = '\0';
408 return CreateFontIndirectW( &logfont );
412 /***********************************************************************
415 * If the driver supports vector fonts we create a gdi font first and
416 * then call the driver to give it a chance to supply its own device
417 * font. If the driver wants to do this it returns TRUE and we can
418 * delete the gdi font, if the driver wants to use the gdi font it
419 * should return FALSE, to signal an error return GDI_ERROR. For
420 * drivers that don't support vector fonts they must supply their own
423 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
426 DC *dc = DC_GetDCPtr( hdc );
430 if (dc->hFont != handle || dc->gdiFont == NULL)
432 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
433 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
436 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
438 if (ret && dc->gdiFont) dc->gdiFont = 0;
440 if (ret == HGDI_ERROR)
441 ret = 0; /* SelectObject returns 0 on error */
447 GDI_ReleaseObj( hdc );
452 /***********************************************************************
455 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
460 FONT_LogFontWTo16( &font->logfont, &lf16 );
462 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
463 memcpy( buffer, &lf16, count );
467 /***********************************************************************
470 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
477 FONT_LogFontWToA( &font->logfont, &lfA );
479 if (count > sizeof(lfA)) count = sizeof(lfA);
480 memcpy( buffer, &lfA, count );
484 /***********************************************************************
487 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
491 return sizeof(LOGFONTW);
492 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
493 memcpy( buffer, &font->logfont, count );
498 /***********************************************************************
501 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
503 WineEngDestroyFontInstance( handle );
504 return GDI_FreeObject( handle, obj );
508 /***********************************************************************
509 * FONT_EnumInstance16
511 * Called by the device driver layer to pass font info
512 * down to the application.
514 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
515 DWORD fType, LPARAM lp )
517 fontEnum16 *pfe = (fontEnum16*)lp;
521 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
522 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
527 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
528 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
529 pfe->dwFlags |= ENUM_CALLED;
530 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
532 args[6] = SELECTOROF(pfe->segLogFont);
533 args[5] = OFFSETOF(pfe->segLogFont);
534 args[4] = SELECTOROF(pfe->segTextMetric);
535 args[3] = OFFSETOF(pfe->segTextMetric);
537 args[1] = HIWORD(pfe->lpData);
538 args[0] = LOWORD(pfe->lpData);
539 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
540 ret = LOWORD(result);
542 /* get the lock again and make sure the DC is still valid */
543 dc = DC_GetDCPtr( pfe->hdc );
544 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
546 if (dc) GDI_ReleaseObj( pfe->hdc );
547 pfe->hdc = 0; /* make sure we don't try to release it later on */
554 /***********************************************************************
557 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
558 DWORD fType, LPARAM lp )
560 fontEnum32 *pfe = (fontEnum32*)lp;
564 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
565 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
566 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
568 /* convert font metrics */
569 ENUMLOGFONTEXA logfont;
570 NEWTEXTMETRICEXA tmA;
572 pfe->dwFlags |= ENUM_CALLED;
573 if (!(pfe->dwFlags & ENUM_UNICODE))
575 FONT_EnumLogFontExWToA( plf, &logfont);
576 FONT_NewTextMetricExWToA( ptm, &tmA );
577 plf = (LPENUMLOGFONTEXW)&logfont;
578 ptm = (NEWTEXTMETRICEXW *)&tmA;
580 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
582 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
584 /* get the lock again and make sure the DC is still valid */
585 dc = DC_GetDCPtr( pfe->hdc );
586 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
588 if (dc) GDI_ReleaseObj( pfe->hdc );
589 pfe->hdc = 0; /* make sure we don't try to release it later on */
596 /***********************************************************************
597 * EnumFontFamiliesEx (GDI.613)
599 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
600 FONTENUMPROC16 efproc, LPARAM lParam,
605 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
606 NEWTEXTMETRICEX16 tm16;
607 ENUMLOGFONTEX16 lf16;
612 FONT_LogFont16ToW(plf, &lfW);
614 fe16.hdc = HDC_32(hDC);
616 fe16.physDev = dc->physDev;
617 fe16.lpLogFontParam = plf;
618 fe16.lpEnumFunc = efproc;
619 fe16.lpData = lParam;
620 fe16.lpTextMetric = &tm16;
621 fe16.lpLogFont = &lf16;
622 fe16.segTextMetric = MapLS( &tm16 );
623 fe16.segLogFont = MapLS( &lf16 );
626 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
628 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
635 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
636 fe16.dwFlags &= ~ENUM_CALLED;
637 if (ret && dc->funcs->pEnumDeviceFonts) {
638 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
639 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
643 UnMapLS( fe16.segTextMetric );
644 UnMapLS( fe16.segLogFont );
645 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
649 /***********************************************************************
650 * FONT_EnumFontFamiliesEx
652 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
653 FONTENUMPROCW efproc,
654 LPARAM lParam, DWORD dwUnicode)
657 DC *dc = DC_GetDCPtr( hDC );
663 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
665 fe32.lpLogFontParam = plf;
666 fe32.lpEnumFunc = efproc;
667 fe32.lpData = lParam;
668 fe32.dwFlags = dwUnicode;
671 fe32.physDev = dc->physDev;
673 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
675 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
682 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
683 fe32.dwFlags &= ~ENUM_CALLED;
684 if (ret && dc->funcs->pEnumDeviceFonts) {
685 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
686 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
690 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
694 /***********************************************************************
695 * EnumFontFamiliesExW (GDI32.@)
697 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
698 FONTENUMPROCW efproc,
699 LPARAM lParam, DWORD dwFlags )
701 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
704 /***********************************************************************
705 * EnumFontFamiliesExA (GDI32.@)
707 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
708 FONTENUMPROCA efproc,
709 LPARAM lParam, DWORD dwFlags)
712 FONT_LogFontAToW( plf, &lfW );
714 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
717 /***********************************************************************
718 * EnumFontFamilies (GDI.330)
720 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
721 FONTENUMPROC16 efproc, LPARAM lpData )
725 lf.lfCharSet = DEFAULT_CHARSET;
726 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
727 else lf.lfFaceName[0] = '\0';
729 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
732 /***********************************************************************
733 * EnumFontFamiliesA (GDI32.@)
735 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
736 FONTENUMPROCA efproc, LPARAM lpData )
740 lf.lfCharSet = DEFAULT_CHARSET;
741 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
742 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
744 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
747 /***********************************************************************
748 * EnumFontFamiliesW (GDI32.@)
750 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
751 FONTENUMPROCW efproc, LPARAM lpData )
755 lf.lfCharSet = DEFAULT_CHARSET;
756 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
757 else lf.lfFaceName[0] = 0;
759 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
762 /***********************************************************************
765 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
768 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
771 /***********************************************************************
772 * EnumFontsA (GDI32.@)
774 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
777 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
780 /***********************************************************************
781 * EnumFontsW (GDI32.@)
783 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
786 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
790 /***********************************************************************
791 * GetTextCharacterExtra (GDI32.@)
793 INT WINAPI GetTextCharacterExtra( HDC hdc )
796 DC *dc = DC_GetDCPtr( hdc );
797 if (!dc) return 0x80000000;
799 GDI_ReleaseObj( hdc );
804 /***********************************************************************
805 * SetTextCharacterExtra (GDI32.@)
807 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
810 DC * dc = DC_GetDCPtr( hdc );
811 if (!dc) return 0x80000000;
812 if (dc->funcs->pSetTextCharacterExtra)
813 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
816 prev = dc->charExtra;
817 dc->charExtra = extra;
819 GDI_ReleaseObj( hdc );
824 /***********************************************************************
825 * SetTextJustification (GDI32.@)
827 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
830 DC * dc = DC_GetDCPtr( hdc );
831 if (!dc) return FALSE;
832 if (dc->funcs->pSetTextJustification)
833 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
836 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
837 if (!extra) breaks = 0;
838 dc->breakTotalExtra = extra;
839 dc->breakCount = breaks;
842 dc->breakExtra = extra / breaks;
843 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
851 GDI_ReleaseObj( hdc );
856 /***********************************************************************
857 * GetTextFaceA (GDI32.@)
859 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
861 INT res = GetTextFaceW(hdc, 0, NULL);
862 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
863 GetTextFaceW( hdc, res, nameW );
867 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
872 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
873 HeapFree( GetProcessHeap(), 0, nameW );
877 /***********************************************************************
878 * GetTextFaceW (GDI32.@)
880 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
885 DC * dc = DC_GetDCPtr( hdc );
889 ret = WineEngGetTextFace(dc->gdiFont, count, name);
890 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
894 lstrcpynW( name, font->logfont.lfFaceName, count );
897 else ret = strlenW(font->logfont.lfFaceName) + 1;
898 GDI_ReleaseObj( dc->hFont );
900 GDI_ReleaseObj( hdc );
905 /***********************************************************************
906 * GetTextExtentPoint32A (GDI32.@)
908 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
913 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
916 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
917 HeapFree( GetProcessHeap(), 0, p );
920 TRACE("(%p %s %d %p): returning %ld x %ld\n",
921 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
926 /***********************************************************************
927 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
929 * Computes width and height of the specified string.
935 BOOL WINAPI GetTextExtentPoint32W(
936 HDC hdc, /* [in] Handle of device context */
937 LPCWSTR str, /* [in] Address of text string */
938 INT count, /* [in] Number of characters in string */
939 LPSIZE size) /* [out] Address of structure for string size */
942 DC * dc = DC_GetDCPtr( hdc );
943 if (!dc) return FALSE;
946 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
947 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
948 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
950 else if(dc->funcs->pGetTextExtentPoint)
951 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
953 GDI_ReleaseObj( hdc );
955 TRACE("(%p %s %d %p): returning %ld x %ld\n",
956 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
960 /***********************************************************************
961 * GetTextExtentPointI [GDI32.@]
963 * Computes width and height of the array of glyph indices.
969 BOOL WINAPI GetTextExtentPointI(
970 HDC hdc, /* [in] Handle of device context */
971 const WORD *indices, /* [in] Address of glyph index array */
972 INT count, /* [in] Number of glyphs in array */
973 LPSIZE size) /* [out] Address of structure for string size */
976 DC * dc = DC_GetDCPtr( hdc );
977 if (!dc) return FALSE;
980 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
981 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
982 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
984 else if(dc->funcs->pGetTextExtentPoint) {
985 FIXME("calling GetTextExtentPoint\n");
986 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
989 GDI_ReleaseObj( hdc );
991 TRACE("(%p %p %d %p): returning %ld x %ld\n",
992 hdc, indices, count, size, size->cx, size->cy );
997 /***********************************************************************
998 * GetTextExtentPointA (GDI32.@)
1000 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1003 TRACE("not bug compatible.\n");
1004 return GetTextExtentPoint32A( hdc, str, count, size );
1007 /***********************************************************************
1008 * GetTextExtentPointW (GDI32.@)
1010 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1013 TRACE("not bug compatible.\n");
1014 return GetTextExtentPoint32W( hdc, str, count, size );
1018 /***********************************************************************
1019 * GetTextExtentExPointA (GDI32.@)
1021 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1022 INT maxExt, LPINT lpnFit,
1023 LPINT alpDx, LPSIZE size )
1027 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1028 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1029 HeapFree( GetProcessHeap(), 0, p );
1034 /***********************************************************************
1035 * GetTextExtentExPointW (GDI32.@)
1037 * Return the size of the string as it would be if it was output properly by
1040 * This should include
1041 * - Intercharacter spacing
1042 * - justification spacing (not yet done)
1043 * - kerning? see below
1045 * Kerning. Since kerning would be carried out by the rendering code it should
1046 * be done by the driver. However they don't support it yet. Also I am not
1047 * yet persuaded that (certainly under Win95) any kerning is actually done.
1049 * str: According to MSDN this should be null-terminated. That is not true; a
1050 * null will not terminate it early.
1051 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1052 * than count. I have seen it be either the size of the full string or
1053 * 1 less than the size of the full string. I have not seen it bear any
1054 * resemblance to the portion that would fit.
1055 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1056 * trailing intercharacter spacing and any trailing justification.
1059 * Currently we do this by measuring each character etc. We should do it by
1060 * passing the request to the driver, perhaps by extending the
1061 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1062 * thinking about kerning issues and rounding issues in the justification.
1065 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1066 INT maxExt, LPINT lpnFit,
1067 LPINT alpDx, LPSIZE size )
1069 int index, nFit, extent;
1073 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1075 size->cx = size->cy = nFit = extent = 0;
1076 for(index = 0; index < count; index++)
1078 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1079 /* GetTextExtentPoint includes intercharacter spacing. */
1080 /* FIXME - justification needs doing yet. Remember that the base
1081 * data will not be in logical coordinates.
1084 if( !lpnFit || extent <= maxExt )
1085 /* It is allowed to be equal. */
1088 if( alpDx ) alpDx[index] = extent;
1090 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1094 if(lpnFit) *lpnFit = nFit;
1097 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1103 /***********************************************************************
1104 * GetTextMetricsA (GDI32.@)
1106 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1110 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1111 FONT_TextMetricWToA( &tm32, metrics );
1115 /***********************************************************************
1116 * GetTextMetricsW (GDI32.@)
1118 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1121 DC * dc = DC_GetDCPtr( hdc );
1122 if (!dc) return FALSE;
1125 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1126 else if (dc->funcs->pGetTextMetrics)
1127 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1131 /* device layer returns values in device units
1132 * therefore we have to convert them to logical */
1134 #define WDPTOLP(x) ((x<0)? \
1135 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1136 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1137 #define HDPTOLP(y) ((y<0)? \
1138 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1139 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1141 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1142 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1143 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1144 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1145 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1146 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1147 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1148 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1152 TRACE("text metrics:\n"
1153 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1154 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1155 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1156 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1157 " PitchAndFamily = %02x\n"
1158 " --------------------\n"
1159 " InternalLeading = %li\n"
1163 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1164 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1165 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1166 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1167 metrics->tmPitchAndFamily,
1168 metrics->tmInternalLeading,
1171 metrics->tmHeight );
1173 GDI_ReleaseObj( hdc );
1178 /***********************************************************************
1179 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1182 * lpOTM should be LPOUTLINETEXTMETRIC
1185 * Success: Non-zero or size of required buffer
1188 UINT16 WINAPI GetOutlineTextMetrics16(
1189 HDC16 hdc, /* [in] Handle of device context */
1190 UINT16 cbData, /* [in] Size of metric data array */
1191 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1193 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1198 /***********************************************************************
1199 * GetOutlineTextMetricsA (GDI32.@)
1200 * Gets metrics for TrueType fonts.
1204 * Success: Non-zero or size of required buffer
1207 UINT WINAPI GetOutlineTextMetricsA(
1208 HDC hdc, /* [in] Handle of device context */
1209 UINT cbData, /* [in] Size of metric data array */
1210 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1212 char buf[512], *ptr;
1214 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1217 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1218 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1220 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1221 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1224 needed = sizeof(OUTLINETEXTMETRICA);
1225 if(lpOTMW->otmpFamilyName)
1226 needed += WideCharToMultiByte(CP_ACP, 0,
1227 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1228 NULL, 0, NULL, NULL);
1229 if(lpOTMW->otmpFaceName)
1230 needed += WideCharToMultiByte(CP_ACP, 0,
1231 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1232 NULL, 0, NULL, NULL);
1233 if(lpOTMW->otmpStyleName)
1234 needed += WideCharToMultiByte(CP_ACP, 0,
1235 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1236 NULL, 0, NULL, NULL);
1237 if(lpOTMW->otmpFullName)
1238 needed += WideCharToMultiByte(CP_ACP, 0,
1239 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1240 NULL, 0, NULL, NULL);
1247 if(needed > cbData) {
1253 lpOTM->otmSize = needed;
1254 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1255 lpOTM->otmFiller = 0;
1256 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1257 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1258 lpOTM->otmfsType = lpOTMW->otmfsType;
1259 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1260 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1261 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1262 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1263 lpOTM->otmAscent = lpOTMW->otmAscent;
1264 lpOTM->otmDescent = lpOTMW->otmDescent;
1265 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1266 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1267 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1268 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1269 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1270 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1271 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1272 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1273 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1274 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1275 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1276 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1277 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1278 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1279 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1280 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1283 ptr = (char*)(lpOTM + 1);
1284 left = needed - sizeof(*lpOTM);
1286 if(lpOTMW->otmpFamilyName) {
1287 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1288 len = WideCharToMultiByte(CP_ACP, 0,
1289 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1290 ptr, left, NULL, NULL);
1294 lpOTM->otmpFamilyName = 0;
1296 if(lpOTMW->otmpFaceName) {
1297 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1298 len = WideCharToMultiByte(CP_ACP, 0,
1299 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1300 ptr, left, NULL, NULL);
1304 lpOTM->otmpFaceName = 0;
1306 if(lpOTMW->otmpStyleName) {
1307 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1308 len = WideCharToMultiByte(CP_ACP, 0,
1309 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1310 ptr, left, NULL, NULL);
1314 lpOTM->otmpStyleName = 0;
1316 if(lpOTMW->otmpFullName) {
1317 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1318 len = WideCharToMultiByte(CP_ACP, 0,
1319 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1320 ptr, left, NULL, NULL);
1323 lpOTM->otmpFullName = 0;
1330 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1331 HeapFree(GetProcessHeap(), 0, lpOTMW);
1337 /***********************************************************************
1338 * GetOutlineTextMetricsW [GDI32.@]
1340 UINT WINAPI GetOutlineTextMetricsW(
1341 HDC hdc, /* [in] Handle of device context */
1342 UINT cbData, /* [in] Size of metric data array */
1343 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1345 DC *dc = DC_GetDCPtr( hdc );
1348 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1352 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1353 if(ret && ret <= cbData) {
1354 #define WDPTOLP(x) ((x<0)? \
1355 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1356 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1357 #define HDPTOLP(y) ((y<0)? \
1358 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1359 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1361 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1362 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1363 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1364 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1365 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1366 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1367 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1368 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1369 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1370 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1371 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1372 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1373 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1374 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1375 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1376 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1377 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1378 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1379 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1380 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1381 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1382 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1383 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1384 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1385 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1386 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1387 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1388 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1389 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1390 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1391 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1392 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1398 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1399 but really this should just be a return 0. */
1401 ret = sizeof(*lpOTM);
1406 memset(lpOTM, 0, ret);
1407 lpOTM->otmSize = sizeof(*lpOTM);
1408 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1410 Further fill of the structure not implemented,
1411 Needs real values for the structure members
1416 GDI_ReleaseObj(hdc);
1421 /***********************************************************************
1422 * GetCharWidthW (GDI32.@)
1423 * GetCharWidth32W (GDI32.@)
1425 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1430 DC * dc = DC_GetDCPtr( hdc );
1431 if (!dc) return FALSE;
1434 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1435 else if (dc->funcs->pGetCharWidth)
1436 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1440 /* convert device units to logical */
1441 for( i = firstChar; i <= lastChar; i++, buffer++ )
1442 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1445 GDI_ReleaseObj( hdc );
1450 /***********************************************************************
1451 * GetCharWidthA (GDI32.@)
1452 * GetCharWidth32A (GDI32.@)
1454 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1457 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1462 if(count <= 0) return FALSE;
1464 str = HeapAlloc(GetProcessHeap(), 0, count);
1465 for(i = 0; i < count; i++)
1466 str[i] = (BYTE)(firstChar + i);
1468 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1470 for(i = 0; i < wlen; i++)
1472 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1480 HeapFree(GetProcessHeap(), 0, str);
1481 HeapFree(GetProcessHeap(), 0, wstr);
1487 /* FIXME: all following APIs ******************************************/
1490 /***********************************************************************
1491 * SetMapperFlags (GDI32.@)
1493 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1495 DC *dc = DC_GetDCPtr( hDC );
1498 if(dc->funcs->pSetMapperFlags)
1499 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1501 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1502 GDI_ReleaseObj( hDC );
1506 /***********************************************************************
1507 * GetAspectRatioFilterEx (GDI.486)
1509 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1511 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1515 /***********************************************************************
1516 * GetAspectRatioFilterEx (GDI32.@)
1518 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1520 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1525 /***********************************************************************
1526 * GetCharABCWidthsA (GDI32.@)
1528 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1531 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1536 if(count <= 0) return FALSE;
1538 str = HeapAlloc(GetProcessHeap(), 0, count);
1539 for(i = 0; i < count; i++)
1540 str[i] = (BYTE)(firstChar + i);
1542 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1544 for(i = 0; i < wlen; i++)
1546 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1554 HeapFree(GetProcessHeap(), 0, str);
1555 HeapFree(GetProcessHeap(), 0, wstr);
1561 /******************************************************************************
1562 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1565 * hdc [I] Handle of device context
1566 * firstChar [I] First character in range to query
1567 * lastChar [I] Last character in range to query
1568 * abc [O] Address of character-width structure
1571 * Only works with TrueType fonts
1577 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1580 DC *dc = DC_GetDCPtr(hdc);
1586 for (i=firstChar;i<=lastChar;i++) {
1587 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1588 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1589 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1590 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1594 GDI_ReleaseObj(hdc);
1599 /***********************************************************************
1600 * GetGlyphOutline (GDI.309)
1602 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1603 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1604 LPVOID lpBuffer, const MAT2 *lpmat2 )
1606 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1607 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1608 return (DWORD)-1; /* failure */
1612 /***********************************************************************
1613 * GetGlyphOutlineA (GDI32.@)
1615 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1616 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1617 LPVOID lpBuffer, const MAT2 *lpmat2 )
1623 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1624 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1628 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1631 HeapFree(GetProcessHeap(), 0, p);
1635 /***********************************************************************
1636 * GetGlyphOutlineW (GDI32.@)
1638 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1639 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1640 LPVOID lpBuffer, const MAT2 *lpmat2 )
1642 DC *dc = DC_GetDCPtr(hdc);
1645 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1646 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1648 if(!dc) return GDI_ERROR;
1651 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1652 cbBuffer, lpBuffer, lpmat2);
1656 GDI_ReleaseObj(hdc);
1661 /***********************************************************************
1662 * CreateScalableFontResourceA (GDI32.@)
1664 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1665 LPCSTR lpszResourceFile,
1666 LPCSTR lpszFontFile,
1667 LPCSTR lpszCurrentPath )
1671 /* fHidden=1 - only visible for the calling app, read-only, not
1672 * enumbered with EnumFonts/EnumFontFamilies
1673 * lpszCurrentPath can be NULL
1675 FIXME("(%ld,%s,%s,%s): stub\n",
1676 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1677 debugstr_a(lpszCurrentPath) );
1679 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1680 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1682 SetLastError(ERROR_FILE_EXISTS);
1685 return FALSE; /* create failed */
1688 /***********************************************************************
1689 * CreateScalableFontResourceW (GDI32.@)
1691 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1692 LPCWSTR lpszResourceFile,
1693 LPCWSTR lpszFontFile,
1694 LPCWSTR lpszCurrentPath )
1696 FIXME("(%ld,%p,%p,%p): stub\n",
1697 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1698 return FALSE; /* create failed */
1702 /*************************************************************************
1703 * GetRasterizerCaps (GDI32.@)
1705 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1707 lprs->nSize = sizeof(RASTERIZER_STATUS);
1708 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1709 lprs->nLanguageID = 0;
1714 /*************************************************************************
1715 * GetKerningPairsA (GDI32.@)
1717 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1718 LPKERNINGPAIR lpKerningPairs )
1720 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1724 /*************************************************************************
1725 * GetKerningPairsW (GDI32.@)
1727 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1728 LPKERNINGPAIR lpKerningPairs )
1731 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1732 for (i = 0; i < cPairs; i++)
1733 lpKerningPairs[i].iKernAmount = 0;
1737 /*************************************************************************
1738 * TranslateCharsetInfo [GDI32.@]
1740 * Fills a CHARSETINFO structure for a character set, code page, or
1741 * font. This allows making the correspondance between different labelings
1742 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1743 * of the same encoding.
1745 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1746 * only one codepage should be set in *lpSrc.
1749 * TRUE on success, FALSE on failure.
1752 BOOL WINAPI TranslateCharsetInfo(
1753 LPDWORD lpSrc, /* [in]
1754 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1755 if flags == TCI_SRCCHARSET: a character set value
1756 if flags == TCI_SRCCODEPAGE: a code page value
1758 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1759 DWORD flags /* [in] determines interpretation of lpSrc */
1763 case TCI_SRCFONTSIG:
1764 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1766 case TCI_SRCCODEPAGE:
1767 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1769 case TCI_SRCCHARSET:
1770 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1775 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1776 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1780 /*************************************************************************
1781 * GetFontLanguageInfo (GDI32.@)
1783 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1785 FONTSIGNATURE fontsig;
1786 static const DWORD GCP_DBCS_MASK=0x003F0000,
1787 GCP_DIACRITIC_MASK=0x00000000,
1788 FLI_GLYPHS_MASK=0x00000000,
1789 GCP_GLYPHSHAPE_MASK=0x00000040,
1790 GCP_KASHIDA_MASK=0x00000000,
1791 GCP_LIGATE_MASK=0x00000000,
1792 GCP_USEKERNING_MASK=0x00000000,
1793 GCP_REORDER_MASK=0x00000060;
1797 GetTextCharsetInfo( hdc, &fontsig, 0 );
1798 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1800 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1803 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1804 result|=GCP_DIACRITIC;
1806 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1809 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1810 result|=GCP_GLYPHSHAPE;
1812 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1813 result|=GCP_KASHIDA;
1815 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1818 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1819 result|=GCP_USEKERNING;
1821 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1822 result|=GCP_REORDER;
1828 /*************************************************************************
1829 * GetFontData [GDI32.@] Retrieve data for TrueType font
1833 * success: Number of bytes returned
1834 * failure: GDI_ERROR
1838 * Calls SetLastError()
1841 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1842 LPVOID buffer, DWORD length)
1844 DC *dc = DC_GetDCPtr(hdc);
1845 DWORD ret = GDI_ERROR;
1847 if(!dc) return GDI_ERROR;
1850 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1852 GDI_ReleaseObj(hdc);
1856 /*************************************************************************
1857 * GetGlyphIndicesA [GDI32.@]
1859 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1860 LPWORD pgi, DWORD flags)
1866 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1867 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1869 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1870 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1871 HeapFree(GetProcessHeap(), 0, lpstrW);
1876 /*************************************************************************
1877 * GetGlyphIndicesW [GDI32.@]
1879 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1880 LPWORD pgi, DWORD flags)
1882 DC *dc = DC_GetDCPtr(hdc);
1883 DWORD ret = GDI_ERROR;
1885 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1886 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1888 if(!dc) return GDI_ERROR;
1891 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1893 GDI_ReleaseObj(hdc);
1897 /*************************************************************************
1898 * GetCharacterPlacementA [GDI32.@]
1901 * the web browser control of ie4 calls this with dwFlags=0
1904 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1905 INT nMaxExtent, GCP_RESULTSA *lpResults,
1910 GCP_RESULTSW resultsW;
1914 TRACE("%s, %d, %d, 0x%08lx\n",
1915 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1917 /* both structs are equal in size */
1918 memcpy(&resultsW, lpResults, sizeof(resultsW));
1920 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1921 if(lpResults->lpOutString)
1922 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1924 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1926 if(lpResults->lpOutString) {
1927 if(font_cp != CP_SYMBOL)
1928 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1929 lpResults->lpOutString, uCount, NULL, NULL );
1931 for(i = 0; i < uCount; i++)
1932 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1935 HeapFree(GetProcessHeap(), 0, lpStringW);
1936 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1941 /*************************************************************************
1942 * GetCharacterPlacementW [GDI32.@]
1944 * Retrieve information about a string. This includes the width, reordering,
1945 * Glyphing and so on.
1949 * The width and height of the string if successful, 0 if failed.
1953 * All flags except GCP_REORDER are not yet implemented.
1954 * Reordering is not 100% complient to the Windows BiDi method.
1955 * Caret positioning is not yet implemented.
1956 * Classes are not yet implemented.
1960 GetCharacterPlacementW(
1961 HDC hdc, /* [in] Device context for which the rendering is to be done */
1962 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1963 INT uCount, /* [in] Number of WORDS in string. */
1964 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1965 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1966 DWORD dwFlags /* [in] Flags specifying how to process the string */
1973 TRACE("%s, %d, %d, 0x%08lx\n",
1974 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1976 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1977 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1978 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1979 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1980 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1982 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1983 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1984 if(lpResults->lpClass) FIXME("classes not implemented\n");
1986 nSet = (UINT)uCount;
1987 if(nSet > lpResults->nGlyphs)
1988 nSet = lpResults->nGlyphs;
1990 /* return number of initialized fields */
1991 lpResults->nGlyphs = nSet;
1993 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1995 /* Treat the case where no special handling was requested in a fastpath way */
1996 /* copy will do if the GCP_REORDER flag is not set */
1997 if(lpResults->lpOutString)
1998 strncpyW( lpResults->lpOutString, lpString, nSet );
2000 if(lpResults->lpOrder)
2002 for(i = 0; i < nSet; i++)
2003 lpResults->lpOrder[i] = i;
2007 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2008 nSet, lpResults->lpOrder );
2011 /* FIXME: Will use the placement chars */
2012 if (lpResults->lpDx)
2015 for (i = 0; i < nSet; i++)
2017 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2018 lpResults->lpDx[i]= c;
2022 if(lpResults->lpGlyphs)
2023 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2025 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2026 ret = MAKELONG(size.cx, size.cy);
2031 /*************************************************************************
2032 * GetCharABCWidthsFloatA [GDI32.@]
2034 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2037 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2041 /*************************************************************************
2042 * GetCharABCWidthsFloatW [GDI32.@]
2044 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2045 UINT iLastChar, LPABCFLOAT lpABCF)
2047 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2051 /*************************************************************************
2052 * GetCharWidthFloatA [GDI32.@]
2054 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2055 UINT iLastChar, PFLOAT pxBuffer)
2057 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2061 /*************************************************************************
2062 * GetCharWidthFloatW [GDI32.@]
2064 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2065 UINT iLastChar, PFLOAT pxBuffer)
2067 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2072 /***********************************************************************
2074 * Font Resource API *
2076 ***********************************************************************/
2078 /***********************************************************************
2079 * AddFontResourceA (GDI32.@)
2081 INT WINAPI AddFontResourceA( LPCSTR str )
2083 return AddFontResourceExA( str, 0, NULL);
2086 /***********************************************************************
2087 * AddFontResourceW (GDI32.@)
2089 INT WINAPI AddFontResourceW( LPCWSTR str )
2091 return AddFontResourceExW(str, 0, NULL);
2095 /***********************************************************************
2096 * AddFontResourceExA (GDI32.@)
2098 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2100 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2101 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2104 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2105 ret = AddFontResourceExW(strW, fl, pdv);
2106 HeapFree(GetProcessHeap(), 0, strW);
2110 /***********************************************************************
2111 * AddFontResourceExW (GDI32.@)
2113 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2115 return WineEngAddFontResourceEx(str, fl, pdv);
2118 /***********************************************************************
2119 * RemoveFontResourceA (GDI32.@)
2121 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2123 return RemoveFontResourceExA(str, 0, 0);
2126 /***********************************************************************
2127 * RemoveFontResourceW (GDI32.@)
2129 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2131 return RemoveFontResourceExW(str, 0, 0);
2134 /***********************************************************************
2135 * RemoveFontResourceExA (GDI32.@)
2137 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2139 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2140 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2143 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2144 ret = RemoveFontResourceExW(strW, fl, pdv);
2145 HeapFree(GetProcessHeap(), 0, strW);
2149 /***********************************************************************
2150 * RemoveFontResourceExW (GDI32.@)
2152 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2154 return WineEngRemoveFontResourceEx(str, fl, pdv);
2157 /***********************************************************************
2158 * GetTextCharset (GDI32.@)
2160 UINT WINAPI GetTextCharset(HDC hdc)
2162 /* MSDN docs say this is equivalent */
2163 return GetTextCharsetInfo(hdc, NULL, 0);
2166 /***********************************************************************
2167 * GetTextCharsetInfo (GDI32.@)
2169 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2171 UINT ret = DEFAULT_CHARSET;
2172 DC *dc = DC_GetDCPtr(hdc);
2177 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2179 GDI_ReleaseObj(hdc);
2182 if (ret == DEFAULT_CHARSET && fs)
2183 memset(fs, 0, sizeof(FONTSIGNATURE));