4 * Copyright 1993 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
31 #include "wine/unicode.h"
33 #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;
81 LPLOGFONTW lpLogFontParam;
82 FONTENUMPROCW lpEnumFunc;
91 * For TranslateCharsetInfo
93 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
94 #define MAXTCIINDEX 32
95 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
97 { ANSI_CHARSET, 1252, FS(0)},
98 { EASTEUROPE_CHARSET, 1250, FS(1)},
99 { RUSSIAN_CHARSET, 1251, FS(2)},
100 { GREEK_CHARSET, 1253, FS(3)},
101 { TURKISH_CHARSET, 1254, FS(4)},
102 { HEBREW_CHARSET, 1255, FS(5)},
103 { ARABIC_CHARSET, 1256, FS(6)},
104 { BALTIC_CHARSET, 1257, FS(7)},
105 { VIETNAMESE_CHARSET, 1258, FS(8)},
106 /* reserved by ANSI */
107 { DEFAULT_CHARSET, 0, FS(0)},
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)},
115 { THAI_CHARSET, 874, FS(16)},
116 { SHIFTJIS_CHARSET, 932, FS(17)},
117 { GB2312_CHARSET, 936, FS(18)},
118 { HANGEUL_CHARSET, 949, FS(19)},
119 { CHINESEBIG5_CHARSET, 950, FS(20)},
120 { JOHAB_CHARSET, 1361, FS(21)},
121 /* reserved for alternate ANSI and OEM */
122 { DEFAULT_CHARSET, 0, FS(0)},
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
126 { DEFAULT_CHARSET, 0, FS(0)},
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
129 { DEFAULT_CHARSET, 0, FS(0)},
130 /* reserved for system */
131 { DEFAULT_CHARSET, 0, FS(0)},
132 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
135 /* ### start build ### */
136 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROC16,LONG,LONG,WORD,LONG);
137 /* ### stop build ### */
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;
242 ptmA->tmLastChar = ptmW->tmLastChar;
243 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
244 ptmA->tmBreakChar = 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;
267 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
268 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
269 ptm16->ntmTm.tmBreakChar = 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 => %04x\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 %04x\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 )
478 FONT_LogFontWToA( &font->logfont, &lfA );
480 if (count > sizeof(lfA)) count = sizeof(lfA);
482 memcpy( buffer, &lfA, count );
486 /***********************************************************************
489 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
492 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
494 memcpy( buffer, &font->logfont, count );
499 /***********************************************************************
502 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
504 WineEngDestroyFontInstance( handle );
505 return GDI_FreeObject( handle, obj );
509 /***********************************************************************
510 * FONT_EnumInstance16
512 * Called by the device driver layer to pass font info
513 * down to the application.
515 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
516 DWORD fType, LPARAM lp )
518 fontEnum16 *pfe = (fontEnum16*)lp;
522 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
523 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
525 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
526 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
527 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
529 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
530 (UINT16)fType, (LPARAM)pfe->lpData );
531 /* get the lock again and make sure the DC is still valid */
532 dc = DC_GetDCPtr( pfe->hdc );
533 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
535 if (dc) GDI_ReleaseObj( pfe->hdc );
536 pfe->hdc = 0; /* make sure we don't try to release it later on */
543 /***********************************************************************
546 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
547 DWORD fType, LPARAM lp )
549 fontEnum32 *pfe = (fontEnum32*)lp;
553 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
554 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
555 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
557 /* convert font metrics */
558 ENUMLOGFONTEXA logfont;
559 NEWTEXTMETRICEXA tmA;
561 pfe->dwFlags |= ENUM_CALLED;
562 if (!(pfe->dwFlags & ENUM_UNICODE))
564 FONT_EnumLogFontExWToA( plf, &logfont);
565 FONT_NewTextMetricExWToA( ptm, &tmA );
566 plf = (LPENUMLOGFONTEXW)&logfont;
567 ptm = (NEWTEXTMETRICEXW *)&tmA;
569 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
571 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
573 /* get the lock again and make sure the DC is still valid */
574 dc = DC_GetDCPtr( pfe->hdc );
575 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
577 if (dc) GDI_ReleaseObj( pfe->hdc );
578 pfe->hdc = 0; /* make sure we don't try to release it later on */
585 /***********************************************************************
586 * EnumFontFamiliesEx (GDI.613)
588 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
589 FONTENUMPROC16 efproc, LPARAM lParam,
594 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
597 fe16.hdc = HDC_32(hDC);
599 fe16.physDev = dc->physDev;
601 if (dc->funcs->pEnumDeviceFonts)
603 NEWTEXTMETRICEX16 tm16;
604 ENUMLOGFONTEX16 lf16;
606 FONT_LogFont16ToW(plf, &lfW);
608 fe16.lpLogFontParam = plf;
609 fe16.lpEnumFunc = efproc;
610 fe16.lpData = lParam;
611 fe16.lpTextMetric = &tm16;
612 fe16.lpLogFont = &lf16;
613 fe16.segTextMetric = MapLS( &tm16 );
614 fe16.segLogFont = MapLS( &lf16 );
616 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
617 FONT_EnumInstance16, (LPARAM)&fe16 );
618 UnMapLS( fe16.segTextMetric );
619 UnMapLS( fe16.segLogFont );
621 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
625 /***********************************************************************
626 * FONT_EnumFontFamiliesEx
628 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
629 FONTENUMPROCW efproc,
630 LPARAM lParam, DWORD dwUnicode)
633 DC *dc = DC_GetDCPtr( hDC );
639 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
641 fe32.lpLogFontParam = plf;
642 fe32.lpEnumFunc = efproc;
643 fe32.lpData = lParam;
644 fe32.dwFlags = dwUnicode;
647 fe32.physDev = dc->physDev;
649 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
651 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
658 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
659 fe32.dwFlags &= ~ENUM_CALLED;
660 if (ret && dc->funcs->pEnumDeviceFonts) {
661 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
662 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
666 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
670 /***********************************************************************
671 * EnumFontFamiliesExW (GDI32.@)
673 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
674 FONTENUMPROCW efproc,
675 LPARAM lParam, DWORD dwFlags )
677 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
680 /***********************************************************************
681 * EnumFontFamiliesExA (GDI32.@)
683 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
684 FONTENUMPROCA efproc,
685 LPARAM lParam, DWORD dwFlags)
688 FONT_LogFontAToW( plf, &lfW );
690 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
693 /***********************************************************************
694 * EnumFontFamilies (GDI.330)
696 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
697 FONTENUMPROC16 efproc, LPARAM lpData )
701 lf.lfCharSet = DEFAULT_CHARSET;
702 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
703 else lf.lfFaceName[0] = '\0';
705 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
708 /***********************************************************************
709 * EnumFontFamiliesA (GDI32.@)
711 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
712 FONTENUMPROCA efproc, LPARAM lpData )
716 lf.lfCharSet = DEFAULT_CHARSET;
717 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
718 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
720 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
723 /***********************************************************************
724 * EnumFontFamiliesW (GDI32.@)
726 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
727 FONTENUMPROCW efproc, LPARAM lpData )
731 lf.lfCharSet = DEFAULT_CHARSET;
732 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
733 else lf.lfFaceName[0] = 0;
735 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
738 /***********************************************************************
741 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
744 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
747 /***********************************************************************
748 * EnumFontsA (GDI32.@)
750 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
753 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
756 /***********************************************************************
757 * EnumFontsW (GDI32.@)
759 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
762 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
766 /***********************************************************************
767 * GetTextCharacterExtra (GDI32.@)
769 INT WINAPI GetTextCharacterExtra( HDC hdc )
772 DC *dc = DC_GetDCPtr( hdc );
773 if (!dc) return 0x80000000;
775 GDI_ReleaseObj( hdc );
780 /***********************************************************************
781 * SetTextCharacterExtra (GDI32.@)
783 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
786 DC * dc = DC_GetDCPtr( hdc );
787 if (!dc) return 0x80000000;
788 if (dc->funcs->pSetTextCharacterExtra)
789 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
792 prev = dc->charExtra;
793 dc->charExtra = extra;
795 GDI_ReleaseObj( hdc );
800 /***********************************************************************
801 * SetTextJustification (GDI32.@)
803 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
806 DC * dc = DC_GetDCPtr( hdc );
807 if (!dc) return FALSE;
808 if (dc->funcs->pSetTextJustification)
809 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
812 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
813 if (!extra) breaks = 0;
814 dc->breakTotalExtra = extra;
815 dc->breakCount = breaks;
818 dc->breakExtra = extra / breaks;
819 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
827 GDI_ReleaseObj( hdc );
832 /***********************************************************************
833 * GetTextFaceA (GDI32.@)
835 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
837 INT res = GetTextFaceW(hdc, 0, NULL);
838 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
839 GetTextFaceW( hdc, res, nameW );
842 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
845 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
846 HeapFree( GetProcessHeap(), 0, nameW );
850 /***********************************************************************
851 * GetTextFaceW (GDI32.@)
853 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
858 DC * dc = DC_GetDCPtr( hdc );
862 ret = WineEngGetTextFace(dc->gdiFont, count, name);
863 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
867 lstrcpynW( name, font->logfont.lfFaceName, count );
870 else ret = strlenW(font->logfont.lfFaceName) + 1;
871 GDI_ReleaseObj( dc->hFont );
873 GDI_ReleaseObj( hdc );
878 /***********************************************************************
879 * GetTextExtentPoint32A (GDI32.@)
881 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
886 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
889 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
890 HeapFree( GetProcessHeap(), 0, p );
893 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
894 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
899 /***********************************************************************
900 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
902 * Computes width and height of the specified string.
908 BOOL WINAPI GetTextExtentPoint32W(
909 HDC hdc, /* [in] Handle of device context */
910 LPCWSTR str, /* [in] Address of text string */
911 INT count, /* [in] Number of characters in string */
912 LPSIZE size) /* [out] Address of structure for string size */
915 DC * dc = DC_GetDCPtr( hdc );
916 if (!dc) return FALSE;
919 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
920 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
921 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
923 else if(dc->funcs->pGetTextExtentPoint)
924 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
926 GDI_ReleaseObj( hdc );
928 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
929 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
933 /***********************************************************************
934 * GetTextExtentPointI [GDI32.@]
936 * Computes width and height of the array of glyph indices.
942 BOOL WINAPI GetTextExtentPointI(
943 HDC hdc, /* [in] Handle of device context */
944 const WORD *indices, /* [in] Address of glyph index array */
945 INT count, /* [in] Number of glyphs in array */
946 LPSIZE size) /* [out] Address of structure for string size */
949 DC * dc = DC_GetDCPtr( hdc );
950 if (!dc) return FALSE;
953 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
954 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
955 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
957 else if(dc->funcs->pGetTextExtentPoint) {
958 FIXME("calling GetTextExtentPoint\n");
959 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
962 GDI_ReleaseObj( hdc );
964 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
965 hdc, indices, count, size, size->cx, size->cy );
970 /***********************************************************************
971 * GetTextExtentPointA (GDI32.@)
973 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
976 TRACE("not bug compatible.\n");
977 return GetTextExtentPoint32A( hdc, str, count, size );
980 /***********************************************************************
981 * GetTextExtentPointW (GDI32.@)
983 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
986 TRACE("not bug compatible.\n");
987 return GetTextExtentPoint32W( hdc, str, count, size );
991 /***********************************************************************
992 * GetTextExtentExPointA (GDI32.@)
994 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
995 INT maxExt, LPINT lpnFit,
996 LPINT alpDx, LPSIZE size )
1000 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1001 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1002 HeapFree( GetProcessHeap(), 0, p );
1007 /***********************************************************************
1008 * GetTextExtentExPointW (GDI32.@)
1010 * Return the size of the string as it would be if it was output properly by
1013 * This should include
1014 * - Intercharacter spacing
1015 * - justification spacing (not yet done)
1016 * - kerning? see below
1018 * Kerning. Since kerning would be carried out by the rendering code it should
1019 * be done by the driver. However they don't support it yet. Also I am not
1020 * yet persuaded that (certainly under Win95) any kerning is actually done.
1022 * str: According to MSDN this should be null-terminated. That is not true; a
1023 * null will not terminate it early.
1024 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1025 * than count. I have seen it be either the size of the full string or
1026 * 1 less than the size of the full string. I have not seen it bear any
1027 * resemblance to the portion that would fit.
1028 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1029 * trailing intercharacter spacing and any trailing justification.
1032 * Currently we do this by measuring each character etc. We should do it by
1033 * passing the request to the driver, perhaps by extending the
1034 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1035 * thinking about kerning issues and rounding issues in the justification.
1038 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1039 INT maxExt, LPINT lpnFit,
1040 LPINT alpDx, LPSIZE size )
1042 int index, nFit, extent;
1046 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1048 size->cx = size->cy = nFit = extent = 0;
1049 for(index = 0; index < count; index++)
1051 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1052 /* GetTextExtentPoint includes intercharacter spacing. */
1053 /* FIXME - justification needs doing yet. Remember that the base
1054 * data will not be in logical coordinates.
1057 if( !lpnFit || extent <= maxExt )
1058 /* It is allowed to be equal. */
1061 if( alpDx ) alpDx[index] = extent;
1063 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1067 if(lpnFit) *lpnFit = nFit;
1070 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1076 /***********************************************************************
1077 * GetTextMetricsA (GDI32.@)
1079 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1083 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1084 FONT_TextMetricWToA( &tm32, metrics );
1088 /***********************************************************************
1089 * GetTextMetricsW (GDI32.@)
1091 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1094 DC * dc = DC_GetDCPtr( hdc );
1095 if (!dc) return FALSE;
1098 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1099 else if (dc->funcs->pGetTextMetrics)
1100 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1104 /* device layer returns values in device units
1105 * therefore we have to convert them to logical */
1107 #define WDPTOLP(x) ((x<0)? \
1108 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1109 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1110 #define HDPTOLP(y) ((y<0)? \
1111 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1112 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1114 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1115 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1116 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1117 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1118 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1119 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1120 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1121 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1125 TRACE("text metrics:\n"
1126 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1127 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1128 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1129 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1130 " PitchAndFamily = %02x\n"
1131 " --------------------\n"
1132 " InternalLeading = %li\n"
1136 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1137 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1138 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1139 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1140 metrics->tmPitchAndFamily,
1141 metrics->tmInternalLeading,
1144 metrics->tmHeight );
1146 GDI_ReleaseObj( hdc );
1151 /***********************************************************************
1152 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1155 * lpOTM should be LPOUTLINETEXTMETRIC
1158 * Success: Non-zero or size of required buffer
1161 UINT16 WINAPI GetOutlineTextMetrics16(
1162 HDC16 hdc, /* [in] Handle of device context */
1163 UINT16 cbData, /* [in] Size of metric data array */
1164 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1166 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1171 /***********************************************************************
1172 * GetOutlineTextMetricsA (GDI32.@)
1173 * Gets metrics for TrueType fonts.
1177 * Success: Non-zero or size of required buffer
1180 UINT WINAPI GetOutlineTextMetricsA(
1181 HDC hdc, /* [in] Handle of device context */
1182 UINT cbData, /* [in] Size of metric data array */
1183 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1185 char buf[512], *ptr;
1187 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1190 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1191 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1193 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1194 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1197 needed = sizeof(OUTLINETEXTMETRICA);
1198 if(lpOTMW->otmpFamilyName)
1199 needed += WideCharToMultiByte(CP_ACP, 0,
1200 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1201 NULL, 0, NULL, NULL);
1202 if(lpOTMW->otmpFaceName)
1203 needed += WideCharToMultiByte(CP_ACP, 0,
1204 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1205 NULL, 0, NULL, NULL);
1206 if(lpOTMW->otmpStyleName)
1207 needed += WideCharToMultiByte(CP_ACP, 0,
1208 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1209 NULL, 0, NULL, NULL);
1210 if(lpOTMW->otmpFullName)
1211 needed += WideCharToMultiByte(CP_ACP, 0,
1212 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1213 NULL, 0, NULL, NULL);
1220 if(needed > cbData) {
1226 lpOTM->otmSize = needed;
1227 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1228 lpOTM->otmFiller = 0;
1229 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1230 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1231 lpOTM->otmfsType = lpOTMW->otmfsType;
1232 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1233 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1234 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1235 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1236 lpOTM->otmAscent = lpOTMW->otmAscent;
1237 lpOTM->otmDescent = lpOTMW->otmDescent;
1238 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1239 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1240 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1241 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1242 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1243 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1244 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1245 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1246 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1247 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1248 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1249 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1250 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1251 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1252 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1253 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1256 ptr = (char*)(lpOTM + 1);
1257 left = needed - sizeof(*lpOTM);
1259 if(lpOTMW->otmpFamilyName) {
1260 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1261 len = WideCharToMultiByte(CP_ACP, 0,
1262 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1263 ptr, left, NULL, NULL);
1267 lpOTM->otmpFamilyName = 0;
1269 if(lpOTMW->otmpFaceName) {
1270 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1271 len = WideCharToMultiByte(CP_ACP, 0,
1272 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1273 ptr, left, NULL, NULL);
1277 lpOTM->otmpFaceName = 0;
1279 if(lpOTMW->otmpStyleName) {
1280 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1281 len = WideCharToMultiByte(CP_ACP, 0,
1282 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1283 ptr, left, NULL, NULL);
1287 lpOTM->otmpStyleName = 0;
1289 if(lpOTMW->otmpFullName) {
1290 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1291 len = WideCharToMultiByte(CP_ACP, 0,
1292 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1293 ptr, left, NULL, NULL);
1296 lpOTM->otmpFullName = 0;
1303 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1304 HeapFree(GetProcessHeap(), 0, lpOTMW);
1310 /***********************************************************************
1311 * GetOutlineTextMetricsW [GDI32.@]
1313 UINT WINAPI GetOutlineTextMetricsW(
1314 HDC hdc, /* [in] Handle of device context */
1315 UINT cbData, /* [in] Size of metric data array */
1316 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1318 DC *dc = DC_GetDCPtr( hdc );
1321 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1325 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1326 if(ret && ret <= cbData) {
1327 #define WDPTOLP(x) ((x<0)? \
1328 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1329 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1330 #define HDPTOLP(y) ((y<0)? \
1331 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1332 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1334 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1335 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1336 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1337 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1338 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1339 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1340 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1341 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1342 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1343 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1344 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1345 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1346 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1347 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1348 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1349 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1350 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1351 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1352 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1353 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1354 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1355 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1356 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1357 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1358 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1359 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1360 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1361 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1362 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1363 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1364 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1365 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1371 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1372 but really this should just be a return 0. */
1374 ret = sizeof(*lpOTM);
1379 memset(lpOTM, 0, ret);
1380 lpOTM->otmSize = sizeof(*lpOTM);
1381 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1383 Further fill of the structure not implemented,
1384 Needs real values for the structure members
1389 GDI_ReleaseObj(hdc);
1394 /***********************************************************************
1395 * GetCharWidthW (GDI32.@)
1396 * GetCharWidth32W (GDI32.@)
1398 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1403 DC * dc = DC_GetDCPtr( hdc );
1404 if (!dc) return FALSE;
1407 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1408 else if (dc->funcs->pGetCharWidth)
1409 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1413 /* convert device units to logical */
1415 extra = dc->vportExtX >> 1;
1416 for( i = firstChar; i <= lastChar; i++, buffer++ )
1417 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1420 GDI_ReleaseObj( hdc );
1425 /***********************************************************************
1426 * GetCharWidthA (GDI32.@)
1427 * GetCharWidth32A (GDI32.@)
1429 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1432 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1437 if(count <= 0) return FALSE;
1439 str = HeapAlloc(GetProcessHeap(), 0, count);
1440 for(i = 0; i < count; i++)
1441 str[i] = (BYTE)(firstChar + i);
1443 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1445 for(i = 0; i < wlen; i++)
1447 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1455 HeapFree(GetProcessHeap(), 0, str);
1456 HeapFree(GetProcessHeap(), 0, wstr);
1462 /* FIXME: all following APIs ******************************************/
1465 /***********************************************************************
1466 * SetMapperFlags (GDI32.@)
1468 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1470 DC *dc = DC_GetDCPtr( hDC );
1473 if(dc->funcs->pSetMapperFlags)
1474 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1476 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1477 GDI_ReleaseObj( hDC );
1481 /***********************************************************************
1482 * GetAspectRatioFilterEx (GDI.486)
1484 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1486 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1490 /***********************************************************************
1491 * GetAspectRatioFilterEx (GDI32.@)
1493 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1495 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1500 /***********************************************************************
1501 * GetCharABCWidthsA (GDI32.@)
1503 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1506 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1511 if(count <= 0) return FALSE;
1513 str = HeapAlloc(GetProcessHeap(), 0, count);
1514 for(i = 0; i < count; i++)
1515 str[i] = (BYTE)(firstChar + i);
1517 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1519 for(i = 0; i < wlen; i++)
1521 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1529 HeapFree(GetProcessHeap(), 0, str);
1530 HeapFree(GetProcessHeap(), 0, wstr);
1536 /******************************************************************************
1537 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1540 * hdc [I] Handle of device context
1541 * firstChar [I] First character in range to query
1542 * lastChar [I] Last character in range to query
1543 * abc [O] Address of character-width structure
1546 * Only works with TrueType fonts
1552 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1555 DC *dc = DC_GetDCPtr(hdc);
1561 for (i=firstChar;i<=lastChar;i++) {
1562 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1563 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1564 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1565 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1569 GDI_ReleaseObj(hdc);
1574 /***********************************************************************
1575 * GetGlyphOutline (GDI.309)
1577 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1578 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1579 LPVOID lpBuffer, const MAT2 *lpmat2 )
1581 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1582 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1583 return (DWORD)-1; /* failure */
1587 /***********************************************************************
1588 * GetGlyphOutlineA (GDI32.@)
1590 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1591 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1592 LPVOID lpBuffer, const MAT2 *lpmat2 )
1598 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1599 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1603 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1606 HeapFree(GetProcessHeap(), 0, p);
1610 /***********************************************************************
1611 * GetGlyphOutlineW (GDI32.@)
1613 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1614 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1615 LPVOID lpBuffer, const MAT2 *lpmat2 )
1617 DC *dc = DC_GetDCPtr(hdc);
1620 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1621 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1623 if(!dc) return GDI_ERROR;
1626 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1627 cbBuffer, lpBuffer, lpmat2);
1631 GDI_ReleaseObj(hdc);
1636 /***********************************************************************
1637 * CreateScalableFontResourceA (GDI32.@)
1639 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1640 LPCSTR lpszResourceFile,
1641 LPCSTR lpszFontFile,
1642 LPCSTR lpszCurrentPath )
1646 /* fHidden=1 - only visible for the calling app, read-only, not
1647 * enumbered with EnumFonts/EnumFontFamilies
1648 * lpszCurrentPath can be NULL
1650 FIXME("(%ld,%s,%s,%s): stub\n",
1651 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1652 debugstr_a(lpszCurrentPath) );
1654 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1655 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1657 SetLastError(ERROR_FILE_EXISTS);
1660 return FALSE; /* create failed */
1663 /***********************************************************************
1664 * CreateScalableFontResourceW (GDI32.@)
1666 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1667 LPCWSTR lpszResourceFile,
1668 LPCWSTR lpszFontFile,
1669 LPCWSTR lpszCurrentPath )
1671 FIXME("(%ld,%p,%p,%p): stub\n",
1672 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1673 return FALSE; /* create failed */
1677 /*************************************************************************
1678 * GetRasterizerCaps (GDI32.@)
1680 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1682 lprs->nSize = sizeof(RASTERIZER_STATUS);
1683 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1684 lprs->nLanguageID = 0;
1689 /*************************************************************************
1690 * GetKerningPairsA (GDI32.@)
1692 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1695 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1696 for (i = 0; i < cPairs; i++)
1697 lpKerningPairs[i].iKernAmount = 0;
1702 /*************************************************************************
1703 * GetKerningPairsW (GDI32.@)
1705 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1706 LPKERNINGPAIR lpKerningPairs )
1708 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1711 /*************************************************************************
1712 * TranslateCharsetInfo [GDI32.@]
1714 * Fills a CHARSETINFO structure for a character set, code page, or
1715 * font. This allows making the correspondance between different labelings
1716 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1717 * of the same encoding.
1719 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1720 * only one codepage should be set in *lpSrc.
1723 * TRUE on success, FALSE on failure.
1726 BOOL WINAPI TranslateCharsetInfo(
1727 LPDWORD lpSrc, /* [in]
1728 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1729 if flags == TCI_SRCCHARSET: a character set value
1730 if flags == TCI_SRCCODEPAGE: a code page value
1732 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1733 DWORD flags /* [in] determines interpretation of lpSrc */
1737 case TCI_SRCFONTSIG:
1738 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1740 case TCI_SRCCODEPAGE:
1741 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1743 case TCI_SRCCHARSET:
1744 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1749 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1750 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1754 /*************************************************************************
1755 * GetFontLanguageInfo (GDI32.@)
1757 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1759 FONTSIGNATURE fontsig;
1760 static const DWORD GCP_DBCS_MASK=0x003F0000,
1761 GCP_DIACRITIC_MASK=0x00000000,
1762 FLI_GLYPHS_MASK=0x00000000,
1763 GCP_GLYPHSHAPE_MASK=0x00000040,
1764 GCP_KASHIDA_MASK=0x00000000,
1765 GCP_LIGATE_MASK=0x00000000,
1766 GCP_USEKERNING_MASK=0x00000000,
1767 GCP_REORDER_MASK=0x00000060;
1771 GetTextCharsetInfo( hdc, &fontsig, 0 );
1772 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1774 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1777 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1778 result|=GCP_DIACRITIC;
1780 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1783 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1784 result|=GCP_GLYPHSHAPE;
1786 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1787 result|=GCP_KASHIDA;
1789 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1792 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1793 result|=GCP_USEKERNING;
1795 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1796 result|=GCP_REORDER;
1802 /*************************************************************************
1803 * GetFontData [GDI32.@] Retrieve data for TrueType font
1807 * success: Number of bytes returned
1808 * failure: GDI_ERROR
1812 * Calls SetLastError()
1815 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1816 LPVOID buffer, DWORD length)
1818 DC *dc = DC_GetDCPtr(hdc);
1819 DWORD ret = GDI_ERROR;
1821 if(!dc) return GDI_ERROR;
1824 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1826 GDI_ReleaseObj(hdc);
1830 /*************************************************************************
1831 * GetGlyphIndicesA [GDI32.@]
1833 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1834 LPWORD pgi, DWORD flags)
1840 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1841 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1843 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1844 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1845 HeapFree(GetProcessHeap(), 0, lpstrW);
1850 /*************************************************************************
1851 * GetGlyphIndicesW [GDI32.@]
1853 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1854 LPWORD pgi, DWORD flags)
1856 DC *dc = DC_GetDCPtr(hdc);
1857 DWORD ret = GDI_ERROR;
1859 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1860 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1862 if(!dc) return GDI_ERROR;
1865 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1867 GDI_ReleaseObj(hdc);
1871 /*************************************************************************
1872 * GetCharacterPlacementA [GDI32.@]
1875 * the web browser control of ie4 calls this with dwFlags=0
1878 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1879 INT nMaxExtent, GCP_RESULTSA *lpResults,
1884 GCP_RESULTSW resultsW;
1888 TRACE("%s, %d, %d, 0x%08lx\n",
1889 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1891 /* both structs are equal in size */
1892 memcpy(&resultsW, lpResults, sizeof(resultsW));
1894 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1895 if(lpResults->lpOutString)
1896 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1898 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1900 if(lpResults->lpOutString) {
1901 if(font_cp != CP_SYMBOL)
1902 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1903 lpResults->lpOutString, uCount, NULL, NULL );
1905 for(i = 0; i < uCount; i++)
1906 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1909 HeapFree(GetProcessHeap(), 0, lpStringW);
1910 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1915 /*************************************************************************
1916 * GetCharacterPlacementW [GDI32.@]
1918 * Retrieve information about a string. This includes the width, reordering,
1919 * Glyphing and so on.
1923 * The width and height of the string if succesful, 0 if failed.
1927 * All flags except GCP_REORDER are not yet implemented.
1928 * Reordering is not 100% complient to the Windows BiDi method.
1929 * Caret positioning is not yet implemented.
1930 * Classes are not yet implemented.
1934 GetCharacterPlacementW(
1935 HDC hdc, /* [in] Device context for which the rendering is to be done */
1936 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1937 INT uCount, /* [in] Number of WORDS in string. */
1938 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1939 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1940 DWORD dwFlags /* [in] Flags specifying how to process the string */
1947 TRACE("%s, %d, %d, 0x%08lx\n",
1948 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1950 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1951 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1952 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1953 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1954 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1956 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1957 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1958 if(lpResults->lpClass) FIXME("classes not implemented\n");
1960 nSet = (UINT)uCount;
1961 if(nSet > lpResults->nGlyphs)
1962 nSet = lpResults->nGlyphs;
1964 /* return number of initialized fields */
1965 lpResults->nGlyphs = nSet;
1969 /* Treat the case where no special handling was requested in a fastpath way */
1970 /* copy will do if the GCP_REORDER flag is not set */
1971 if(lpResults->lpOutString)
1972 for(i=0; i<nSet && lpString[i]!=0; ++i )
1973 lpResults->lpOutString[i]=lpString[i];
1975 if(lpResults->lpOrder)
1977 for(i = 0; i < nSet; i++)
1978 lpResults->lpOrder[i] = i;
1982 if((dwFlags&GCP_REORDER)!=0)
1986 /* Keep a static table that translates the C2 types to something meaningful */
1987 /* 1 - left to right
1988 * -1 - right to left
1991 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
1993 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
1994 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
1996 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2001 /* Fill in the order array with directionality values */
2002 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2004 /* The complete and correct (at least according to MS) BiDi algorythm is not
2005 * yet implemented here. Instead, we just make sure that consecutive runs of
2006 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2007 * that are between runs of opposing directions the base (ok, always LTR) dir.
2008 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2011 for( i=0; i<uCount; i+=run_end )
2013 for( run_end=1; i+run_end<uCount &&
2014 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2015 chardir[pwCharType[i+run_end]]==0); ++run_end )
2018 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2021 if(lpResults->lpOutString)
2024 for( j=0; j<run_end; j++ )
2026 lpResults->lpOutString[i+j]=lpString[i+j];
2030 if(lpResults->lpOrder)
2033 for( j=0; j<run_end; j++ )
2034 lpResults->lpOrder[i+j] = i+j;
2040 /* Since, at this stage, the paragraph context is always LTR,
2041 * remove any neutrals from the end of this run.
2043 if( chardir[pwCharType[i]]!=0 )
2044 while( chardir[pwCharType[i+run_end-1]]==0 )
2047 if(lpResults->lpOutString)
2050 for( j=0; j<run_end; j++ )
2052 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2056 if(lpResults->lpOrder)
2059 for( j=0; j<run_end; j++ )
2060 lpResults->lpOrder[i+j] = i+run_end-j-1;
2065 HeapFree(GetProcessHeap(), 0, pwCharType);
2068 /* FIXME: Will use the placement chars */
2069 if (lpResults->lpDx)
2072 for (i = 0; i < nSet; i++)
2074 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2075 lpResults->lpDx[i]= c;
2079 if(lpResults->lpGlyphs)
2080 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2082 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2083 ret = MAKELONG(size.cx, size.cy);
2088 /*************************************************************************
2089 * GetCharABCWidthsFloatA [GDI32.@]
2091 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2094 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2098 /*************************************************************************
2099 * GetCharABCWidthsFloatW [GDI32.@]
2101 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2102 UINT iLastChar, LPABCFLOAT lpABCF)
2104 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2108 /*************************************************************************
2109 * GetCharWidthFloatA [GDI32.@]
2111 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2112 UINT iLastChar, PFLOAT pxBuffer)
2114 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2118 /*************************************************************************
2119 * GetCharWidthFloatW [GDI32.@]
2121 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2122 UINT iLastChar, PFLOAT pxBuffer)
2124 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2129 /***********************************************************************
2131 * Font Resource API *
2133 ***********************************************************************/
2135 /***********************************************************************
2136 * AddFontResourceA (GDI32.@)
2138 INT WINAPI AddFontResourceA( LPCSTR str )
2140 return AddFontResourceExA( str, 0, NULL);
2143 /***********************************************************************
2144 * AddFontResourceW (GDI32.@)
2146 INT WINAPI AddFontResourceW( LPCWSTR str )
2148 return AddFontResourceExW(str, 0, NULL);
2152 /***********************************************************************
2153 * AddFontResourceExA (GDI32.@)
2155 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2157 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2158 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2161 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2162 ret = AddFontResourceExW(strW, fl, pdv);
2163 HeapFree(GetProcessHeap(), 0, strW);
2167 /***********************************************************************
2168 * AddFontResourceExW (GDI32.@)
2170 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2172 return WineEngAddFontResourceEx(str, fl, pdv);
2175 /***********************************************************************
2176 * RemoveFontResourceA (GDI32.@)
2178 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2180 return RemoveFontResourceExA(str, 0, 0);
2183 /***********************************************************************
2184 * RemoveFontResourceW (GDI32.@)
2186 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2188 return RemoveFontResourceExW(str, 0, 0);
2191 /***********************************************************************
2192 * RemoveFontResourceExA (GDI32.@)
2194 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2196 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2197 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2200 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2201 ret = RemoveFontResourceExW(strW, fl, pdv);
2202 HeapFree(GetProcessHeap(), 0, strW);
2206 /***********************************************************************
2207 * RemoveFontResourceExW (GDI32.@)
2209 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2211 return WineEngRemoveFontResourceEx(str, fl, pdv);