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 FONTENUMPROC16 lpEnumFunc;
69 LPNEWTEXTMETRICEX16 lpTextMetric;
70 LPENUMLOGFONTEX16 lpLogFont;
80 LPLOGFONTW lpLogFontParam;
81 FONTENUMPROCW 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(FONTENUMPROC16,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, NEWTEXTMETRICEXA *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 %d %x %d %d) %s %s %s => %04x\n",
321 plf->lfHeight, plf->lfWidth,
322 plf->lfEscapement, plf->lfOrientation,
323 plf->lfPitchAndFamily,
324 plf->lfOutPrecision, plf->lfClipPrecision,
325 plf->lfQuality, plf->lfCharSet,
326 debugstr_w(plf->lfFaceName),
327 plf->lfWeight > 400 ? "Bold" : "",
328 plf->lfItalic ? "Italic" : "", hFont);
330 if (plf->lfEscapement != plf->lfOrientation) {
331 /* this should really depend on whether GM_ADVANCED is set */
332 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
333 WARN("orientation angle %f set to "
334 "escapement angle %f for new font %04x\n",
335 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
337 GDI_ReleaseObj( hFont );
340 else WARN("(NULL) => NULL\n");
345 /*************************************************************************
346 * CreateFontA (GDI32.@)
348 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
349 INT orient, INT weight, DWORD italic,
350 DWORD underline, DWORD strikeout, DWORD charset,
351 DWORD outpres, DWORD clippres, DWORD quality,
352 DWORD pitch, LPCSTR name )
356 logfont.lfHeight = height;
357 logfont.lfWidth = width;
358 logfont.lfEscapement = esc;
359 logfont.lfOrientation = orient;
360 logfont.lfWeight = weight;
361 logfont.lfItalic = italic;
362 logfont.lfUnderline = underline;
363 logfont.lfStrikeOut = strikeout;
364 logfont.lfCharSet = charset;
365 logfont.lfOutPrecision = outpres;
366 logfont.lfClipPrecision = clippres;
367 logfont.lfQuality = quality;
368 logfont.lfPitchAndFamily = pitch;
371 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
373 logfont.lfFaceName[0] = '\0';
375 return CreateFontIndirectA( &logfont );
378 /*************************************************************************
379 * CreateFontW (GDI32.@)
381 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
382 INT orient, INT weight, DWORD italic,
383 DWORD underline, DWORD strikeout, DWORD charset,
384 DWORD outpres, DWORD clippres, DWORD quality,
385 DWORD pitch, LPCWSTR name )
389 logfont.lfHeight = height;
390 logfont.lfWidth = width;
391 logfont.lfEscapement = esc;
392 logfont.lfOrientation = orient;
393 logfont.lfWeight = weight;
394 logfont.lfItalic = italic;
395 logfont.lfUnderline = underline;
396 logfont.lfStrikeOut = strikeout;
397 logfont.lfCharSet = charset;
398 logfont.lfOutPrecision = outpres;
399 logfont.lfClipPrecision = clippres;
400 logfont.lfQuality = quality;
401 logfont.lfPitchAndFamily = pitch;
404 lstrcpynW(logfont.lfFaceName, name,
405 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
407 logfont.lfFaceName[0] = '\0';
409 return CreateFontIndirectW( &logfont );
413 /***********************************************************************
416 * If the driver supports vector fonts we create a gdi font first and
417 * then call the driver to give it a chance to supply its own device
418 * font. If the driver wants to do this it returns TRUE and we can
419 * delete the gdi font, if the driver wants to use the gdi font it
420 * should return FALSE, to signal an error return GDI_ERROR. For
421 * drivers that don't support vector fonts they must supply their own
424 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
427 DC *dc = DC_GetDCPtr( hdc );
431 if (dc->hFont != handle || dc->gdiFont == NULL)
433 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
434 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
437 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
439 if (ret && dc->gdiFont) dc->gdiFont = 0;
441 if (ret == HGDI_ERROR)
442 ret = 0; /* SelectObject returns 0 on error */
448 GDI_ReleaseObj( hdc );
453 /***********************************************************************
456 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
461 FONT_LogFontWTo16( &font->logfont, &lf16 );
463 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
464 memcpy( buffer, &lf16, count );
468 /***********************************************************************
471 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
476 FONT_LogFontWToA( &font->logfont, &lfA );
478 if (count > sizeof(lfA)) count = sizeof(lfA);
480 memcpy( buffer, &lfA, count );
484 /***********************************************************************
487 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
490 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
492 memcpy( buffer, &font->logfont, count );
497 /***********************************************************************
500 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
502 WineEngDestroyFontInstance( handle );
503 return GDI_FreeObject( handle, obj );
507 /***********************************************************************
508 * FONT_EnumInstance16
510 * Called by the device driver layer to pass font info
511 * down to the application.
513 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
514 DWORD fType, LPARAM lp )
516 fontEnum16 *pfe = (fontEnum16*)lp;
520 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
521 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
523 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
524 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
525 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
527 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
528 (UINT16)fType, (LPARAM)pfe->lpData );
529 /* get the lock again and make sure the DC is still valid */
530 dc = DC_GetDCPtr( pfe->hdc );
531 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
533 if (dc) GDI_ReleaseObj( pfe->hdc );
534 pfe->hdc = 0; /* make sure we don't try to release it later on */
541 /***********************************************************************
544 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
545 DWORD fType, LPARAM lp )
547 fontEnum32 *pfe = (fontEnum32*)lp;
551 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
552 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
553 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
555 /* convert font metrics */
556 ENUMLOGFONTEXA logfont;
557 NEWTEXTMETRICEXA tmA;
559 pfe->dwFlags |= ENUM_CALLED;
560 if (!(pfe->dwFlags & ENUM_UNICODE))
562 FONT_EnumLogFontExWToA( plf, &logfont);
563 FONT_NewTextMetricExWToA( ptm, &tmA );
564 plf = (LPENUMLOGFONTEXW)&logfont;
565 ptm = (NEWTEXTMETRICEXW *)&tmA;
567 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
569 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
571 /* get the lock again and make sure the DC is still valid */
572 dc = DC_GetDCPtr( pfe->hdc );
573 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
575 if (dc) GDI_ReleaseObj( pfe->hdc );
576 pfe->hdc = 0; /* make sure we don't try to release it later on */
583 /***********************************************************************
584 * EnumFontFamiliesEx (GDI.613)
586 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
587 FONTENUMPROC16 efproc, LPARAM lParam,
592 DC* dc = DC_GetDCPtr( hDC );
597 fe16.physDev = dc->physDev;
599 if (dc->funcs->pEnumDeviceFonts)
601 NEWTEXTMETRICEX16 tm16;
602 ENUMLOGFONTEX16 lf16;
604 FONT_LogFont16ToW(plf, &lfW);
606 fe16.lpLogFontParam = plf;
607 fe16.lpEnumFunc = efproc;
608 fe16.lpData = lParam;
609 fe16.lpTextMetric = &tm16;
610 fe16.lpLogFont = &lf16;
611 fe16.segTextMetric = MapLS( &tm16 );
612 fe16.segLogFont = MapLS( &lf16 );
614 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
615 FONT_EnumInstance16, (LPARAM)&fe16 );
616 UnMapLS( fe16.segTextMetric );
617 UnMapLS( fe16.segLogFont );
619 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
623 /***********************************************************************
624 * FONT_EnumFontFamiliesEx
626 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
627 FONTENUMPROCW efproc,
628 LPARAM lParam, DWORD dwUnicode)
631 DC *dc = DC_GetDCPtr( hDC );
637 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
639 fe32.lpLogFontParam = plf;
640 fe32.lpEnumFunc = efproc;
641 fe32.lpData = lParam;
642 fe32.dwFlags = dwUnicode;
645 fe32.physDev = dc->physDev;
647 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
649 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
656 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
657 fe32.dwFlags &= ~ENUM_CALLED;
658 if (ret && dc->funcs->pEnumDeviceFonts) {
659 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
660 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
664 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
668 /***********************************************************************
669 * EnumFontFamiliesExW (GDI32.@)
671 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
672 FONTENUMPROCW efproc,
673 LPARAM lParam, DWORD dwFlags )
675 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
678 /***********************************************************************
679 * EnumFontFamiliesExA (GDI32.@)
681 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
682 FONTENUMPROCA efproc,
683 LPARAM lParam, DWORD dwFlags)
686 FONT_LogFontAToW( plf, &lfW );
688 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
691 /***********************************************************************
692 * EnumFontFamilies (GDI.330)
694 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
695 FONTENUMPROC16 efproc, LPARAM lpData )
699 lf.lfCharSet = DEFAULT_CHARSET;
700 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
701 else lf.lfFaceName[0] = '\0';
703 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
706 /***********************************************************************
707 * EnumFontFamiliesA (GDI32.@)
709 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
710 FONTENUMPROCA efproc, LPARAM lpData )
714 lf.lfCharSet = DEFAULT_CHARSET;
715 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
716 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
718 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
721 /***********************************************************************
722 * EnumFontFamiliesW (GDI32.@)
724 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
725 FONTENUMPROCW efproc, LPARAM lpData )
729 lf.lfCharSet = DEFAULT_CHARSET;
730 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
731 else lf.lfFaceName[0] = 0;
733 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
736 /***********************************************************************
739 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
742 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
745 /***********************************************************************
746 * EnumFontsA (GDI32.@)
748 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
751 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
754 /***********************************************************************
755 * EnumFontsW (GDI32.@)
757 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
760 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
764 /***********************************************************************
765 * GetTextCharacterExtra (GDI32.@)
767 INT WINAPI GetTextCharacterExtra( HDC hdc )
770 DC *dc = DC_GetDCPtr( hdc );
771 if (!dc) return 0x80000000;
773 GDI_ReleaseObj( hdc );
778 /***********************************************************************
779 * SetTextCharacterExtra (GDI32.@)
781 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
784 DC * dc = DC_GetDCPtr( hdc );
785 if (!dc) return 0x80000000;
786 if (dc->funcs->pSetTextCharacterExtra)
787 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
790 prev = dc->charExtra;
791 dc->charExtra = extra;
793 GDI_ReleaseObj( hdc );
798 /***********************************************************************
799 * SetTextJustification (GDI32.@)
801 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
804 DC * dc = DC_GetDCPtr( hdc );
805 if (!dc) return FALSE;
806 if (dc->funcs->pSetTextJustification)
807 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
810 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
811 if (!extra) breaks = 0;
812 dc->breakTotalExtra = extra;
813 dc->breakCount = breaks;
816 dc->breakExtra = extra / breaks;
817 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
825 GDI_ReleaseObj( hdc );
830 /***********************************************************************
831 * GetTextFaceA (GDI32.@)
833 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
835 INT res = GetTextFaceW(hdc, 0, NULL);
836 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
837 GetTextFaceW( hdc, res, nameW );
840 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
843 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
844 HeapFree( GetProcessHeap(), 0, nameW );
848 /***********************************************************************
849 * GetTextFaceW (GDI32.@)
851 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
856 DC * dc = DC_GetDCPtr( hdc );
860 ret = WineEngGetTextFace(dc->gdiFont, count, name);
861 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
865 lstrcpynW( name, font->logfont.lfFaceName, count );
868 else ret = strlenW(font->logfont.lfFaceName) + 1;
869 GDI_ReleaseObj( dc->hFont );
871 GDI_ReleaseObj( hdc );
876 /***********************************************************************
877 * GetTextExtentPoint32A (GDI32.@)
879 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
884 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
887 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
888 HeapFree( GetProcessHeap(), 0, p );
891 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
892 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
897 /***********************************************************************
898 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
900 * Computes width and height of the specified string.
906 BOOL WINAPI GetTextExtentPoint32W(
907 HDC hdc, /* [in] Handle of device context */
908 LPCWSTR str, /* [in] Address of text string */
909 INT count, /* [in] Number of characters in string */
910 LPSIZE size) /* [out] Address of structure for string size */
913 DC * dc = DC_GetDCPtr( hdc );
914 if (!dc) return FALSE;
917 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
918 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
919 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
921 else if(dc->funcs->pGetTextExtentPoint)
922 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
924 GDI_ReleaseObj( hdc );
926 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
927 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
931 /***********************************************************************
932 * GetTextExtentPointI [GDI32.@]
934 * Computes width and height of the array of glyph indices.
940 BOOL WINAPI GetTextExtentPointI(
941 HDC hdc, /* [in] Handle of device context */
942 const WORD *indices, /* [in] Address of glyph index array */
943 INT count, /* [in] Number of glyphs in array */
944 LPSIZE size) /* [out] Address of structure for string size */
947 DC * dc = DC_GetDCPtr( hdc );
948 if (!dc) return FALSE;
951 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
952 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
953 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
955 else if(dc->funcs->pGetTextExtentPoint) {
956 FIXME("calling GetTextExtentPoint\n");
957 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
960 GDI_ReleaseObj( hdc );
962 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
963 hdc, indices, count, size, size->cx, size->cy );
968 /***********************************************************************
969 * GetTextExtentPointA (GDI32.@)
971 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
974 TRACE("not bug compatible.\n");
975 return GetTextExtentPoint32A( hdc, str, count, size );
978 /***********************************************************************
979 * GetTextExtentPointW (GDI32.@)
981 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
984 TRACE("not bug compatible.\n");
985 return GetTextExtentPoint32W( hdc, str, count, size );
989 /***********************************************************************
990 * GetTextExtentExPointA (GDI32.@)
992 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
993 INT maxExt, LPINT lpnFit,
994 LPINT alpDx, LPSIZE size )
998 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
999 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1000 HeapFree( GetProcessHeap(), 0, p );
1005 /***********************************************************************
1006 * GetTextExtentExPointW (GDI32.@)
1008 * Return the size of the string as it would be if it was output properly by
1011 * This should include
1012 * - Intercharacter spacing
1013 * - justification spacing (not yet done)
1014 * - kerning? see below
1016 * Kerning. Since kerning would be carried out by the rendering code it should
1017 * be done by the driver. However they don't support it yet. Also I am not
1018 * yet persuaded that (certainly under Win95) any kerning is actually done.
1020 * str: According to MSDN this should be null-terminated. That is not true; a
1021 * null will not terminate it early.
1022 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1023 * than count. I have seen it be either the size of the full string or
1024 * 1 less than the size of the full string. I have not seen it bear any
1025 * resemblance to the portion that would fit.
1026 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1027 * trailing intercharacter spacing and any trailing justification.
1030 * Currently we do this by measuring each character etc. We should do it by
1031 * passing the request to the driver, perhaps by extending the
1032 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1033 * thinking about kerning issues and rounding issues in the justification.
1036 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1037 INT maxExt, LPINT lpnFit,
1038 LPINT alpDx, LPSIZE size )
1040 int index, nFit, extent;
1044 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1046 size->cx = size->cy = nFit = extent = 0;
1047 for(index = 0; index < count; index++)
1049 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1050 /* GetTextExtentPoint includes intercharacter spacing. */
1051 /* FIXME - justification needs doing yet. Remember that the base
1052 * data will not be in logical coordinates.
1055 if( !lpnFit || extent <= maxExt )
1056 /* It is allowed to be equal. */
1059 if( alpDx ) alpDx[index] = extent;
1061 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1065 if(lpnFit) *lpnFit = nFit;
1068 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1074 /***********************************************************************
1075 * GetTextMetricsA (GDI32.@)
1077 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1081 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1082 FONT_TextMetricWToA( &tm32, metrics );
1086 /***********************************************************************
1087 * GetTextMetricsW (GDI32.@)
1089 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1092 DC * dc = DC_GetDCPtr( hdc );
1093 if (!dc) return FALSE;
1096 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1097 else if (dc->funcs->pGetTextMetrics)
1098 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1102 /* device layer returns values in device units
1103 * therefore we have to convert them to logical */
1105 #define WDPTOLP(x) ((x<0)? \
1106 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1107 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1108 #define HDPTOLP(y) ((y<0)? \
1109 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1110 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1112 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1113 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1114 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1115 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1116 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1117 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1118 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1119 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1123 TRACE("text metrics:\n"
1124 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1125 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1126 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1127 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1128 " PitchAndFamily = %02x\n"
1129 " --------------------\n"
1130 " InternalLeading = %li\n"
1134 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1135 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1136 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1137 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1138 metrics->tmPitchAndFamily,
1139 metrics->tmInternalLeading,
1142 metrics->tmHeight );
1144 GDI_ReleaseObj( hdc );
1149 /***********************************************************************
1150 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1153 * lpOTM should be LPOUTLINETEXTMETRIC
1156 * Success: Non-zero or size of required buffer
1159 UINT16 WINAPI GetOutlineTextMetrics16(
1160 HDC16 hdc, /* [in] Handle of device context */
1161 UINT16 cbData, /* [in] Size of metric data array */
1162 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1164 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1169 /***********************************************************************
1170 * GetOutlineTextMetricsA (GDI32.@)
1171 * Gets metrics for TrueType fonts.
1175 * Success: Non-zero or size of required buffer
1178 UINT WINAPI GetOutlineTextMetricsA(
1179 HDC hdc, /* [in] Handle of device context */
1180 UINT cbData, /* [in] Size of metric data array */
1181 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1183 char buf[512], *ptr;
1185 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1188 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1189 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1191 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1192 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1195 needed = sizeof(OUTLINETEXTMETRICA);
1196 if(lpOTMW->otmpFamilyName)
1197 needed += WideCharToMultiByte(CP_ACP, 0,
1198 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1199 NULL, 0, NULL, NULL);
1200 if(lpOTMW->otmpFaceName)
1201 needed += WideCharToMultiByte(CP_ACP, 0,
1202 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1203 NULL, 0, NULL, NULL);
1204 if(lpOTMW->otmpStyleName)
1205 needed += WideCharToMultiByte(CP_ACP, 0,
1206 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1207 NULL, 0, NULL, NULL);
1208 if(lpOTMW->otmpFullName)
1209 needed += WideCharToMultiByte(CP_ACP, 0,
1210 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1211 NULL, 0, NULL, NULL);
1218 if(needed > cbData) {
1224 lpOTM->otmSize = needed;
1225 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1226 lpOTM->otmFiller = 0;
1227 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1228 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1229 lpOTM->otmfsType = lpOTMW->otmfsType;
1230 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1231 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1232 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1233 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1234 lpOTM->otmAscent = lpOTMW->otmAscent;
1235 lpOTM->otmDescent = lpOTMW->otmDescent;
1236 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1237 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1238 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1239 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1240 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1241 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1242 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1243 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1244 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1245 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1246 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1247 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1248 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1249 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1250 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1251 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1254 ptr = (char*)(lpOTM + 1);
1255 left = needed - sizeof(*lpOTM);
1257 if(lpOTMW->otmpFamilyName) {
1258 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1259 len = WideCharToMultiByte(CP_ACP, 0,
1260 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1261 ptr, left, NULL, NULL);
1265 lpOTM->otmpFamilyName = 0;
1267 if(lpOTMW->otmpFaceName) {
1268 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1269 len = WideCharToMultiByte(CP_ACP, 0,
1270 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1271 ptr, left, NULL, NULL);
1275 lpOTM->otmpFaceName = 0;
1277 if(lpOTMW->otmpStyleName) {
1278 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1279 len = WideCharToMultiByte(CP_ACP, 0,
1280 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1281 ptr, left, NULL, NULL);
1285 lpOTM->otmpStyleName = 0;
1287 if(lpOTMW->otmpFullName) {
1288 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1289 len = WideCharToMultiByte(CP_ACP, 0,
1290 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1291 ptr, left, NULL, NULL);
1294 lpOTM->otmpFullName = 0;
1301 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1302 HeapFree(GetProcessHeap(), 0, lpOTMW);
1308 /***********************************************************************
1309 * GetOutlineTextMetricsW [GDI32.@]
1311 UINT WINAPI GetOutlineTextMetricsW(
1312 HDC hdc, /* [in] Handle of device context */
1313 UINT cbData, /* [in] Size of metric data array */
1314 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1316 DC *dc = DC_GetDCPtr( hdc );
1319 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1323 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1324 if(ret && ret <= cbData) {
1325 #define WDPTOLP(x) ((x<0)? \
1326 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1327 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1328 #define HDPTOLP(y) ((y<0)? \
1329 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1330 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1332 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1333 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1334 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1335 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1336 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1337 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1338 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1339 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1340 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1341 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1342 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1343 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1344 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1345 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1346 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1347 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1348 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1349 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1350 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1351 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1352 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1353 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1354 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1355 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1356 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1357 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1358 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1359 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1360 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1361 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1362 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1363 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1369 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1370 but really this should just be a return 0. */
1372 ret = sizeof(*lpOTM);
1377 memset(lpOTM, 0, ret);
1378 lpOTM->otmSize = sizeof(*lpOTM);
1379 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1381 Further fill of the structure not implemented,
1382 Needs real values for the structure members
1387 GDI_ReleaseObj(hdc);
1392 /***********************************************************************
1393 * GetCharWidthW (GDI32.@)
1394 * GetCharWidth32W (GDI32.@)
1396 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1401 DC * dc = DC_GetDCPtr( hdc );
1402 if (!dc) return FALSE;
1405 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1406 else if (dc->funcs->pGetCharWidth)
1407 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1411 /* convert device units to logical */
1413 extra = dc->vportExtX >> 1;
1414 for( i = firstChar; i <= lastChar; i++, buffer++ )
1415 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1418 GDI_ReleaseObj( hdc );
1423 /***********************************************************************
1424 * GetCharWidthA (GDI32.@)
1425 * GetCharWidth32A (GDI32.@)
1427 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1430 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1435 if(count <= 0) return FALSE;
1437 str = HeapAlloc(GetProcessHeap(), 0, count);
1438 for(i = 0; i < count; i++)
1439 str[i] = (BYTE)(firstChar + i);
1441 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1443 for(i = 0; i < wlen; i++)
1445 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1453 HeapFree(GetProcessHeap(), 0, str);
1454 HeapFree(GetProcessHeap(), 0, wstr);
1460 /* FIXME: all following APIs ******************************************/
1463 /***********************************************************************
1464 * SetMapperFlags (GDI32.@)
1466 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1468 DC *dc = DC_GetDCPtr( hDC );
1471 if(dc->funcs->pSetMapperFlags)
1472 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1474 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1475 GDI_ReleaseObj( hDC );
1479 /***********************************************************************
1480 * GetAspectRatioFilterEx (GDI.486)
1482 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1484 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1488 /***********************************************************************
1489 * GetAspectRatioFilterEx (GDI32.@)
1491 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1493 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1498 /***********************************************************************
1499 * GetCharABCWidthsA (GDI32.@)
1501 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1504 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1509 if(count <= 0) return FALSE;
1511 str = HeapAlloc(GetProcessHeap(), 0, count);
1512 for(i = 0; i < count; i++)
1513 str[i] = (BYTE)(firstChar + i);
1515 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1517 for(i = 0; i < wlen; i++)
1519 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1527 HeapFree(GetProcessHeap(), 0, str);
1528 HeapFree(GetProcessHeap(), 0, wstr);
1534 /******************************************************************************
1535 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1538 * hdc [I] Handle of device context
1539 * firstChar [I] First character in range to query
1540 * lastChar [I] Last character in range to query
1541 * abc [O] Address of character-width structure
1544 * Only works with TrueType fonts
1550 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1553 DC *dc = DC_GetDCPtr(hdc);
1559 for (i=firstChar;i<=lastChar;i++) {
1560 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1561 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1562 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1563 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1567 GDI_ReleaseObj(hdc);
1572 /***********************************************************************
1573 * GetGlyphOutline (GDI.309)
1575 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1576 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1577 LPVOID lpBuffer, const MAT2 *lpmat2 )
1579 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1580 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1581 return (DWORD)-1; /* failure */
1585 /***********************************************************************
1586 * GetGlyphOutlineA (GDI32.@)
1588 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1589 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1590 LPVOID lpBuffer, const MAT2 *lpmat2 )
1596 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1597 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1601 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1604 HeapFree(GetProcessHeap(), 0, p);
1608 /***********************************************************************
1609 * GetGlyphOutlineW (GDI32.@)
1611 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1612 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1613 LPVOID lpBuffer, const MAT2 *lpmat2 )
1615 DC *dc = DC_GetDCPtr(hdc);
1618 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1619 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1621 if(!dc) return GDI_ERROR;
1624 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1625 cbBuffer, lpBuffer, lpmat2);
1629 GDI_ReleaseObj(hdc);
1634 /***********************************************************************
1635 * CreateScalableFontResourceA (GDI32.@)
1637 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1638 LPCSTR lpszResourceFile,
1639 LPCSTR lpszFontFile,
1640 LPCSTR lpszCurrentPath )
1644 /* fHidden=1 - only visible for the calling app, read-only, not
1645 * enumbered with EnumFonts/EnumFontFamilies
1646 * lpszCurrentPath can be NULL
1648 FIXME("(%ld,%s,%s,%s): stub\n",
1649 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1650 debugstr_a(lpszCurrentPath) );
1652 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1653 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1655 SetLastError(ERROR_FILE_EXISTS);
1658 return FALSE; /* create failed */
1661 /***********************************************************************
1662 * CreateScalableFontResourceW (GDI32.@)
1664 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1665 LPCWSTR lpszResourceFile,
1666 LPCWSTR lpszFontFile,
1667 LPCWSTR lpszCurrentPath )
1669 FIXME("(%ld,%p,%p,%p): stub\n",
1670 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1671 return FALSE; /* create failed */
1675 /*************************************************************************
1676 * GetRasterizerCaps (GDI32.@)
1678 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1680 lprs->nSize = sizeof(RASTERIZER_STATUS);
1681 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1682 lprs->nLanguageID = 0;
1687 /*************************************************************************
1688 * GetKerningPairsA (GDI32.@)
1690 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1693 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1694 for (i = 0; i < cPairs; i++)
1695 lpKerningPairs[i].iKernAmount = 0;
1700 /*************************************************************************
1701 * GetKerningPairsW (GDI32.@)
1703 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1704 LPKERNINGPAIR lpKerningPairs )
1706 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1709 /*************************************************************************
1710 * TranslateCharsetInfo [GDI32.@]
1712 * Fills a CHARSETINFO structure for a character set, code page, or
1713 * font. This allows making the correspondance between different labelings
1714 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1715 * of the same encoding.
1717 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1718 * only one codepage should be set in *lpSrc.
1721 * TRUE on success, FALSE on failure.
1724 BOOL WINAPI TranslateCharsetInfo(
1725 LPDWORD lpSrc, /* [in]
1726 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1727 if flags == TCI_SRCCHARSET: a character set value
1728 if flags == TCI_SRCCODEPAGE: a code page value
1730 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1731 DWORD flags /* [in] determines interpretation of lpSrc */
1735 case TCI_SRCFONTSIG:
1736 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1738 case TCI_SRCCODEPAGE:
1739 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1741 case TCI_SRCCHARSET:
1742 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1747 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1748 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1752 /*************************************************************************
1753 * GetFontLanguageInfo (GDI32.@)
1755 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1757 FONTSIGNATURE fontsig;
1758 static const DWORD GCP_DBCS_MASK=0x003F0000,
1759 GCP_DIACRITIC_MASK=0x00000000,
1760 FLI_GLYPHS_MASK=0x00000000,
1761 GCP_GLYPHSHAPE_MASK=0x00000040,
1762 GCP_KASHIDA_MASK=0x00000000,
1763 GCP_LIGATE_MASK=0x00000000,
1764 GCP_USEKERNING_MASK=0x00000000,
1765 GCP_REORDER_MASK=0x00000060;
1769 GetTextCharsetInfo( hdc, &fontsig, 0 );
1770 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1772 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1775 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1776 result|=GCP_DIACRITIC;
1778 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1781 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1782 result|=GCP_GLYPHSHAPE;
1784 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1785 result|=GCP_KASHIDA;
1787 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1790 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1791 result|=GCP_USEKERNING;
1793 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1794 result|=GCP_REORDER;
1800 /*************************************************************************
1801 * GetFontData [GDI32.@] Retrieve data for TrueType font
1805 * success: Number of bytes returned
1806 * failure: GDI_ERROR
1810 * Calls SetLastError()
1813 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1814 LPVOID buffer, DWORD length)
1816 DC *dc = DC_GetDCPtr(hdc);
1817 DWORD ret = GDI_ERROR;
1819 if(!dc) return GDI_ERROR;
1822 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1824 GDI_ReleaseObj(hdc);
1828 /*************************************************************************
1829 * GetGlyphIndicesA [GDI32.@]
1831 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1832 LPWORD pgi, DWORD flags)
1838 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1839 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1841 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1842 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1843 HeapFree(GetProcessHeap(), 0, lpstrW);
1848 /*************************************************************************
1849 * GetGlyphIndicesW [GDI32.@]
1851 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1852 LPWORD pgi, DWORD flags)
1854 DC *dc = DC_GetDCPtr(hdc);
1855 DWORD ret = GDI_ERROR;
1857 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1858 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1860 if(!dc) return GDI_ERROR;
1863 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1865 GDI_ReleaseObj(hdc);
1869 /*************************************************************************
1870 * GetCharacterPlacementA [GDI32.@]
1873 * the web browser control of ie4 calls this with dwFlags=0
1876 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1877 INT nMaxExtent, GCP_RESULTSA *lpResults,
1882 GCP_RESULTSW resultsW;
1886 TRACE("%s, %d, %d, 0x%08lx\n",
1887 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1889 /* both structs are equal in size */
1890 memcpy(&resultsW, lpResults, sizeof(resultsW));
1892 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1893 if(lpResults->lpOutString)
1894 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1896 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1898 if(lpResults->lpOutString) {
1899 if(font_cp != CP_SYMBOL)
1900 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1901 lpResults->lpOutString, uCount, NULL, NULL );
1903 for(i = 0; i < uCount; i++)
1904 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1907 HeapFree(GetProcessHeap(), 0, lpStringW);
1908 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1913 /*************************************************************************
1914 * GetCharacterPlacementW [GDI32.@]
1916 * Retrieve information about a string. This includes the width, reordering,
1917 * Glyphing and so on.
1921 * The width and height of the string if succesful, 0 if failed.
1925 * All flags except GCP_REORDER are not yet implemented.
1926 * Reordering is not 100% complient to the Windows BiDi method.
1927 * Caret positioning is not yet implemented.
1928 * Classes are not yet implemented.
1932 GetCharacterPlacementW(
1933 HDC hdc, /* [in] Device context for which the rendering is to be done */
1934 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1935 INT uCount, /* [in] Number of WORDS in string. */
1936 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1937 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1938 DWORD dwFlags /* [in] Flags specifying how to process the string */
1945 TRACE("%s, %d, %d, 0x%08lx\n",
1946 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1948 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1949 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1950 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1951 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1952 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1954 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1955 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1956 if(lpResults->lpClass) FIXME("classes not implemented\n");
1958 nSet = (UINT)uCount;
1959 if(nSet > lpResults->nGlyphs)
1960 nSet = lpResults->nGlyphs;
1962 /* return number of initialized fields */
1963 lpResults->nGlyphs = nSet;
1967 /* Treat the case where no special handling was requested in a fastpath way */
1968 /* copy will do if the GCP_REORDER flag is not set */
1969 if(lpResults->lpOutString)
1970 for(i=0; i<nSet && lpString[i]!=0; ++i )
1971 lpResults->lpOutString[i]=lpString[i];
1973 if(lpResults->lpOrder)
1975 for(i = 0; i < nSet; i++)
1976 lpResults->lpOrder[i] = i;
1980 if((dwFlags&GCP_REORDER)!=0)
1984 /* Keep a static table that translates the C2 types to something meaningful */
1985 /* 1 - left to right
1986 * -1 - right to left
1989 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
1991 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
1992 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
1994 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1999 /* Fill in the order array with directionality values */
2000 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2002 /* The complete and correct (at least according to MS) BiDi algorythm is not
2003 * yet implemented here. Instead, we just make sure that consecutive runs of
2004 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2005 * that are between runs of opposing directions the base (ok, always LTR) dir.
2006 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2009 for( i=0; i<uCount; i+=run_end )
2011 for( run_end=1; i+run_end<uCount &&
2012 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2013 chardir[pwCharType[i+run_end]]==0); ++run_end )
2016 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2019 if(lpResults->lpOutString)
2022 for( j=0; j<run_end; j++ )
2024 lpResults->lpOutString[i+j]=lpString[i+j];
2028 if(lpResults->lpOrder)
2031 for( j=0; j<run_end; j++ )
2032 lpResults->lpOrder[i+j] = i+j;
2038 /* Since, at this stage, the paragraph context is always LTR,
2039 * remove any neutrals from the end of this run.
2041 if( chardir[pwCharType[i]]!=0 )
2042 while( chardir[pwCharType[i+run_end-1]]==0 )
2045 if(lpResults->lpOutString)
2048 for( j=0; j<run_end; j++ )
2050 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2054 if(lpResults->lpOrder)
2057 for( j=0; j<run_end; j++ )
2058 lpResults->lpOrder[i+j] = i+run_end-j-1;
2063 HeapFree(GetProcessHeap(), 0, pwCharType);
2066 /* FIXME: Will use the placement chars */
2067 if (lpResults->lpDx)
2070 for (i = 0; i < nSet; i++)
2072 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2073 lpResults->lpDx[i]= c;
2077 if(lpResults->lpGlyphs)
2078 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2080 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2081 ret = MAKELONG(size.cx, size.cy);
2086 /*************************************************************************
2087 * GetCharABCWidthsFloatA [GDI32.@]
2089 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2092 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2096 /*************************************************************************
2097 * GetCharABCWidthsFloatW [GDI32.@]
2099 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2100 UINT iLastChar, LPABCFLOAT lpABCF)
2102 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2106 /*************************************************************************
2107 * GetCharWidthFloatA [GDI32.@]
2109 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2110 UINT iLastChar, PFLOAT pxBuffer)
2112 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2116 /*************************************************************************
2117 * GetCharWidthFloatW [GDI32.@]
2119 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2120 UINT iLastChar, PFLOAT pxBuffer)
2122 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2127 /***********************************************************************
2129 * Font Resource API *
2131 ***********************************************************************/
2133 /***********************************************************************
2134 * AddFontResourceA (GDI32.@)
2136 INT WINAPI AddFontResourceA( LPCSTR str )
2138 return AddFontResourceExA( str, 0, NULL);
2141 /***********************************************************************
2142 * AddFontResourceW (GDI32.@)
2144 INT WINAPI AddFontResourceW( LPCWSTR str )
2146 return AddFontResourceExW(str, 0, NULL);
2150 /***********************************************************************
2151 * AddFontResourceExA (GDI32.@)
2153 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2155 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2156 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2159 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2160 ret = AddFontResourceExW(strW, fl, pdv);
2161 HeapFree(GetProcessHeap(), 0, strW);
2165 /***********************************************************************
2166 * AddFontResourceExW (GDI32.@)
2168 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2170 return WineEngAddFontResourceEx(str, fl, pdv);
2173 /***********************************************************************
2174 * RemoveFontResourceA (GDI32.@)
2176 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2178 return RemoveFontResourceExA(str, 0, 0);
2181 /***********************************************************************
2182 * RemoveFontResourceW (GDI32.@)
2184 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2186 return RemoveFontResourceExW(str, 0, 0);
2189 /***********************************************************************
2190 * RemoveFontResourceExA (GDI32.@)
2192 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2194 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2195 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2198 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2199 ret = RemoveFontResourceExW(strW, fl, pdv);
2200 HeapFree(GetProcessHeap(), 0, strW);
2204 /***********************************************************************
2205 * RemoveFontResourceExW (GDI32.@)
2207 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2209 return WineEngRemoveFontResourceEx(str, fl, pdv);