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"
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(font);
36 WINE_DECLARE_DEBUG_CHANNEL(gdi);
38 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
39 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
40 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
44 static const struct gdi_obj_funcs font_funcs =
46 FONT_SelectObject, /* pSelectObject */
47 FONT_GetObject16, /* pGetObject16 */
48 FONT_GetObjectA, /* pGetObjectA */
49 FONT_GetObjectW, /* pGetObjectW */
50 NULL, /* pUnrealizeObject */
51 FONT_DeleteObject /* pDeleteObject */
54 #define ENUM_UNICODE 0x00000001
55 #define ENUM_CALLED 0x00000002
65 LPLOGFONT16 lpLogFontParam;
66 FONTENUMPROC16 lpEnumFunc;
69 LPNEWTEXTMETRICEX16 lpTextMetric;
70 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 => %p\n",
323 plf->lfHeight, plf->lfWidth,
324 plf->lfEscapement, plf->lfOrientation,
325 plf->lfPitchAndFamily,
326 plf->lfOutPrecision, plf->lfClipPrecision,
327 plf->lfQuality, plf->lfCharSet,
328 debugstr_w(plf->lfFaceName),
329 plf->lfWeight > 400 ? "Bold" : "",
330 plf->lfItalic ? "Italic" : "", hFont);
332 if (plf->lfEscapement != plf->lfOrientation) {
333 /* this should really depend on whether GM_ADVANCED is set */
334 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
335 WARN("orientation angle %f set to "
336 "escapement angle %f for new font %p\n",
337 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
339 GDI_ReleaseObj( hFont );
342 else WARN("(NULL) => NULL\n");
347 /*************************************************************************
348 * CreateFontA (GDI32.@)
350 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
351 INT orient, INT weight, DWORD italic,
352 DWORD underline, DWORD strikeout, DWORD charset,
353 DWORD outpres, DWORD clippres, DWORD quality,
354 DWORD pitch, LPCSTR name )
358 logfont.lfHeight = height;
359 logfont.lfWidth = width;
360 logfont.lfEscapement = esc;
361 logfont.lfOrientation = orient;
362 logfont.lfWeight = weight;
363 logfont.lfItalic = italic;
364 logfont.lfUnderline = underline;
365 logfont.lfStrikeOut = strikeout;
366 logfont.lfCharSet = charset;
367 logfont.lfOutPrecision = outpres;
368 logfont.lfClipPrecision = clippres;
369 logfont.lfQuality = quality;
370 logfont.lfPitchAndFamily = pitch;
373 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
375 logfont.lfFaceName[0] = '\0';
377 return CreateFontIndirectA( &logfont );
380 /*************************************************************************
381 * CreateFontW (GDI32.@)
383 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
384 INT orient, INT weight, DWORD italic,
385 DWORD underline, DWORD strikeout, DWORD charset,
386 DWORD outpres, DWORD clippres, DWORD quality,
387 DWORD pitch, LPCWSTR name )
391 logfont.lfHeight = height;
392 logfont.lfWidth = width;
393 logfont.lfEscapement = esc;
394 logfont.lfOrientation = orient;
395 logfont.lfWeight = weight;
396 logfont.lfItalic = italic;
397 logfont.lfUnderline = underline;
398 logfont.lfStrikeOut = strikeout;
399 logfont.lfCharSet = charset;
400 logfont.lfOutPrecision = outpres;
401 logfont.lfClipPrecision = clippres;
402 logfont.lfQuality = quality;
403 logfont.lfPitchAndFamily = pitch;
406 lstrcpynW(logfont.lfFaceName, name,
407 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
409 logfont.lfFaceName[0] = '\0';
411 return CreateFontIndirectW( &logfont );
415 /***********************************************************************
418 * If the driver supports vector fonts we create a gdi font first and
419 * then call the driver to give it a chance to supply its own device
420 * font. If the driver wants to do this it returns TRUE and we can
421 * delete the gdi font, if the driver wants to use the gdi font it
422 * should return FALSE, to signal an error return GDI_ERROR. For
423 * drivers that don't support vector fonts they must supply their own
426 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
429 DC *dc = DC_GetDCPtr( hdc );
433 if (dc->hFont != handle || dc->gdiFont == NULL)
435 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
436 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
439 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
441 if (ret && dc->gdiFont) dc->gdiFont = 0;
443 if (ret == HGDI_ERROR)
444 ret = 0; /* SelectObject returns 0 on error */
450 GDI_ReleaseObj( hdc );
455 /***********************************************************************
458 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
463 FONT_LogFontWTo16( &font->logfont, &lf16 );
465 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
466 memcpy( buffer, &lf16, count );
470 /***********************************************************************
473 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
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 pfe->dwFlags |= ENUM_CALLED;
528 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
530 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
531 (UINT16)fType, (LPARAM)pfe->lpData );
532 /* get the lock again and make sure the DC is still valid */
533 dc = DC_GetDCPtr( pfe->hdc );
534 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
536 if (dc) GDI_ReleaseObj( pfe->hdc );
537 pfe->hdc = 0; /* make sure we don't try to release it later on */
544 /***********************************************************************
547 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
548 DWORD fType, LPARAM lp )
550 fontEnum32 *pfe = (fontEnum32*)lp;
554 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
555 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
556 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
558 /* convert font metrics */
559 ENUMLOGFONTEXA logfont;
560 NEWTEXTMETRICEXA tmA;
562 pfe->dwFlags |= ENUM_CALLED;
563 if (!(pfe->dwFlags & ENUM_UNICODE))
565 FONT_EnumLogFontExWToA( plf, &logfont);
566 FONT_NewTextMetricExWToA( ptm, &tmA );
567 plf = (LPENUMLOGFONTEXW)&logfont;
568 ptm = (NEWTEXTMETRICEXW *)&tmA;
570 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
572 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
574 /* get the lock again and make sure the DC is still valid */
575 dc = DC_GetDCPtr( pfe->hdc );
576 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
578 if (dc) GDI_ReleaseObj( pfe->hdc );
579 pfe->hdc = 0; /* make sure we don't try to release it later on */
586 /***********************************************************************
587 * EnumFontFamiliesEx (GDI.613)
589 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
590 FONTENUMPROC16 efproc, LPARAM lParam,
595 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
596 NEWTEXTMETRICEX16 tm16;
597 ENUMLOGFONTEX16 lf16;
602 FONT_LogFont16ToW(plf, &lfW);
604 fe16.hdc = HDC_32(hDC);
606 fe16.physDev = dc->physDev;
607 fe16.lpLogFontParam = plf;
608 fe16.lpEnumFunc = efproc;
609 fe16.lpData = lParam;
610 fe16.lpTextMetric = &tm16;
611 fe16.lpLogFont = &lf16;
612 fe16.segTextMetric = MapLS( &tm16 );
613 fe16.segLogFont = MapLS( &lf16 );
616 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
618 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
625 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
626 fe16.dwFlags &= ~ENUM_CALLED;
627 if (ret && dc->funcs->pEnumDeviceFonts) {
628 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
629 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
633 UnMapLS( fe16.segTextMetric );
634 UnMapLS( fe16.segLogFont );
635 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
639 /***********************************************************************
640 * FONT_EnumFontFamiliesEx
642 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
643 FONTENUMPROCW efproc,
644 LPARAM lParam, DWORD dwUnicode)
647 DC *dc = DC_GetDCPtr( hDC );
653 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
655 fe32.lpLogFontParam = plf;
656 fe32.lpEnumFunc = efproc;
657 fe32.lpData = lParam;
658 fe32.dwFlags = dwUnicode;
661 fe32.physDev = dc->physDev;
663 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
665 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
672 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
673 fe32.dwFlags &= ~ENUM_CALLED;
674 if (ret && dc->funcs->pEnumDeviceFonts) {
675 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
676 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
680 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
684 /***********************************************************************
685 * EnumFontFamiliesExW (GDI32.@)
687 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
688 FONTENUMPROCW efproc,
689 LPARAM lParam, DWORD dwFlags )
691 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
694 /***********************************************************************
695 * EnumFontFamiliesExA (GDI32.@)
697 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
698 FONTENUMPROCA efproc,
699 LPARAM lParam, DWORD dwFlags)
702 FONT_LogFontAToW( plf, &lfW );
704 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
707 /***********************************************************************
708 * EnumFontFamilies (GDI.330)
710 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
711 FONTENUMPROC16 efproc, LPARAM lpData )
715 lf.lfCharSet = DEFAULT_CHARSET;
716 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
717 else lf.lfFaceName[0] = '\0';
719 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
722 /***********************************************************************
723 * EnumFontFamiliesA (GDI32.@)
725 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
726 FONTENUMPROCA efproc, LPARAM lpData )
730 lf.lfCharSet = DEFAULT_CHARSET;
731 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
732 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
734 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
737 /***********************************************************************
738 * EnumFontFamiliesW (GDI32.@)
740 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
741 FONTENUMPROCW efproc, LPARAM lpData )
745 lf.lfCharSet = DEFAULT_CHARSET;
746 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
747 else lf.lfFaceName[0] = 0;
749 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
752 /***********************************************************************
755 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
758 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
761 /***********************************************************************
762 * EnumFontsA (GDI32.@)
764 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
767 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
770 /***********************************************************************
771 * EnumFontsW (GDI32.@)
773 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
776 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
780 /***********************************************************************
781 * GetTextCharacterExtra (GDI32.@)
783 INT WINAPI GetTextCharacterExtra( HDC hdc )
786 DC *dc = DC_GetDCPtr( hdc );
787 if (!dc) return 0x80000000;
789 GDI_ReleaseObj( hdc );
794 /***********************************************************************
795 * SetTextCharacterExtra (GDI32.@)
797 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
800 DC * dc = DC_GetDCPtr( hdc );
801 if (!dc) return 0x80000000;
802 if (dc->funcs->pSetTextCharacterExtra)
803 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
806 prev = dc->charExtra;
807 dc->charExtra = extra;
809 GDI_ReleaseObj( hdc );
814 /***********************************************************************
815 * SetTextJustification (GDI32.@)
817 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
820 DC * dc = DC_GetDCPtr( hdc );
821 if (!dc) return FALSE;
822 if (dc->funcs->pSetTextJustification)
823 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
826 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
827 if (!extra) breaks = 0;
828 dc->breakTotalExtra = extra;
829 dc->breakCount = breaks;
832 dc->breakExtra = extra / breaks;
833 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
841 GDI_ReleaseObj( hdc );
846 /***********************************************************************
847 * GetTextFaceA (GDI32.@)
849 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
851 INT res = GetTextFaceW(hdc, 0, NULL);
852 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
853 GetTextFaceW( hdc, res, nameW );
856 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
859 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
860 HeapFree( GetProcessHeap(), 0, nameW );
864 /***********************************************************************
865 * GetTextFaceW (GDI32.@)
867 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
872 DC * dc = DC_GetDCPtr( hdc );
876 ret = WineEngGetTextFace(dc->gdiFont, count, name);
877 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
881 lstrcpynW( name, font->logfont.lfFaceName, count );
884 else ret = strlenW(font->logfont.lfFaceName) + 1;
885 GDI_ReleaseObj( dc->hFont );
887 GDI_ReleaseObj( hdc );
892 /***********************************************************************
893 * GetTextExtentPoint32A (GDI32.@)
895 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
900 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
903 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
904 HeapFree( GetProcessHeap(), 0, p );
907 TRACE("(%p %s %d %p): returning %ld x %ld\n",
908 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
913 /***********************************************************************
914 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
916 * Computes width and height of the specified string.
922 BOOL WINAPI GetTextExtentPoint32W(
923 HDC hdc, /* [in] Handle of device context */
924 LPCWSTR str, /* [in] Address of text string */
925 INT count, /* [in] Number of characters in string */
926 LPSIZE size) /* [out] Address of structure for string size */
929 DC * dc = DC_GetDCPtr( hdc );
930 if (!dc) return FALSE;
933 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
934 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
935 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
937 else if(dc->funcs->pGetTextExtentPoint)
938 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
940 GDI_ReleaseObj( hdc );
942 TRACE("(%p %s %d %p): returning %ld x %ld\n",
943 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
947 /***********************************************************************
948 * GetTextExtentPointI [GDI32.@]
950 * Computes width and height of the array of glyph indices.
956 BOOL WINAPI GetTextExtentPointI(
957 HDC hdc, /* [in] Handle of device context */
958 const WORD *indices, /* [in] Address of glyph index array */
959 INT count, /* [in] Number of glyphs in array */
960 LPSIZE size) /* [out] Address of structure for string size */
963 DC * dc = DC_GetDCPtr( hdc );
964 if (!dc) return FALSE;
967 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
968 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
969 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
971 else if(dc->funcs->pGetTextExtentPoint) {
972 FIXME("calling GetTextExtentPoint\n");
973 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
976 GDI_ReleaseObj( hdc );
978 TRACE("(%p %p %d %p): returning %ld x %ld\n",
979 hdc, indices, count, size, size->cx, size->cy );
984 /***********************************************************************
985 * GetTextExtentPointA (GDI32.@)
987 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
990 TRACE("not bug compatible.\n");
991 return GetTextExtentPoint32A( hdc, str, count, size );
994 /***********************************************************************
995 * GetTextExtentPointW (GDI32.@)
997 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1000 TRACE("not bug compatible.\n");
1001 return GetTextExtentPoint32W( hdc, str, count, size );
1005 /***********************************************************************
1006 * GetTextExtentExPointA (GDI32.@)
1008 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1009 INT maxExt, LPINT lpnFit,
1010 LPINT alpDx, LPSIZE size )
1014 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1015 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1016 HeapFree( GetProcessHeap(), 0, p );
1021 /***********************************************************************
1022 * GetTextExtentExPointW (GDI32.@)
1024 * Return the size of the string as it would be if it was output properly by
1027 * This should include
1028 * - Intercharacter spacing
1029 * - justification spacing (not yet done)
1030 * - kerning? see below
1032 * Kerning. Since kerning would be carried out by the rendering code it should
1033 * be done by the driver. However they don't support it yet. Also I am not
1034 * yet persuaded that (certainly under Win95) any kerning is actually done.
1036 * str: According to MSDN this should be null-terminated. That is not true; a
1037 * null will not terminate it early.
1038 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1039 * than count. I have seen it be either the size of the full string or
1040 * 1 less than the size of the full string. I have not seen it bear any
1041 * resemblance to the portion that would fit.
1042 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1043 * trailing intercharacter spacing and any trailing justification.
1046 * Currently we do this by measuring each character etc. We should do it by
1047 * passing the request to the driver, perhaps by extending the
1048 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1049 * thinking about kerning issues and rounding issues in the justification.
1052 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1053 INT maxExt, LPINT lpnFit,
1054 LPINT alpDx, LPSIZE size )
1056 int index, nFit, extent;
1060 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1062 size->cx = size->cy = nFit = extent = 0;
1063 for(index = 0; index < count; index++)
1065 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1066 /* GetTextExtentPoint includes intercharacter spacing. */
1067 /* FIXME - justification needs doing yet. Remember that the base
1068 * data will not be in logical coordinates.
1071 if( !lpnFit || extent <= maxExt )
1072 /* It is allowed to be equal. */
1075 if( alpDx ) alpDx[index] = extent;
1077 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1081 if(lpnFit) *lpnFit = nFit;
1084 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1090 /***********************************************************************
1091 * GetTextMetricsA (GDI32.@)
1093 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1097 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1098 FONT_TextMetricWToA( &tm32, metrics );
1102 /***********************************************************************
1103 * GetTextMetricsW (GDI32.@)
1105 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1108 DC * dc = DC_GetDCPtr( hdc );
1109 if (!dc) return FALSE;
1112 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1113 else if (dc->funcs->pGetTextMetrics)
1114 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1118 /* device layer returns values in device units
1119 * therefore we have to convert them to logical */
1121 #define WDPTOLP(x) ((x<0)? \
1122 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1123 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1124 #define HDPTOLP(y) ((y<0)? \
1125 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1126 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1128 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1129 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1130 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1131 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1132 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1133 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1134 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1135 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1139 TRACE("text metrics:\n"
1140 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1141 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1142 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1143 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1144 " PitchAndFamily = %02x\n"
1145 " --------------------\n"
1146 " InternalLeading = %li\n"
1150 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1151 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1152 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1153 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1154 metrics->tmPitchAndFamily,
1155 metrics->tmInternalLeading,
1158 metrics->tmHeight );
1160 GDI_ReleaseObj( hdc );
1165 /***********************************************************************
1166 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1169 * lpOTM should be LPOUTLINETEXTMETRIC
1172 * Success: Non-zero or size of required buffer
1175 UINT16 WINAPI GetOutlineTextMetrics16(
1176 HDC16 hdc, /* [in] Handle of device context */
1177 UINT16 cbData, /* [in] Size of metric data array */
1178 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1180 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1185 /***********************************************************************
1186 * GetOutlineTextMetricsA (GDI32.@)
1187 * Gets metrics for TrueType fonts.
1191 * Success: Non-zero or size of required buffer
1194 UINT WINAPI GetOutlineTextMetricsA(
1195 HDC hdc, /* [in] Handle of device context */
1196 UINT cbData, /* [in] Size of metric data array */
1197 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1199 char buf[512], *ptr;
1201 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1204 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1205 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1207 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1208 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1211 needed = sizeof(OUTLINETEXTMETRICA);
1212 if(lpOTMW->otmpFamilyName)
1213 needed += WideCharToMultiByte(CP_ACP, 0,
1214 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1215 NULL, 0, NULL, NULL);
1216 if(lpOTMW->otmpFaceName)
1217 needed += WideCharToMultiByte(CP_ACP, 0,
1218 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1219 NULL, 0, NULL, NULL);
1220 if(lpOTMW->otmpStyleName)
1221 needed += WideCharToMultiByte(CP_ACP, 0,
1222 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1223 NULL, 0, NULL, NULL);
1224 if(lpOTMW->otmpFullName)
1225 needed += WideCharToMultiByte(CP_ACP, 0,
1226 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1227 NULL, 0, NULL, NULL);
1234 if(needed > cbData) {
1240 lpOTM->otmSize = needed;
1241 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1242 lpOTM->otmFiller = 0;
1243 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1244 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1245 lpOTM->otmfsType = lpOTMW->otmfsType;
1246 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1247 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1248 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1249 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1250 lpOTM->otmAscent = lpOTMW->otmAscent;
1251 lpOTM->otmDescent = lpOTMW->otmDescent;
1252 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1253 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1254 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1255 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1256 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1257 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1258 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1259 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1260 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1261 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1262 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1263 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1264 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1265 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1266 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1267 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1270 ptr = (char*)(lpOTM + 1);
1271 left = needed - sizeof(*lpOTM);
1273 if(lpOTMW->otmpFamilyName) {
1274 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1275 len = WideCharToMultiByte(CP_ACP, 0,
1276 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1277 ptr, left, NULL, NULL);
1281 lpOTM->otmpFamilyName = 0;
1283 if(lpOTMW->otmpFaceName) {
1284 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1285 len = WideCharToMultiByte(CP_ACP, 0,
1286 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1287 ptr, left, NULL, NULL);
1291 lpOTM->otmpFaceName = 0;
1293 if(lpOTMW->otmpStyleName) {
1294 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1295 len = WideCharToMultiByte(CP_ACP, 0,
1296 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1297 ptr, left, NULL, NULL);
1301 lpOTM->otmpStyleName = 0;
1303 if(lpOTMW->otmpFullName) {
1304 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1305 len = WideCharToMultiByte(CP_ACP, 0,
1306 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1307 ptr, left, NULL, NULL);
1310 lpOTM->otmpFullName = 0;
1317 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1318 HeapFree(GetProcessHeap(), 0, lpOTMW);
1324 /***********************************************************************
1325 * GetOutlineTextMetricsW [GDI32.@]
1327 UINT WINAPI GetOutlineTextMetricsW(
1328 HDC hdc, /* [in] Handle of device context */
1329 UINT cbData, /* [in] Size of metric data array */
1330 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1332 DC *dc = DC_GetDCPtr( hdc );
1335 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1339 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1340 if(ret && ret <= cbData) {
1341 #define WDPTOLP(x) ((x<0)? \
1342 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1343 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1344 #define HDPTOLP(y) ((y<0)? \
1345 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1346 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1348 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1349 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1350 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1351 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1352 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1353 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1354 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1355 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1356 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1357 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1358 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1359 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1360 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1361 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1362 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1363 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1364 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1365 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1366 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1367 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1368 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1369 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1370 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1371 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1372 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1373 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1374 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1375 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1376 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1377 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1378 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1379 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1385 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1386 but really this should just be a return 0. */
1388 ret = sizeof(*lpOTM);
1393 memset(lpOTM, 0, ret);
1394 lpOTM->otmSize = sizeof(*lpOTM);
1395 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1397 Further fill of the structure not implemented,
1398 Needs real values for the structure members
1403 GDI_ReleaseObj(hdc);
1408 /***********************************************************************
1409 * GetCharWidthW (GDI32.@)
1410 * GetCharWidth32W (GDI32.@)
1412 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1417 DC * dc = DC_GetDCPtr( hdc );
1418 if (!dc) return FALSE;
1421 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1422 else if (dc->funcs->pGetCharWidth)
1423 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1427 /* convert device units to logical */
1429 extra = dc->vportExtX >> 1;
1430 for( i = firstChar; i <= lastChar; i++, buffer++ )
1431 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1434 GDI_ReleaseObj( hdc );
1439 /***********************************************************************
1440 * GetCharWidthA (GDI32.@)
1441 * GetCharWidth32A (GDI32.@)
1443 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1446 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1451 if(count <= 0) return FALSE;
1453 str = HeapAlloc(GetProcessHeap(), 0, count);
1454 for(i = 0; i < count; i++)
1455 str[i] = (BYTE)(firstChar + i);
1457 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1459 for(i = 0; i < wlen; i++)
1461 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1469 HeapFree(GetProcessHeap(), 0, str);
1470 HeapFree(GetProcessHeap(), 0, wstr);
1476 /* FIXME: all following APIs ******************************************/
1479 /***********************************************************************
1480 * SetMapperFlags (GDI32.@)
1482 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1484 DC *dc = DC_GetDCPtr( hDC );
1487 if(dc->funcs->pSetMapperFlags)
1488 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1490 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1491 GDI_ReleaseObj( hDC );
1495 /***********************************************************************
1496 * GetAspectRatioFilterEx (GDI.486)
1498 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1500 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1504 /***********************************************************************
1505 * GetAspectRatioFilterEx (GDI32.@)
1507 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1509 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1514 /***********************************************************************
1515 * GetCharABCWidthsA (GDI32.@)
1517 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1520 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1525 if(count <= 0) return FALSE;
1527 str = HeapAlloc(GetProcessHeap(), 0, count);
1528 for(i = 0; i < count; i++)
1529 str[i] = (BYTE)(firstChar + i);
1531 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1533 for(i = 0; i < wlen; i++)
1535 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1543 HeapFree(GetProcessHeap(), 0, str);
1544 HeapFree(GetProcessHeap(), 0, wstr);
1550 /******************************************************************************
1551 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1554 * hdc [I] Handle of device context
1555 * firstChar [I] First character in range to query
1556 * lastChar [I] Last character in range to query
1557 * abc [O] Address of character-width structure
1560 * Only works with TrueType fonts
1566 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1569 DC *dc = DC_GetDCPtr(hdc);
1575 for (i=firstChar;i<=lastChar;i++) {
1576 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1577 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1578 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1579 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1583 GDI_ReleaseObj(hdc);
1588 /***********************************************************************
1589 * GetGlyphOutline (GDI.309)
1591 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1592 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1593 LPVOID lpBuffer, const MAT2 *lpmat2 )
1595 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1596 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1597 return (DWORD)-1; /* failure */
1601 /***********************************************************************
1602 * GetGlyphOutlineA (GDI32.@)
1604 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1605 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1606 LPVOID lpBuffer, const MAT2 *lpmat2 )
1612 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1613 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1617 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1620 HeapFree(GetProcessHeap(), 0, p);
1624 /***********************************************************************
1625 * GetGlyphOutlineW (GDI32.@)
1627 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1628 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1629 LPVOID lpBuffer, const MAT2 *lpmat2 )
1631 DC *dc = DC_GetDCPtr(hdc);
1634 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1635 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1637 if(!dc) return GDI_ERROR;
1640 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1641 cbBuffer, lpBuffer, lpmat2);
1645 GDI_ReleaseObj(hdc);
1650 /***********************************************************************
1651 * CreateScalableFontResourceA (GDI32.@)
1653 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1654 LPCSTR lpszResourceFile,
1655 LPCSTR lpszFontFile,
1656 LPCSTR lpszCurrentPath )
1660 /* fHidden=1 - only visible for the calling app, read-only, not
1661 * enumbered with EnumFonts/EnumFontFamilies
1662 * lpszCurrentPath can be NULL
1664 FIXME("(%ld,%s,%s,%s): stub\n",
1665 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1666 debugstr_a(lpszCurrentPath) );
1668 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1669 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1671 SetLastError(ERROR_FILE_EXISTS);
1674 return FALSE; /* create failed */
1677 /***********************************************************************
1678 * CreateScalableFontResourceW (GDI32.@)
1680 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1681 LPCWSTR lpszResourceFile,
1682 LPCWSTR lpszFontFile,
1683 LPCWSTR lpszCurrentPath )
1685 FIXME("(%ld,%p,%p,%p): stub\n",
1686 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1687 return FALSE; /* create failed */
1691 /*************************************************************************
1692 * GetRasterizerCaps (GDI32.@)
1694 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1696 lprs->nSize = sizeof(RASTERIZER_STATUS);
1697 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1698 lprs->nLanguageID = 0;
1703 /*************************************************************************
1704 * GetKerningPairsA (GDI32.@)
1706 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1709 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1710 for (i = 0; i < cPairs; i++)
1711 lpKerningPairs[i].iKernAmount = 0;
1716 /*************************************************************************
1717 * GetKerningPairsW (GDI32.@)
1719 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1720 LPKERNINGPAIR lpKerningPairs )
1722 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1725 /*************************************************************************
1726 * TranslateCharsetInfo [GDI32.@]
1728 * Fills a CHARSETINFO structure for a character set, code page, or
1729 * font. This allows making the correspondance between different labelings
1730 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1731 * of the same encoding.
1733 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1734 * only one codepage should be set in *lpSrc.
1737 * TRUE on success, FALSE on failure.
1740 BOOL WINAPI TranslateCharsetInfo(
1741 LPDWORD lpSrc, /* [in]
1742 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1743 if flags == TCI_SRCCHARSET: a character set value
1744 if flags == TCI_SRCCODEPAGE: a code page value
1746 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1747 DWORD flags /* [in] determines interpretation of lpSrc */
1751 case TCI_SRCFONTSIG:
1752 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1754 case TCI_SRCCODEPAGE:
1755 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1757 case TCI_SRCCHARSET:
1758 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1763 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1764 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1768 /*************************************************************************
1769 * GetFontLanguageInfo (GDI32.@)
1771 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1773 FONTSIGNATURE fontsig;
1774 static const DWORD GCP_DBCS_MASK=0x003F0000,
1775 GCP_DIACRITIC_MASK=0x00000000,
1776 FLI_GLYPHS_MASK=0x00000000,
1777 GCP_GLYPHSHAPE_MASK=0x00000040,
1778 GCP_KASHIDA_MASK=0x00000000,
1779 GCP_LIGATE_MASK=0x00000000,
1780 GCP_USEKERNING_MASK=0x00000000,
1781 GCP_REORDER_MASK=0x00000060;
1785 GetTextCharsetInfo( hdc, &fontsig, 0 );
1786 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1788 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1791 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1792 result|=GCP_DIACRITIC;
1794 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1797 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1798 result|=GCP_GLYPHSHAPE;
1800 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1801 result|=GCP_KASHIDA;
1803 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1806 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1807 result|=GCP_USEKERNING;
1809 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1810 result|=GCP_REORDER;
1816 /*************************************************************************
1817 * GetFontData [GDI32.@] Retrieve data for TrueType font
1821 * success: Number of bytes returned
1822 * failure: GDI_ERROR
1826 * Calls SetLastError()
1829 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1830 LPVOID buffer, DWORD length)
1832 DC *dc = DC_GetDCPtr(hdc);
1833 DWORD ret = GDI_ERROR;
1835 if(!dc) return GDI_ERROR;
1838 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1840 GDI_ReleaseObj(hdc);
1844 /*************************************************************************
1845 * GetGlyphIndicesA [GDI32.@]
1847 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1848 LPWORD pgi, DWORD flags)
1854 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1855 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1857 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1858 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1859 HeapFree(GetProcessHeap(), 0, lpstrW);
1864 /*************************************************************************
1865 * GetGlyphIndicesW [GDI32.@]
1867 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1868 LPWORD pgi, DWORD flags)
1870 DC *dc = DC_GetDCPtr(hdc);
1871 DWORD ret = GDI_ERROR;
1873 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1874 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1876 if(!dc) return GDI_ERROR;
1879 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1881 GDI_ReleaseObj(hdc);
1885 /*************************************************************************
1886 * GetCharacterPlacementA [GDI32.@]
1889 * the web browser control of ie4 calls this with dwFlags=0
1892 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1893 INT nMaxExtent, GCP_RESULTSA *lpResults,
1898 GCP_RESULTSW resultsW;
1902 TRACE("%s, %d, %d, 0x%08lx\n",
1903 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1905 /* both structs are equal in size */
1906 memcpy(&resultsW, lpResults, sizeof(resultsW));
1908 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1909 if(lpResults->lpOutString)
1910 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1912 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1914 if(lpResults->lpOutString) {
1915 if(font_cp != CP_SYMBOL)
1916 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1917 lpResults->lpOutString, uCount, NULL, NULL );
1919 for(i = 0; i < uCount; i++)
1920 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1923 HeapFree(GetProcessHeap(), 0, lpStringW);
1924 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1929 /*************************************************************************
1930 * GetCharacterPlacementW [GDI32.@]
1932 * Retrieve information about a string. This includes the width, reordering,
1933 * Glyphing and so on.
1937 * The width and height of the string if succesful, 0 if failed.
1941 * All flags except GCP_REORDER are not yet implemented.
1942 * Reordering is not 100% complient to the Windows BiDi method.
1943 * Caret positioning is not yet implemented.
1944 * Classes are not yet implemented.
1948 GetCharacterPlacementW(
1949 HDC hdc, /* [in] Device context for which the rendering is to be done */
1950 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1951 INT uCount, /* [in] Number of WORDS in string. */
1952 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1953 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1954 DWORD dwFlags /* [in] Flags specifying how to process the string */
1961 TRACE("%s, %d, %d, 0x%08lx\n",
1962 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1964 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1965 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1966 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1967 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1968 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1970 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1971 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1972 if(lpResults->lpClass) FIXME("classes not implemented\n");
1974 nSet = (UINT)uCount;
1975 if(nSet > lpResults->nGlyphs)
1976 nSet = lpResults->nGlyphs;
1978 /* return number of initialized fields */
1979 lpResults->nGlyphs = nSet;
1983 /* Treat the case where no special handling was requested in a fastpath way */
1984 /* copy will do if the GCP_REORDER flag is not set */
1985 if(lpResults->lpOutString)
1986 for(i=0; i<nSet && lpString[i]!=0; ++i )
1987 lpResults->lpOutString[i]=lpString[i];
1989 if(lpResults->lpOrder)
1991 for(i = 0; i < nSet; i++)
1992 lpResults->lpOrder[i] = i;
1996 if((dwFlags&GCP_REORDER)!=0)
2000 /* Keep a static table that translates the C2 types to something meaningful */
2001 /* 1 - left to right
2002 * -1 - right to left
2005 static const int chardir[]={ 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, 0, 0 };
2007 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2008 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
2010 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2015 /* Fill in the order array with directionality values */
2016 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2018 /* The complete and correct (at least according to MS) BiDi algorythm is not
2019 * yet implemented here. Instead, we just make sure that consecutive runs of
2020 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2021 * that are between runs of opposing directions the base (ok, always LTR) dir.
2022 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2025 for( i=0; i<uCount; i+=run_end )
2027 for( run_end=1; i+run_end<uCount &&
2028 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2029 chardir[pwCharType[i+run_end]]==0); ++run_end )
2032 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2035 if(lpResults->lpOutString)
2038 for( j=0; j<run_end; j++ )
2040 lpResults->lpOutString[i+j]=lpString[i+j];
2044 if(lpResults->lpOrder)
2047 for( j=0; j<run_end; j++ )
2048 lpResults->lpOrder[i+j] = i+j;
2054 /* Since, at this stage, the paragraph context is always LTR,
2055 * remove any neutrals from the end of this run.
2057 if( chardir[pwCharType[i]]!=0 )
2058 while( chardir[pwCharType[i+run_end-1]]==0 )
2061 if(lpResults->lpOutString)
2064 for( j=0; j<run_end; j++ )
2066 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2070 if(lpResults->lpOrder)
2073 for( j=0; j<run_end; j++ )
2074 lpResults->lpOrder[i+j] = i+run_end-j-1;
2079 HeapFree(GetProcessHeap(), 0, pwCharType);
2082 /* FIXME: Will use the placement chars */
2083 if (lpResults->lpDx)
2086 for (i = 0; i < nSet; i++)
2088 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2089 lpResults->lpDx[i]= c;
2093 if(lpResults->lpGlyphs)
2094 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2096 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2097 ret = MAKELONG(size.cx, size.cy);
2102 /*************************************************************************
2103 * GetCharABCWidthsFloatA [GDI32.@]
2105 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2108 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2112 /*************************************************************************
2113 * GetCharABCWidthsFloatW [GDI32.@]
2115 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2116 UINT iLastChar, LPABCFLOAT lpABCF)
2118 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2122 /*************************************************************************
2123 * GetCharWidthFloatA [GDI32.@]
2125 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2126 UINT iLastChar, PFLOAT pxBuffer)
2128 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2132 /*************************************************************************
2133 * GetCharWidthFloatW [GDI32.@]
2135 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2136 UINT iLastChar, PFLOAT pxBuffer)
2138 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2143 /***********************************************************************
2145 * Font Resource API *
2147 ***********************************************************************/
2149 /***********************************************************************
2150 * AddFontResourceA (GDI32.@)
2152 INT WINAPI AddFontResourceA( LPCSTR str )
2154 return AddFontResourceExA( str, 0, NULL);
2157 /***********************************************************************
2158 * AddFontResourceW (GDI32.@)
2160 INT WINAPI AddFontResourceW( LPCWSTR str )
2162 return AddFontResourceExW(str, 0, NULL);
2166 /***********************************************************************
2167 * AddFontResourceExA (GDI32.@)
2169 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2171 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2172 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2175 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2176 ret = AddFontResourceExW(strW, fl, pdv);
2177 HeapFree(GetProcessHeap(), 0, strW);
2181 /***********************************************************************
2182 * AddFontResourceExW (GDI32.@)
2184 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2186 return WineEngAddFontResourceEx(str, fl, pdv);
2189 /***********************************************************************
2190 * RemoveFontResourceA (GDI32.@)
2192 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2194 return RemoveFontResourceExA(str, 0, 0);
2197 /***********************************************************************
2198 * RemoveFontResourceW (GDI32.@)
2200 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2202 return RemoveFontResourceExW(str, 0, 0);
2205 /***********************************************************************
2206 * RemoveFontResourceExA (GDI32.@)
2208 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2210 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2211 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2214 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2215 ret = RemoveFontResourceExW(strW, fl, pdv);
2216 HeapFree(GetProcessHeap(), 0, strW);
2220 /***********************************************************************
2221 * RemoveFontResourceExW (GDI32.@)
2223 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2225 return WineEngRemoveFontResourceEx(str, fl, pdv);