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"
30 #include "wine/unicode.h"
32 #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 FONTENUMPROCEX16 lpEnumFunc;
69 LPNEWTEXTMETRICEX16 lpTextMetric;
70 LPENUMLOGFONTEX16 lpLogFont;
80 LPLOGFONTW lpLogFontParam;
81 FONTENUMPROCEXW lpEnumFunc;
90 * For TranslateCharsetInfo
92 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
93 #define MAXTCIINDEX 32
94 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
96 { ANSI_CHARSET, 1252, FS(0)},
97 { EASTEUROPE_CHARSET, 1250, FS(1)},
98 { RUSSIAN_CHARSET, 1251, FS(2)},
99 { GREEK_CHARSET, 1253, FS(3)},
100 { TURKISH_CHARSET, 1254, FS(4)},
101 { HEBREW_CHARSET, 1255, FS(5)},
102 { ARABIC_CHARSET, 1256, FS(6)},
103 { BALTIC_CHARSET, 1257, FS(7)},
104 { VIETNAMESE_CHARSET, 1258, FS(8)},
105 /* reserved by ANSI */
106 { DEFAULT_CHARSET, 0, FS(0)},
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)},
114 { THAI_CHARSET, 874, FS(16)},
115 { SHIFTJIS_CHARSET, 932, FS(17)},
116 { GB2312_CHARSET, 936, FS(18)},
117 { HANGEUL_CHARSET, 949, FS(19)},
118 { CHINESEBIG5_CHARSET, 950, FS(20)},
119 { JOHAB_CHARSET, 1361, FS(21)},
120 /* reserved for alternate ANSI and OEM */
121 { DEFAULT_CHARSET, 0, FS(0)},
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 /* reserved for system */
130 { DEFAULT_CHARSET, 0, FS(0)},
131 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
134 /* ### start build ### */
135 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
136 /* ### stop build ### */
138 /***********************************************************************
139 * LOGFONT conversion functions.
141 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
143 font16->lfHeight = font32->lfHeight;
144 font16->lfWidth = font32->lfWidth;
145 font16->lfEscapement = font32->lfEscapement;
146 font16->lfOrientation = font32->lfOrientation;
147 font16->lfWeight = font32->lfWeight;
148 font16->lfItalic = font32->lfItalic;
149 font16->lfUnderline = font32->lfUnderline;
150 font16->lfStrikeOut = font32->lfStrikeOut;
151 font16->lfCharSet = font32->lfCharSet;
152 font16->lfOutPrecision = font32->lfOutPrecision;
153 font16->lfClipPrecision = font32->lfClipPrecision;
154 font16->lfQuality = font32->lfQuality;
155 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
156 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
157 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
158 font16->lfFaceName[LF_FACESIZE-1] = 0;
161 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
163 font32->lfHeight = font16->lfHeight;
164 font32->lfWidth = font16->lfWidth;
165 font32->lfEscapement = font16->lfEscapement;
166 font32->lfOrientation = font16->lfOrientation;
167 font32->lfWeight = font16->lfWeight;
168 font32->lfItalic = font16->lfItalic;
169 font32->lfUnderline = font16->lfUnderline;
170 font32->lfStrikeOut = font16->lfStrikeOut;
171 font32->lfCharSet = font16->lfCharSet;
172 font32->lfOutPrecision = font16->lfOutPrecision;
173 font32->lfClipPrecision = font16->lfClipPrecision;
174 font32->lfQuality = font16->lfQuality;
175 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
176 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
177 font32->lfFaceName[LF_FACESIZE-1] = 0;
180 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
182 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
183 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
187 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
189 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
190 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
191 LF_FACESIZE, NULL, NULL);
194 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
196 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
198 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
199 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
200 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
201 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
202 font16->elfStyle, LF_FACESIZE, NULL, NULL );
203 font16->elfStyle[LF_FACESIZE-1] = '\0';
204 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
205 font16->elfScript, LF_FACESIZE, NULL, NULL );
206 font16->elfScript[LF_FACESIZE-1] = '\0';
209 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
211 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
213 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
214 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
215 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
216 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
217 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
218 fontA->elfStyle[LF_FACESIZE-1] = '\0';
219 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
220 fontA->elfScript, LF_FACESIZE, NULL, NULL );
221 fontA->elfScript[LF_FACESIZE-1] = '\0';
224 /***********************************************************************
225 * TEXTMETRIC conversion functions.
227 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
229 ptmA->tmHeight = ptmW->tmHeight;
230 ptmA->tmAscent = ptmW->tmAscent;
231 ptmA->tmDescent = ptmW->tmDescent;
232 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
233 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
234 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
235 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
236 ptmA->tmWeight = ptmW->tmWeight;
237 ptmA->tmOverhang = ptmW->tmOverhang;
238 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
239 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
240 ptmA->tmFirstChar = ptmW->tmFirstChar;
241 ptmA->tmLastChar = ptmW->tmLastChar;
242 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
243 ptmA->tmBreakChar = ptmW->tmBreakChar;
244 ptmA->tmItalic = ptmW->tmItalic;
245 ptmA->tmUnderlined = ptmW->tmUnderlined;
246 ptmA->tmStruckOut = ptmW->tmStruckOut;
247 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
248 ptmA->tmCharSet = ptmW->tmCharSet;
252 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
254 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
255 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
256 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
257 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
258 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
259 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
260 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
261 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
262 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
263 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
264 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
265 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
266 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
267 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
268 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
269 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
270 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
271 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
272 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
273 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
274 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
275 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
276 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
277 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
278 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
281 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
283 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
284 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
285 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
286 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
287 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
288 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
291 /***********************************************************************
292 * CreateFontIndirectA (GDI32.@)
294 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
299 FONT_LogFontAToW( plfA, &lfW );
300 return CreateFontIndirectW( &lfW );
302 return CreateFontIndirectW( NULL );
306 /***********************************************************************
307 * CreateFontIndirectW (GDI32.@)
309 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
316 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
318 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
320 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
321 plf->lfHeight, plf->lfWidth,
322 plf->lfEscapement, plf->lfOrientation,
323 plf->lfPitchAndFamily,
324 debugstr_w(plf->lfFaceName),
325 plf->lfWeight > 400 ? "Bold" : "",
326 plf->lfItalic ? "Italic" : "", hFont);
328 if (plf->lfEscapement != plf->lfOrientation) {
329 /* this should really depend on whether GM_ADVANCED is set */
330 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
331 WARN("orientation angle %f set to "
332 "escapement angle %f for new font %04x\n",
333 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
335 GDI_ReleaseObj( hFont );
338 else WARN("(NULL) => NULL\n");
343 /*************************************************************************
344 * CreateFontA (GDI32.@)
346 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
347 INT orient, INT weight, DWORD italic,
348 DWORD underline, DWORD strikeout, DWORD charset,
349 DWORD outpres, DWORD clippres, DWORD quality,
350 DWORD pitch, LPCSTR name )
354 logfont.lfHeight = height;
355 logfont.lfWidth = width;
356 logfont.lfEscapement = esc;
357 logfont.lfOrientation = orient;
358 logfont.lfWeight = weight;
359 logfont.lfItalic = italic;
360 logfont.lfUnderline = underline;
361 logfont.lfStrikeOut = strikeout;
362 logfont.lfCharSet = charset;
363 logfont.lfOutPrecision = outpres;
364 logfont.lfClipPrecision = clippres;
365 logfont.lfQuality = quality;
366 logfont.lfPitchAndFamily = pitch;
369 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
371 logfont.lfFaceName[0] = '\0';
373 return CreateFontIndirectA( &logfont );
376 /*************************************************************************
377 * CreateFontW (GDI32.@)
379 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
380 INT orient, INT weight, DWORD italic,
381 DWORD underline, DWORD strikeout, DWORD charset,
382 DWORD outpres, DWORD clippres, DWORD quality,
383 DWORD pitch, LPCWSTR name )
387 logfont.lfHeight = height;
388 logfont.lfWidth = width;
389 logfont.lfEscapement = esc;
390 logfont.lfOrientation = orient;
391 logfont.lfWeight = weight;
392 logfont.lfItalic = italic;
393 logfont.lfUnderline = underline;
394 logfont.lfStrikeOut = strikeout;
395 logfont.lfCharSet = charset;
396 logfont.lfOutPrecision = outpres;
397 logfont.lfClipPrecision = clippres;
398 logfont.lfQuality = quality;
399 logfont.lfPitchAndFamily = pitch;
402 lstrcpynW(logfont.lfFaceName, name,
403 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
405 logfont.lfFaceName[0] = '\0';
407 return CreateFontIndirectW( &logfont );
411 /***********************************************************************
414 * If the driver supports vector fonts we create a gdi font first and
415 * then call the driver to give it a chance to supply its own device
416 * font. If the driver wants to do this it returns TRUE and we can
417 * delete the gdi font, if the driver wants to use the gdi font it
418 * should return FALSE, to signal an error return GDI_ERROR. For
419 * drivers that don't support vector fonts they must supply their own
422 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
425 DC *dc = DC_GetDCPtr( hdc );
429 if (dc->hFont != handle || dc->gdiFont == NULL)
431 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
432 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
435 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
437 if (ret && dc->gdiFont) dc->gdiFont = 0;
439 if (ret == HGDI_ERROR)
440 ret = 0; /* SelectObject returns 0 on error */
446 GDI_ReleaseObj( hdc );
451 /***********************************************************************
454 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
459 FONT_LogFontWTo16( &font->logfont, &lf16 );
461 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
462 memcpy( buffer, &lf16, count );
466 /***********************************************************************
469 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
474 FONT_LogFontWToA( &font->logfont, &lfA );
476 if (count > sizeof(lfA)) count = sizeof(lfA);
478 memcpy( buffer, &lfA, count );
482 /***********************************************************************
485 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
488 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
490 memcpy( buffer, &font->logfont, count );
495 /***********************************************************************
498 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
500 WineEngDestroyFontInstance( handle );
501 return GDI_FreeObject( handle, obj );
505 /***********************************************************************
506 * FONT_EnumInstance16
508 * Called by the device driver layer to pass font info
509 * down to the application.
511 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
512 DWORD fType, LPARAM lp )
514 fontEnum16 *pfe = (fontEnum16*)lp;
518 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
519 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
521 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
522 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
523 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
525 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
526 (UINT16)fType, (LPARAM)pfe->lpData );
527 /* get the lock again and make sure the DC is still valid */
528 dc = DC_GetDCPtr( pfe->hdc );
529 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
531 if (dc) GDI_ReleaseObj( pfe->hdc );
532 pfe->hdc = 0; /* make sure we don't try to release it later on */
539 /***********************************************************************
542 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
543 DWORD fType, LPARAM lp )
545 fontEnum32 *pfe = (fontEnum32*)lp;
549 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
550 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
551 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
553 /* convert font metrics */
554 ENUMLOGFONTEXA logfont;
555 NEWTEXTMETRICEXA tmA;
557 pfe->dwFlags |= ENUM_CALLED;
558 if (!(pfe->dwFlags & ENUM_UNICODE))
560 FONT_EnumLogFontExWToA( plf, &logfont);
561 FONT_NewTextMetricExWToA( ptm, &tmA );
562 plf = (LPENUMLOGFONTEXW)&logfont;
563 ptm = (LPNEWTEXTMETRICEXW)&tmA;
565 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
567 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
569 /* get the lock again and make sure the DC is still valid */
570 dc = DC_GetDCPtr( pfe->hdc );
571 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
573 if (dc) GDI_ReleaseObj( pfe->hdc );
574 pfe->hdc = 0; /* make sure we don't try to release it later on */
581 /***********************************************************************
582 * EnumFontFamiliesEx (GDI.613)
584 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
585 FONTENUMPROCEX16 efproc, LPARAM lParam,
590 DC* dc = DC_GetDCPtr( hDC );
595 fe16.physDev = dc->physDev;
597 if (dc->funcs->pEnumDeviceFonts)
599 NEWTEXTMETRICEX16 tm16;
600 ENUMLOGFONTEX16 lf16;
602 FONT_LogFont16ToW(plf, &lfW);
604 fe16.lpLogFontParam = plf;
605 fe16.lpEnumFunc = efproc;
606 fe16.lpData = lParam;
607 fe16.lpTextMetric = &tm16;
608 fe16.lpLogFont = &lf16;
609 fe16.segTextMetric = MapLS( &tm16 );
610 fe16.segLogFont = MapLS( &lf16 );
612 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
613 FONT_EnumInstance16, (LPARAM)&fe16 );
614 UnMapLS( fe16.segTextMetric );
615 UnMapLS( fe16.segLogFont );
617 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
621 /***********************************************************************
622 * FONT_EnumFontFamiliesEx
624 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
625 FONTENUMPROCEXW efproc,
626 LPARAM lParam, DWORD dwUnicode)
629 DC *dc = DC_GetDCPtr( hDC );
635 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
637 fe32.lpLogFontParam = plf;
638 fe32.lpEnumFunc = efproc;
639 fe32.lpData = lParam;
640 fe32.dwFlags = dwUnicode;
643 fe32.physDev = dc->physDev;
645 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
647 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
654 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
655 fe32.dwFlags &= ~ENUM_CALLED;
656 if (ret && dc->funcs->pEnumDeviceFonts) {
657 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
658 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
662 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
666 /***********************************************************************
667 * EnumFontFamiliesExW (GDI32.@)
669 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
670 FONTENUMPROCEXW efproc,
671 LPARAM lParam, DWORD dwFlags )
673 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
676 /***********************************************************************
677 * EnumFontFamiliesExA (GDI32.@)
679 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
680 FONTENUMPROCEXA efproc,
681 LPARAM lParam, DWORD dwFlags)
684 FONT_LogFontAToW( plf, &lfW );
686 return FONT_EnumFontFamiliesEx( hDC, &lfW,
687 (FONTENUMPROCEXW)efproc, lParam, 0);
690 /***********************************************************************
691 * EnumFontFamilies (GDI.330)
693 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
694 FONTENUMPROC16 efproc, LPARAM lpData )
698 lf.lfCharSet = DEFAULT_CHARSET;
699 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
700 else lf.lfFaceName[0] = '\0';
702 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
705 /***********************************************************************
706 * EnumFontFamiliesA (GDI32.@)
708 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
709 FONTENUMPROCA efproc, LPARAM lpData )
713 lf.lfCharSet = DEFAULT_CHARSET;
714 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
715 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
717 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
720 /***********************************************************************
721 * EnumFontFamiliesW (GDI32.@)
723 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
724 FONTENUMPROCW efproc, LPARAM lpData )
728 lf.lfCharSet = DEFAULT_CHARSET;
729 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
730 else lf.lfFaceName[0] = 0;
732 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
735 /***********************************************************************
738 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
741 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
744 /***********************************************************************
745 * EnumFontsA (GDI32.@)
747 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
750 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
753 /***********************************************************************
754 * EnumFontsW (GDI32.@)
756 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
759 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
763 /***********************************************************************
764 * GetTextCharacterExtra (GDI32.@)
766 INT WINAPI GetTextCharacterExtra( HDC hdc )
769 DC *dc = DC_GetDCPtr( hdc );
771 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
773 GDI_ReleaseObj( hdc );
778 /***********************************************************************
779 * SetTextCharacterExtra (GDI32.@)
781 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
784 DC * dc = DC_GetDCPtr( hdc );
786 if (dc->funcs->pSetTextCharacterExtra)
787 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
790 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
791 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
792 dc->charExtra = abs(extra);
794 GDI_ReleaseObj( hdc );
799 /***********************************************************************
800 * SetTextJustification (GDI32.@)
802 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
805 DC * dc = DC_GetDCPtr( hdc );
806 if (!dc) return FALSE;
807 if (dc->funcs->pSetTextJustification)
808 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
811 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
812 if (!extra) breaks = 0;
813 dc->breakTotalExtra = extra;
814 dc->breakCount = breaks;
817 dc->breakExtra = extra / breaks;
818 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
826 GDI_ReleaseObj( hdc );
831 /***********************************************************************
832 * GetTextFaceA (GDI32.@)
834 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
836 INT res = GetTextFaceW(hdc, 0, NULL);
837 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
838 GetTextFaceW( hdc, res, nameW );
841 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
844 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
845 HeapFree( GetProcessHeap(), 0, nameW );
849 /***********************************************************************
850 * GetTextFaceW (GDI32.@)
852 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
857 DC * dc = DC_GetDCPtr( hdc );
861 ret = WineEngGetTextFace(dc->gdiFont, count, name);
862 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
866 lstrcpynW( name, font->logfont.lfFaceName, count );
869 else ret = strlenW(font->logfont.lfFaceName) + 1;
870 GDI_ReleaseObj( dc->hFont );
872 GDI_ReleaseObj( hdc );
877 /***********************************************************************
878 * GetTextExtentPoint32A (GDI32.@)
880 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
885 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
888 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
889 HeapFree( GetProcessHeap(), 0, p );
892 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
893 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
898 /***********************************************************************
899 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
901 * Computes width and height of the specified string.
907 BOOL WINAPI GetTextExtentPoint32W(
908 HDC hdc, /* [in] Handle of device context */
909 LPCWSTR str, /* [in] Address of text string */
910 INT count, /* [in] Number of characters in string */
911 LPSIZE size) /* [out] Address of structure for string size */
914 DC * dc = DC_GetDCPtr( hdc );
915 if (!dc) return FALSE;
918 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
919 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
920 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
922 else if(dc->funcs->pGetTextExtentPoint)
923 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
925 GDI_ReleaseObj( hdc );
927 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
928 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
932 /***********************************************************************
933 * GetTextExtentPointI [GDI32.@]
935 * Computes width and height of the array of glyph indices.
941 BOOL WINAPI GetTextExtentPointI(
942 HDC hdc, /* [in] Handle of device context */
943 const WORD *indices, /* [in] Address of glyph index array */
944 INT count, /* [in] Number of glyphs in array */
945 LPSIZE size) /* [out] Address of structure for string size */
948 DC * dc = DC_GetDCPtr( hdc );
949 if (!dc) return FALSE;
952 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
953 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
954 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
956 else if(dc->funcs->pGetTextExtentPoint) {
957 FIXME("calling GetTextExtentPoint\n");
958 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
961 GDI_ReleaseObj( hdc );
963 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
964 hdc, indices, count, size, size->cx, size->cy );
969 /***********************************************************************
970 * GetTextExtentPointA (GDI32.@)
972 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
975 TRACE("not bug compatible.\n");
976 return GetTextExtentPoint32A( hdc, str, count, size );
979 /***********************************************************************
980 * GetTextExtentPointW (GDI32.@)
982 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
985 TRACE("not bug compatible.\n");
986 return GetTextExtentPoint32W( hdc, str, count, size );
990 /***********************************************************************
991 * GetTextExtentExPointA (GDI32.@)
993 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
994 INT maxExt, LPINT lpnFit,
995 LPINT alpDx, LPSIZE size )
999 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1000 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1001 HeapFree( GetProcessHeap(), 0, p );
1006 /***********************************************************************
1007 * GetTextExtentExPointW (GDI32.@)
1009 * Return the size of the string as it would be if it was output properly by
1012 * This should include
1013 * - Intercharacter spacing
1014 * - justification spacing (not yet done)
1015 * - kerning? see below
1017 * Kerning. Since kerning would be carried out by the rendering code it should
1018 * be done by the driver. However they don't support it yet. Also I am not
1019 * yet persuaded that (certainly under Win95) any kerning is actually done.
1021 * str: According to MSDN this should be null-terminated. That is not true; a
1022 * null will not terminate it early.
1023 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1024 * than count. I have seen it be either the size of the full string or
1025 * 1 less than the size of the full string. I have not seen it bear any
1026 * resemblance to the portion that would fit.
1027 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1028 * trailing intercharacter spacing and any trailing justification.
1031 * Currently we do this by measuring each character etc. We should do it by
1032 * passing the request to the driver, perhaps by extending the
1033 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1034 * thinking about kerning issues and rounding issues in the justification.
1037 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1038 INT maxExt, LPINT lpnFit,
1039 LPINT alpDx, LPSIZE size )
1041 int index, nFit, extent;
1045 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1047 size->cx = size->cy = nFit = extent = 0;
1048 for(index = 0; index < count; index++)
1050 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1051 /* GetTextExtentPoint includes intercharacter spacing. */
1052 /* FIXME - justification needs doing yet. Remember that the base
1053 * data will not be in logical coordinates.
1056 if( !lpnFit || extent <= maxExt )
1057 /* It is allowed to be equal. */
1060 if( alpDx ) alpDx[index] = extent;
1062 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1066 if(lpnFit) *lpnFit = nFit;
1069 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1075 /***********************************************************************
1076 * GetTextMetricsA (GDI32.@)
1078 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1082 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1083 FONT_TextMetricWToA( &tm32, metrics );
1087 /***********************************************************************
1088 * GetTextMetricsW (GDI32.@)
1090 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1093 DC * dc = DC_GetDCPtr( hdc );
1094 if (!dc) return FALSE;
1097 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1098 else if (dc->funcs->pGetTextMetrics)
1099 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1103 /* device layer returns values in device units
1104 * therefore we have to convert them to logical */
1106 #define WDPTOLP(x) ((x<0)? \
1107 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1108 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1109 #define HDPTOLP(y) ((y<0)? \
1110 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1111 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1113 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1114 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1115 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1116 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1117 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1118 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1119 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1120 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1124 TRACE("text metrics:\n"
1125 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1126 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1127 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1128 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1129 " PitchAndFamily = %02x\n"
1130 " --------------------\n"
1131 " InternalLeading = %li\n"
1135 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1136 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1137 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1138 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1139 metrics->tmPitchAndFamily,
1140 metrics->tmInternalLeading,
1143 metrics->tmHeight );
1145 GDI_ReleaseObj( hdc );
1150 /***********************************************************************
1151 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1154 * lpOTM should be LPOUTLINETEXTMETRIC
1157 * Success: Non-zero or size of required buffer
1160 UINT16 WINAPI GetOutlineTextMetrics16(
1161 HDC16 hdc, /* [in] Handle of device context */
1162 UINT16 cbData, /* [in] Size of metric data array */
1163 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1165 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1170 /***********************************************************************
1171 * GetOutlineTextMetricsA (GDI32.@)
1172 * Gets metrics for TrueType fonts.
1176 * Success: Non-zero or size of required buffer
1179 UINT WINAPI GetOutlineTextMetricsA(
1180 HDC hdc, /* [in] Handle of device context */
1181 UINT cbData, /* [in] Size of metric data array */
1182 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1184 char buf[512], *ptr;
1186 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1189 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1190 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1192 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1193 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1196 needed = sizeof(OUTLINETEXTMETRICA);
1197 if(lpOTMW->otmpFamilyName)
1198 needed += WideCharToMultiByte(CP_ACP, 0,
1199 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1200 NULL, 0, NULL, NULL);
1201 if(lpOTMW->otmpFaceName)
1202 needed += WideCharToMultiByte(CP_ACP, 0,
1203 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1204 NULL, 0, NULL, NULL);
1205 if(lpOTMW->otmpStyleName)
1206 needed += WideCharToMultiByte(CP_ACP, 0,
1207 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1208 NULL, 0, NULL, NULL);
1209 if(lpOTMW->otmpFullName)
1210 needed += WideCharToMultiByte(CP_ACP, 0,
1211 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1212 NULL, 0, NULL, NULL);
1219 if(needed > cbData) {
1225 lpOTM->otmSize = needed;
1226 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1227 lpOTM->otmFiller = 0;
1228 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1229 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1230 lpOTM->otmfsType = lpOTMW->otmfsType;
1231 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1232 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1233 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1234 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1235 lpOTM->otmAscent = lpOTMW->otmAscent;
1236 lpOTM->otmDescent = lpOTMW->otmDescent;
1237 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1238 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1239 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1240 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1241 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1242 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1243 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1244 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1245 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1246 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1247 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1248 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1249 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1250 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1251 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1252 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1255 ptr = (char*)(lpOTM + 1);
1256 left = needed - sizeof(*lpOTM);
1258 if(lpOTMW->otmpFamilyName) {
1259 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1260 len = WideCharToMultiByte(CP_ACP, 0,
1261 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1262 ptr, left, NULL, NULL);
1266 lpOTM->otmpFamilyName = 0;
1268 if(lpOTMW->otmpFaceName) {
1269 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1270 len = WideCharToMultiByte(CP_ACP, 0,
1271 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1272 ptr, left, NULL, NULL);
1276 lpOTM->otmpFaceName = 0;
1278 if(lpOTMW->otmpStyleName) {
1279 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1280 len = WideCharToMultiByte(CP_ACP, 0,
1281 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1282 ptr, left, NULL, NULL);
1286 lpOTM->otmpStyleName = 0;
1288 if(lpOTMW->otmpFullName) {
1289 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1290 len = WideCharToMultiByte(CP_ACP, 0,
1291 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1292 ptr, left, NULL, NULL);
1295 lpOTM->otmpFullName = 0;
1302 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1303 HeapFree(GetProcessHeap(), 0, lpOTMW);
1309 /***********************************************************************
1310 * GetOutlineTextMetricsW [GDI32.@]
1312 UINT WINAPI GetOutlineTextMetricsW(
1313 HDC hdc, /* [in] Handle of device context */
1314 UINT cbData, /* [in] Size of metric data array */
1315 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1317 DC *dc = DC_GetDCPtr( hdc );
1320 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1324 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1325 if(ret && ret <= cbData) {
1326 #define WDPTOLP(x) ((x<0)? \
1327 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1328 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1329 #define HDPTOLP(y) ((y<0)? \
1330 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1331 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1333 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1334 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1335 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1336 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1337 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1338 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1339 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1340 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1341 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1342 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1343 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1344 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1345 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1346 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1347 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1348 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1349 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1350 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1351 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1352 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1353 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1354 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1355 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1356 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1357 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1358 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1359 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1360 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1361 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1362 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1363 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1364 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1370 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1371 but really this should just be a return 0. */
1373 ret = sizeof(*lpOTM);
1378 memset(lpOTM, 0, ret);
1379 lpOTM->otmSize = sizeof(*lpOTM);
1380 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1382 Further fill of the structure not implemented,
1383 Needs real values for the structure members
1388 GDI_ReleaseObj(hdc);
1393 /***********************************************************************
1394 * GetCharWidthW (GDI32.@)
1395 * GetCharWidth32W (GDI32.@)
1397 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1402 DC * dc = DC_GetDCPtr( hdc );
1403 if (!dc) return FALSE;
1406 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1407 else if (dc->funcs->pGetCharWidth)
1408 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1412 /* convert device units to logical */
1414 extra = dc->vportExtX >> 1;
1415 for( i = firstChar; i <= lastChar; i++, buffer++ )
1416 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1419 GDI_ReleaseObj( hdc );
1424 /***********************************************************************
1425 * GetCharWidthA (GDI32.@)
1426 * GetCharWidth32A (GDI32.@)
1428 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1431 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1436 if(count <= 0) return FALSE;
1438 str = HeapAlloc(GetProcessHeap(), 0, count);
1439 for(i = 0; i < count; i++)
1440 str[i] = (BYTE)(firstChar + i);
1442 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1444 for(i = 0; i < wlen; i++)
1446 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1454 HeapFree(GetProcessHeap(), 0, str);
1455 HeapFree(GetProcessHeap(), 0, wstr);
1461 /* FIXME: all following APIs ******************************************/
1464 /***********************************************************************
1465 * SetMapperFlags (GDI32.@)
1467 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1469 DC *dc = DC_GetDCPtr( hDC );
1472 if(dc->funcs->pSetMapperFlags)
1473 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1475 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1476 GDI_ReleaseObj( hDC );
1480 /***********************************************************************
1481 * GetAspectRatioFilterEx (GDI.486)
1483 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1485 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1489 /***********************************************************************
1490 * GetAspectRatioFilterEx (GDI32.@)
1492 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1494 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1499 /***********************************************************************
1500 * GetCharABCWidthsA (GDI32.@)
1502 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1505 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1510 if(count <= 0) return FALSE;
1512 str = HeapAlloc(GetProcessHeap(), 0, count);
1513 for(i = 0; i < count; i++)
1514 str[i] = (BYTE)(firstChar + i);
1516 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1518 for(i = 0; i < wlen; i++)
1520 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1528 HeapFree(GetProcessHeap(), 0, str);
1529 HeapFree(GetProcessHeap(), 0, wstr);
1535 /******************************************************************************
1536 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1539 * hdc [I] Handle of device context
1540 * firstChar [I] First character in range to query
1541 * lastChar [I] Last character in range to query
1542 * abc [O] Address of character-width structure
1545 * Only works with TrueType fonts
1551 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1554 DC *dc = DC_GetDCPtr(hdc);
1560 for (i=firstChar;i<=lastChar;i++) {
1561 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1562 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1563 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1564 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1568 GDI_ReleaseObj(hdc);
1573 /***********************************************************************
1574 * GetGlyphOutline (GDI.309)
1576 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1577 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1578 LPVOID lpBuffer, const MAT2 *lpmat2 )
1580 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1581 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1582 return (DWORD)-1; /* failure */
1586 /***********************************************************************
1587 * GetGlyphOutlineA (GDI32.@)
1589 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1590 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1591 LPVOID lpBuffer, const MAT2 *lpmat2 )
1597 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1598 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1602 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1605 HeapFree(GetProcessHeap(), 0, p);
1609 /***********************************************************************
1610 * GetGlyphOutlineW (GDI32.@)
1612 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1613 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1614 LPVOID lpBuffer, const MAT2 *lpmat2 )
1616 DC *dc = DC_GetDCPtr(hdc);
1619 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1620 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1622 if(!dc) return GDI_ERROR;
1625 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1626 cbBuffer, lpBuffer, lpmat2);
1630 GDI_ReleaseObj(hdc);
1635 /***********************************************************************
1636 * CreateScalableFontResourceA (GDI32.@)
1638 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1639 LPCSTR lpszResourceFile,
1640 LPCSTR lpszFontFile,
1641 LPCSTR lpszCurrentPath )
1645 /* fHidden=1 - only visible for the calling app, read-only, not
1646 * enumbered with EnumFonts/EnumFontFamilies
1647 * lpszCurrentPath can be NULL
1649 FIXME("(%ld,%s,%s,%s): stub\n",
1650 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1651 debugstr_a(lpszCurrentPath) );
1653 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1654 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1656 SetLastError(ERROR_FILE_EXISTS);
1659 return FALSE; /* create failed */
1662 /***********************************************************************
1663 * CreateScalableFontResourceW (GDI32.@)
1665 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1666 LPCWSTR lpszResourceFile,
1667 LPCWSTR lpszFontFile,
1668 LPCWSTR lpszCurrentPath )
1670 FIXME("(%ld,%p,%p,%p): stub\n",
1671 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1672 return FALSE; /* create failed */
1676 /*************************************************************************
1677 * GetRasterizerCaps (GDI32.@)
1679 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1681 lprs->nSize = sizeof(RASTERIZER_STATUS);
1682 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1683 lprs->nLanguageID = 0;
1688 /*************************************************************************
1689 * GetKerningPairsA (GDI32.@)
1691 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1694 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1695 for (i = 0; i < cPairs; i++)
1696 lpKerningPairs[i].iKernAmount = 0;
1701 /*************************************************************************
1702 * GetKerningPairsW (GDI32.@)
1704 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1705 LPKERNINGPAIR lpKerningPairs )
1707 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1710 /*************************************************************************
1711 * TranslateCharsetInfo [GDI32.@]
1713 * Fills a CHARSETINFO structure for a character set, code page, or
1714 * font. This allows making the correspondance between different labelings
1715 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1716 * of the same encoding.
1718 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1719 * only one codepage should be set in *lpSrc.
1722 * TRUE on success, FALSE on failure.
1725 BOOL WINAPI TranslateCharsetInfo(
1726 LPDWORD lpSrc, /* [in]
1727 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1728 if flags == TCI_SRCCHARSET: a character set value
1729 if flags == TCI_SRCCODEPAGE: a code page value
1731 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1732 DWORD flags /* [in] determines interpretation of lpSrc */
1736 case TCI_SRCFONTSIG:
1737 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1739 case TCI_SRCCODEPAGE:
1740 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1742 case TCI_SRCCHARSET:
1743 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1748 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1749 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1753 /*************************************************************************
1754 * GetFontLanguageInfo (GDI32.@)
1756 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1758 FONTSIGNATURE fontsig;
1759 static const DWORD GCP_DBCS_MASK=0x003F0000,
1760 GCP_DIACRITIC_MASK=0x00000000,
1761 FLI_GLYPHS_MASK=0x00000000,
1762 GCP_GLYPHSHAPE_MASK=0x00000040,
1763 GCP_KASHIDA_MASK=0x00000000,
1764 GCP_LIGATE_MASK=0x00000000,
1765 GCP_USEKERNING_MASK=0x00000000,
1766 GCP_REORDER_MASK=0x00000060;
1770 GetTextCharsetInfo( hdc, &fontsig, 0 );
1771 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1773 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1776 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1777 result|=GCP_DIACRITIC;
1779 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1782 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1783 result|=GCP_GLYPHSHAPE;
1785 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1786 result|=GCP_KASHIDA;
1788 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1791 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1792 result|=GCP_USEKERNING;
1794 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1795 result|=GCP_REORDER;
1801 /*************************************************************************
1802 * GetFontData [GDI32.@] Retrieve data for TrueType font
1806 * success: Number of bytes returned
1807 * failure: GDI_ERROR
1811 * Calls SetLastError()
1814 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1815 LPVOID buffer, DWORD length)
1817 DC *dc = DC_GetDCPtr(hdc);
1818 DWORD ret = GDI_ERROR;
1820 if(!dc) return GDI_ERROR;
1823 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1825 GDI_ReleaseObj(hdc);
1829 /*************************************************************************
1830 * GetGlyphIndicesA [GDI32.@]
1832 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1833 LPWORD pgi, DWORD flags)
1839 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1840 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1842 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1843 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1844 HeapFree(GetProcessHeap(), 0, lpstrW);
1849 /*************************************************************************
1850 * GetGlyphIndicesW [GDI32.@]
1852 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1853 LPWORD pgi, DWORD flags)
1855 DC *dc = DC_GetDCPtr(hdc);
1856 DWORD ret = GDI_ERROR;
1858 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1859 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1861 if(!dc) return GDI_ERROR;
1864 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1866 GDI_ReleaseObj(hdc);
1870 /*************************************************************************
1871 * GetCharacterPlacementA [GDI32.@]
1874 * the web browser control of ie4 calls this with dwFlags=0
1877 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1878 INT nMaxExtent, GCP_RESULTSA *lpResults,
1883 GCP_RESULTSW resultsW;
1887 TRACE("%s, %d, %d, 0x%08lx\n",
1888 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1890 /* both structs are equal in size */
1891 memcpy(&resultsW, lpResults, sizeof(resultsW));
1893 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1894 if(lpResults->lpOutString)
1895 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1897 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1899 if(lpResults->lpOutString) {
1900 if(font_cp != CP_SYMBOL)
1901 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1902 lpResults->lpOutString, uCount, NULL, NULL );
1904 for(i = 0; i < uCount; i++)
1905 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1908 HeapFree(GetProcessHeap(), 0, lpStringW);
1909 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1914 /*************************************************************************
1915 * GetCharacterPlacementW [GDI32.@]
1917 * Retrieve information about a string. This includes the width, reordering,
1918 * Glyphing and so on.
1922 * The width and height of the string if succesful, 0 if failed.
1926 * All flags except GCP_REORDER are not yet implemented.
1927 * Reordering is not 100% complient to the Windows BiDi method.
1928 * Caret positioning is not yet implemented.
1929 * Classes are not yet implemented.
1933 GetCharacterPlacementW(
1934 HDC hdc, /* [in] Device context for which the rendering is to be done */
1935 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1936 INT uCount, /* [in] Number of WORDS in string. */
1937 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1938 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1939 DWORD dwFlags /* [in] Flags specifying how to process the string */
1946 TRACE("%s, %d, %d, 0x%08lx\n",
1947 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1949 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1950 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1951 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1952 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1953 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1955 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1956 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1957 if(lpResults->lpClass) FIXME("classes not implemented\n");
1959 nSet = (UINT)uCount;
1960 if(nSet > lpResults->nGlyphs)
1961 nSet = lpResults->nGlyphs;
1963 /* return number of initialized fields */
1964 lpResults->nGlyphs = nSet;
1968 /* Treat the case where no special handling was requested in a fastpath way */
1969 /* copy will do if the GCP_REORDER flag is not set */
1970 if(lpResults->lpOutString)
1971 for(i=0; i<nSet && lpString[i]!=0; ++i )
1972 lpResults->lpOutString[i]=lpString[i];
1974 if(lpResults->lpOrder)
1976 for(i = 0; i < nSet; i++)
1977 lpResults->lpOrder[i] = i;
1981 if((dwFlags&GCP_REORDER)!=0)
1985 /* Keep a static table that translates the C2 types to something meaningful */
1986 /* 1 - left to right
1987 * -1 - right to left
1990 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
1992 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
1993 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
1995 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2000 /* Fill in the order array with directionality values */
2001 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2003 /* The complete and correct (at least according to MS) BiDi algorythm is not
2004 * yet implemented here. Instead, we just make sure that consecutive runs of
2005 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2006 * that are between runs of opposing directions the base (ok, always LTR) dir.
2007 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2010 for( i=0; i<uCount; i+=run_end )
2012 for( run_end=1; i+run_end<uCount &&
2013 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2014 chardir[pwCharType[i+run_end]]==0); ++run_end )
2017 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2020 if(lpResults->lpOutString)
2023 for( j=0; j<run_end; j++ )
2025 lpResults->lpOutString[i+j]=lpString[i+j];
2029 if(lpResults->lpOrder)
2032 for( j=0; j<run_end; j++ )
2033 lpResults->lpOrder[i+j] = i+j;
2039 /* Since, at this stage, the paragraph context is always LTR,
2040 * remove any neutrals from the end of this run.
2042 if( chardir[pwCharType[i]]!=0 )
2043 while( chardir[pwCharType[i+run_end-1]]==0 )
2046 if(lpResults->lpOutString)
2049 for( j=0; j<run_end; j++ )
2051 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2055 if(lpResults->lpOrder)
2058 for( j=0; j<run_end; j++ )
2059 lpResults->lpOrder[i+j] = i+run_end-j-1;
2064 HeapFree(GetProcessHeap(), 0, pwCharType);
2067 /* FIXME: Will use the placement chars */
2068 if (lpResults->lpDx)
2071 for (i = 0; i < nSet; i++)
2073 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2074 lpResults->lpDx[i]= c;
2078 if(lpResults->lpGlyphs)
2079 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2081 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2082 ret = MAKELONG(size.cx, size.cy);
2087 /*************************************************************************
2088 * GetCharABCWidthsFloatA [GDI32.@]
2090 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2093 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2097 /*************************************************************************
2098 * GetCharABCWidthsFloatW [GDI32.@]
2100 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2101 UINT iLastChar, LPABCFLOAT lpABCF)
2103 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2107 /*************************************************************************
2108 * GetCharWidthFloatA [GDI32.@]
2110 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2111 UINT iLastChar, PFLOAT pxBuffer)
2113 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2117 /*************************************************************************
2118 * GetCharWidthFloatW [GDI32.@]
2120 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2121 UINT iLastChar, PFLOAT pxBuffer)
2123 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2128 /***********************************************************************
2130 * Font Resource API *
2132 ***********************************************************************/
2134 /***********************************************************************
2135 * AddFontResourceA (GDI32.@)
2137 INT WINAPI AddFontResourceA( LPCSTR str )
2139 return AddFontResourceExA( str, 0, NULL);
2142 /***********************************************************************
2143 * AddFontResourceW (GDI32.@)
2145 INT WINAPI AddFontResourceW( LPCWSTR str )
2147 return AddFontResourceExW(str, 0, NULL);
2151 /***********************************************************************
2152 * AddFontResourceExA (GDI32.@)
2154 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2156 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2157 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2160 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2161 ret = AddFontResourceExW(strW, fl, pdv);
2162 HeapFree(GetProcessHeap(), 0, strW);
2166 /***********************************************************************
2167 * AddFontResourceExW (GDI32.@)
2169 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2171 return WineEngAddFontResourceEx(str, fl, pdv);
2174 /***********************************************************************
2175 * RemoveFontResourceA (GDI32.@)
2177 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2179 return RemoveFontResourceExA(str, 0, 0);
2182 /***********************************************************************
2183 * RemoveFontResourceW (GDI32.@)
2185 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2187 return RemoveFontResourceExW(str, 0, 0);
2190 /***********************************************************************
2191 * RemoveFontResourceExA (GDI32.@)
2193 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2195 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2196 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2199 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2200 ret = RemoveFontResourceExW(strW, fl, pdv);
2201 HeapFree(GetProcessHeap(), 0, strW);
2205 /***********************************************************************
2206 * RemoveFontResourceExW (GDI32.@)
2208 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2210 return WineEngRemoveFontResourceEx(str, fl, pdv);