4 * Copyright 1993 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(font);
36 WINE_DECLARE_DEBUG_CHANNEL(gdi);
38 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
39 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
40 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
44 static const struct gdi_obj_funcs font_funcs =
46 FONT_SelectObject, /* pSelectObject */
47 FONT_GetObject16, /* pGetObject16 */
48 FONT_GetObjectA, /* pGetObjectA */
49 FONT_GetObjectW, /* pGetObjectW */
50 NULL, /* pUnrealizeObject */
51 FONT_DeleteObject /* pDeleteObject */
54 #define ENUM_UNICODE 0x00000001
55 #define ENUM_CALLED 0x00000002
65 LPLOGFONT16 lpLogFontParam;
66 FONTENUMPROC16 lpEnumFunc;
69 LPNEWTEXTMETRICEX16 lpTextMetric;
70 LPENUMLOGFONTEX16 lpLogFont;
81 LPLOGFONTW lpLogFontParam;
82 FONTENUMPROCW lpEnumFunc;
91 * For TranslateCharsetInfo
93 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
94 #define MAXTCIINDEX 32
95 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
97 { ANSI_CHARSET, 1252, FS(0)},
98 { EASTEUROPE_CHARSET, 1250, FS(1)},
99 { RUSSIAN_CHARSET, 1251, FS(2)},
100 { GREEK_CHARSET, 1253, FS(3)},
101 { TURKISH_CHARSET, 1254, FS(4)},
102 { HEBREW_CHARSET, 1255, FS(5)},
103 { ARABIC_CHARSET, 1256, FS(6)},
104 { BALTIC_CHARSET, 1257, FS(7)},
105 { VIETNAMESE_CHARSET, 1258, FS(8)},
106 /* reserved by ANSI */
107 { DEFAULT_CHARSET, 0, FS(0)},
108 { DEFAULT_CHARSET, 0, FS(0)},
109 { DEFAULT_CHARSET, 0, FS(0)},
110 { DEFAULT_CHARSET, 0, FS(0)},
111 { DEFAULT_CHARSET, 0, FS(0)},
112 { DEFAULT_CHARSET, 0, FS(0)},
113 { DEFAULT_CHARSET, 0, FS(0)},
115 { THAI_CHARSET, 874, FS(16)},
116 { SHIFTJIS_CHARSET, 932, FS(17)},
117 { GB2312_CHARSET, 936, FS(18)},
118 { HANGEUL_CHARSET, 949, FS(19)},
119 { CHINESEBIG5_CHARSET, 950, FS(20)},
120 { JOHAB_CHARSET, 1361, FS(21)},
121 /* reserved for alternate ANSI and OEM */
122 { DEFAULT_CHARSET, 0, FS(0)},
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
126 { DEFAULT_CHARSET, 0, FS(0)},
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
129 { DEFAULT_CHARSET, 0, FS(0)},
130 /* reserved for system */
131 { DEFAULT_CHARSET, 0, FS(0)},
132 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
135 /***********************************************************************
136 * LOGFONT conversion functions.
138 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
140 font16->lfHeight = font32->lfHeight;
141 font16->lfWidth = font32->lfWidth;
142 font16->lfEscapement = font32->lfEscapement;
143 font16->lfOrientation = font32->lfOrientation;
144 font16->lfWeight = font32->lfWeight;
145 font16->lfItalic = font32->lfItalic;
146 font16->lfUnderline = font32->lfUnderline;
147 font16->lfStrikeOut = font32->lfStrikeOut;
148 font16->lfCharSet = font32->lfCharSet;
149 font16->lfOutPrecision = font32->lfOutPrecision;
150 font16->lfClipPrecision = font32->lfClipPrecision;
151 font16->lfQuality = font32->lfQuality;
152 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
153 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
154 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
155 font16->lfFaceName[LF_FACESIZE-1] = 0;
158 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
160 font32->lfHeight = font16->lfHeight;
161 font32->lfWidth = font16->lfWidth;
162 font32->lfEscapement = font16->lfEscapement;
163 font32->lfOrientation = font16->lfOrientation;
164 font32->lfWeight = font16->lfWeight;
165 font32->lfItalic = font16->lfItalic;
166 font32->lfUnderline = font16->lfUnderline;
167 font32->lfStrikeOut = font16->lfStrikeOut;
168 font32->lfCharSet = font16->lfCharSet;
169 font32->lfOutPrecision = font16->lfOutPrecision;
170 font32->lfClipPrecision = font16->lfClipPrecision;
171 font32->lfQuality = font16->lfQuality;
172 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
173 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
174 font32->lfFaceName[LF_FACESIZE-1] = 0;
177 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
179 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
180 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
184 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
186 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
187 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
188 LF_FACESIZE, NULL, NULL);
191 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
193 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
195 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
196 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
197 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
198 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
199 font16->elfStyle, LF_FACESIZE, NULL, NULL );
200 font16->elfStyle[LF_FACESIZE-1] = '\0';
201 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
202 font16->elfScript, LF_FACESIZE, NULL, NULL );
203 font16->elfScript[LF_FACESIZE-1] = '\0';
206 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
208 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
210 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
211 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
212 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
213 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
214 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
215 fontA->elfStyle[LF_FACESIZE-1] = '\0';
216 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
217 fontA->elfScript, LF_FACESIZE, NULL, NULL );
218 fontA->elfScript[LF_FACESIZE-1] = '\0';
221 /***********************************************************************
222 * TEXTMETRIC conversion functions.
224 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
226 ptmA->tmHeight = ptmW->tmHeight;
227 ptmA->tmAscent = ptmW->tmAscent;
228 ptmA->tmDescent = ptmW->tmDescent;
229 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
230 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
231 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
232 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
233 ptmA->tmWeight = ptmW->tmWeight;
234 ptmA->tmOverhang = ptmW->tmOverhang;
235 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
236 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
237 ptmA->tmFirstChar = ptmW->tmFirstChar;
238 ptmA->tmLastChar = ptmW->tmLastChar;
239 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
240 ptmA->tmBreakChar = ptmW->tmBreakChar;
241 ptmA->tmItalic = ptmW->tmItalic;
242 ptmA->tmUnderlined = ptmW->tmUnderlined;
243 ptmA->tmStruckOut = ptmW->tmStruckOut;
244 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
245 ptmA->tmCharSet = ptmW->tmCharSet;
249 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
251 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
252 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
253 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
254 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
255 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
256 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
257 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
258 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
259 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
260 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
261 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
262 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
263 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
264 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
265 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
266 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
267 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
268 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
269 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
270 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
271 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
272 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
273 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
274 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
275 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
278 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
280 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
281 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
282 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
283 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
284 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
285 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
288 /***********************************************************************
289 * CreateFontIndirectA (GDI32.@)
291 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
296 FONT_LogFontAToW( plfA, &lfW );
297 return CreateFontIndirectW( &lfW );
299 return CreateFontIndirectW( NULL );
303 /***********************************************************************
304 * CreateFontIndirectW (GDI32.@)
306 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
313 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
314 (HGDIOBJ *)&hFont, &font_funcs )))
316 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
318 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
319 plf->lfHeight, plf->lfWidth,
320 plf->lfEscapement, plf->lfOrientation,
321 plf->lfPitchAndFamily,
322 plf->lfOutPrecision, plf->lfClipPrecision,
323 plf->lfQuality, plf->lfCharSet,
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 %p\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, NEWTEXTMETRICEXW *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 )
524 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
525 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
526 pfe->dwFlags |= ENUM_CALLED;
527 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
529 args[6] = SELECTOROF(pfe->segLogFont);
530 args[5] = OFFSETOF(pfe->segLogFont);
531 args[4] = SELECTOROF(pfe->segTextMetric);
532 args[3] = OFFSETOF(pfe->segTextMetric);
534 args[1] = HIWORD(pfe->lpData);
535 args[0] = LOWORD(pfe->lpData);
536 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
537 ret = LOWORD(result);
539 /* get the lock again and make sure the DC is still valid */
540 dc = DC_GetDCPtr( pfe->hdc );
541 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
543 if (dc) GDI_ReleaseObj( pfe->hdc );
544 pfe->hdc = 0; /* make sure we don't try to release it later on */
551 /***********************************************************************
554 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
555 DWORD fType, LPARAM lp )
557 fontEnum32 *pfe = (fontEnum32*)lp;
561 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
562 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
563 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
565 /* convert font metrics */
566 ENUMLOGFONTEXA logfont;
567 NEWTEXTMETRICEXA tmA;
569 pfe->dwFlags |= ENUM_CALLED;
570 if (!(pfe->dwFlags & ENUM_UNICODE))
572 FONT_EnumLogFontExWToA( plf, &logfont);
573 FONT_NewTextMetricExWToA( ptm, &tmA );
574 plf = (LPENUMLOGFONTEXW)&logfont;
575 ptm = (NEWTEXTMETRICEXW *)&tmA;
577 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
579 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
581 /* get the lock again and make sure the DC is still valid */
582 dc = DC_GetDCPtr( pfe->hdc );
583 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
585 if (dc) GDI_ReleaseObj( pfe->hdc );
586 pfe->hdc = 0; /* make sure we don't try to release it later on */
593 /***********************************************************************
594 * EnumFontFamiliesEx (GDI.613)
596 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
597 FONTENUMPROC16 efproc, LPARAM lParam,
602 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
603 NEWTEXTMETRICEX16 tm16;
604 ENUMLOGFONTEX16 lf16;
609 FONT_LogFont16ToW(plf, &lfW);
611 fe16.hdc = HDC_32(hDC);
613 fe16.physDev = dc->physDev;
614 fe16.lpLogFontParam = plf;
615 fe16.lpEnumFunc = efproc;
616 fe16.lpData = lParam;
617 fe16.lpTextMetric = &tm16;
618 fe16.lpLogFont = &lf16;
619 fe16.segTextMetric = MapLS( &tm16 );
620 fe16.segLogFont = MapLS( &lf16 );
623 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
625 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
632 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
633 fe16.dwFlags &= ~ENUM_CALLED;
634 if (ret && dc->funcs->pEnumDeviceFonts) {
635 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
636 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
640 UnMapLS( fe16.segTextMetric );
641 UnMapLS( fe16.segLogFont );
642 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
646 /***********************************************************************
647 * FONT_EnumFontFamiliesEx
649 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
650 FONTENUMPROCW efproc,
651 LPARAM lParam, DWORD dwUnicode)
654 DC *dc = DC_GetDCPtr( hDC );
660 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
662 fe32.lpLogFontParam = plf;
663 fe32.lpEnumFunc = efproc;
664 fe32.lpData = lParam;
665 fe32.dwFlags = dwUnicode;
668 fe32.physDev = dc->physDev;
670 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
672 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
679 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
680 fe32.dwFlags &= ~ENUM_CALLED;
681 if (ret && dc->funcs->pEnumDeviceFonts) {
682 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
683 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
687 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
691 /***********************************************************************
692 * EnumFontFamiliesExW (GDI32.@)
694 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
695 FONTENUMPROCW efproc,
696 LPARAM lParam, DWORD dwFlags )
698 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
701 /***********************************************************************
702 * EnumFontFamiliesExA (GDI32.@)
704 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
705 FONTENUMPROCA efproc,
706 LPARAM lParam, DWORD dwFlags)
709 FONT_LogFontAToW( plf, &lfW );
711 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
714 /***********************************************************************
715 * EnumFontFamilies (GDI.330)
717 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
718 FONTENUMPROC16 efproc, LPARAM lpData )
722 lf.lfCharSet = DEFAULT_CHARSET;
723 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
724 else lf.lfFaceName[0] = '\0';
726 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
729 /***********************************************************************
730 * EnumFontFamiliesA (GDI32.@)
732 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
733 FONTENUMPROCA efproc, LPARAM lpData )
737 lf.lfCharSet = DEFAULT_CHARSET;
738 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
739 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
741 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
744 /***********************************************************************
745 * EnumFontFamiliesW (GDI32.@)
747 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
748 FONTENUMPROCW efproc, LPARAM lpData )
752 lf.lfCharSet = DEFAULT_CHARSET;
753 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
754 else lf.lfFaceName[0] = 0;
756 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
759 /***********************************************************************
762 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
765 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
768 /***********************************************************************
769 * EnumFontsA (GDI32.@)
771 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
774 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
777 /***********************************************************************
778 * EnumFontsW (GDI32.@)
780 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
783 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
787 /***********************************************************************
788 * GetTextCharacterExtra (GDI32.@)
790 INT WINAPI GetTextCharacterExtra( HDC hdc )
793 DC *dc = DC_GetDCPtr( hdc );
794 if (!dc) return 0x80000000;
796 GDI_ReleaseObj( hdc );
801 /***********************************************************************
802 * SetTextCharacterExtra (GDI32.@)
804 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
807 DC * dc = DC_GetDCPtr( hdc );
808 if (!dc) return 0x80000000;
809 if (dc->funcs->pSetTextCharacterExtra)
810 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
813 prev = dc->charExtra;
814 dc->charExtra = extra;
816 GDI_ReleaseObj( hdc );
821 /***********************************************************************
822 * SetTextJustification (GDI32.@)
824 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
827 DC * dc = DC_GetDCPtr( hdc );
828 if (!dc) return FALSE;
829 if (dc->funcs->pSetTextJustification)
830 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
833 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
834 if (!extra) breaks = 0;
835 dc->breakTotalExtra = extra;
836 dc->breakCount = breaks;
839 dc->breakExtra = extra / breaks;
840 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
848 GDI_ReleaseObj( hdc );
853 /***********************************************************************
854 * GetTextFaceA (GDI32.@)
856 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
858 INT res = GetTextFaceW(hdc, 0, NULL);
859 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
860 GetTextFaceW( hdc, res, nameW );
863 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
866 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
867 HeapFree( GetProcessHeap(), 0, nameW );
871 /***********************************************************************
872 * GetTextFaceW (GDI32.@)
874 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
879 DC * dc = DC_GetDCPtr( hdc );
883 ret = WineEngGetTextFace(dc->gdiFont, count, name);
884 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
888 lstrcpynW( name, font->logfont.lfFaceName, count );
891 else ret = strlenW(font->logfont.lfFaceName) + 1;
892 GDI_ReleaseObj( dc->hFont );
894 GDI_ReleaseObj( hdc );
899 /***********************************************************************
900 * GetTextExtentPoint32A (GDI32.@)
902 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
907 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
910 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
911 HeapFree( GetProcessHeap(), 0, p );
914 TRACE("(%p %s %d %p): returning %ld x %ld\n",
915 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
920 /***********************************************************************
921 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
923 * Computes width and height of the specified string.
929 BOOL WINAPI GetTextExtentPoint32W(
930 HDC hdc, /* [in] Handle of device context */
931 LPCWSTR str, /* [in] Address of text string */
932 INT count, /* [in] Number of characters in string */
933 LPSIZE size) /* [out] Address of structure for string size */
936 DC * dc = DC_GetDCPtr( hdc );
937 if (!dc) return FALSE;
940 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
941 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
942 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
944 else if(dc->funcs->pGetTextExtentPoint)
945 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
947 GDI_ReleaseObj( hdc );
949 TRACE("(%p %s %d %p): returning %ld x %ld\n",
950 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
954 /***********************************************************************
955 * GetTextExtentPointI [GDI32.@]
957 * Computes width and height of the array of glyph indices.
963 BOOL WINAPI GetTextExtentPointI(
964 HDC hdc, /* [in] Handle of device context */
965 const WORD *indices, /* [in] Address of glyph index array */
966 INT count, /* [in] Number of glyphs in array */
967 LPSIZE size) /* [out] Address of structure for string size */
970 DC * dc = DC_GetDCPtr( hdc );
971 if (!dc) return FALSE;
974 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
975 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
976 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
978 else if(dc->funcs->pGetTextExtentPoint) {
979 FIXME("calling GetTextExtentPoint\n");
980 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
983 GDI_ReleaseObj( hdc );
985 TRACE("(%p %p %d %p): returning %ld x %ld\n",
986 hdc, indices, count, size, size->cx, size->cy );
991 /***********************************************************************
992 * GetTextExtentPointA (GDI32.@)
994 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
997 TRACE("not bug compatible.\n");
998 return GetTextExtentPoint32A( hdc, str, count, size );
1001 /***********************************************************************
1002 * GetTextExtentPointW (GDI32.@)
1004 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1007 TRACE("not bug compatible.\n");
1008 return GetTextExtentPoint32W( hdc, str, count, size );
1012 /***********************************************************************
1013 * GetTextExtentExPointA (GDI32.@)
1015 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1016 INT maxExt, LPINT lpnFit,
1017 LPINT alpDx, LPSIZE size )
1021 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1022 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1023 HeapFree( GetProcessHeap(), 0, p );
1028 /***********************************************************************
1029 * GetTextExtentExPointW (GDI32.@)
1031 * Return the size of the string as it would be if it was output properly by
1034 * This should include
1035 * - Intercharacter spacing
1036 * - justification spacing (not yet done)
1037 * - kerning? see below
1039 * Kerning. Since kerning would be carried out by the rendering code it should
1040 * be done by the driver. However they don't support it yet. Also I am not
1041 * yet persuaded that (certainly under Win95) any kerning is actually done.
1043 * str: According to MSDN this should be null-terminated. That is not true; a
1044 * null will not terminate it early.
1045 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1046 * than count. I have seen it be either the size of the full string or
1047 * 1 less than the size of the full string. I have not seen it bear any
1048 * resemblance to the portion that would fit.
1049 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1050 * trailing intercharacter spacing and any trailing justification.
1053 * Currently we do this by measuring each character etc. We should do it by
1054 * passing the request to the driver, perhaps by extending the
1055 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1056 * thinking about kerning issues and rounding issues in the justification.
1059 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1060 INT maxExt, LPINT lpnFit,
1061 LPINT alpDx, LPSIZE size )
1063 int index, nFit, extent;
1067 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1069 size->cx = size->cy = nFit = extent = 0;
1070 for(index = 0; index < count; index++)
1072 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1073 /* GetTextExtentPoint includes intercharacter spacing. */
1074 /* FIXME - justification needs doing yet. Remember that the base
1075 * data will not be in logical coordinates.
1078 if( !lpnFit || extent <= maxExt )
1079 /* It is allowed to be equal. */
1082 if( alpDx ) alpDx[index] = extent;
1084 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1088 if(lpnFit) *lpnFit = nFit;
1091 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1097 /***********************************************************************
1098 * GetTextMetricsA (GDI32.@)
1100 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1104 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1105 FONT_TextMetricWToA( &tm32, metrics );
1109 /***********************************************************************
1110 * GetTextMetricsW (GDI32.@)
1112 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1115 DC * dc = DC_GetDCPtr( hdc );
1116 if (!dc) return FALSE;
1119 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1120 else if (dc->funcs->pGetTextMetrics)
1121 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1125 /* device layer returns values in device units
1126 * therefore we have to convert them to logical */
1128 #define WDPTOLP(x) ((x<0)? \
1129 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1130 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1131 #define HDPTOLP(y) ((y<0)? \
1132 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1133 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1135 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1136 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1137 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1138 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1139 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1140 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1141 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1142 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1146 TRACE("text metrics:\n"
1147 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1148 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1149 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1150 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1151 " PitchAndFamily = %02x\n"
1152 " --------------------\n"
1153 " InternalLeading = %li\n"
1157 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1158 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1159 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1160 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1161 metrics->tmPitchAndFamily,
1162 metrics->tmInternalLeading,
1165 metrics->tmHeight );
1167 GDI_ReleaseObj( hdc );
1172 /***********************************************************************
1173 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1176 * lpOTM should be LPOUTLINETEXTMETRIC
1179 * Success: Non-zero or size of required buffer
1182 UINT16 WINAPI GetOutlineTextMetrics16(
1183 HDC16 hdc, /* [in] Handle of device context */
1184 UINT16 cbData, /* [in] Size of metric data array */
1185 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1187 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1192 /***********************************************************************
1193 * GetOutlineTextMetricsA (GDI32.@)
1194 * Gets metrics for TrueType fonts.
1198 * Success: Non-zero or size of required buffer
1201 UINT WINAPI GetOutlineTextMetricsA(
1202 HDC hdc, /* [in] Handle of device context */
1203 UINT cbData, /* [in] Size of metric data array */
1204 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1206 char buf[512], *ptr;
1208 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1211 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1212 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1214 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1215 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1218 needed = sizeof(OUTLINETEXTMETRICA);
1219 if(lpOTMW->otmpFamilyName)
1220 needed += WideCharToMultiByte(CP_ACP, 0,
1221 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1222 NULL, 0, NULL, NULL);
1223 if(lpOTMW->otmpFaceName)
1224 needed += WideCharToMultiByte(CP_ACP, 0,
1225 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1226 NULL, 0, NULL, NULL);
1227 if(lpOTMW->otmpStyleName)
1228 needed += WideCharToMultiByte(CP_ACP, 0,
1229 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1230 NULL, 0, NULL, NULL);
1231 if(lpOTMW->otmpFullName)
1232 needed += WideCharToMultiByte(CP_ACP, 0,
1233 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1234 NULL, 0, NULL, NULL);
1241 if(needed > cbData) {
1247 lpOTM->otmSize = needed;
1248 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1249 lpOTM->otmFiller = 0;
1250 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1251 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1252 lpOTM->otmfsType = lpOTMW->otmfsType;
1253 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1254 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1255 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1256 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1257 lpOTM->otmAscent = lpOTMW->otmAscent;
1258 lpOTM->otmDescent = lpOTMW->otmDescent;
1259 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1260 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1261 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1262 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1263 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1264 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1265 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1266 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1267 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1268 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1269 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1270 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1271 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1272 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1273 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1274 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1277 ptr = (char*)(lpOTM + 1);
1278 left = needed - sizeof(*lpOTM);
1280 if(lpOTMW->otmpFamilyName) {
1281 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1282 len = WideCharToMultiByte(CP_ACP, 0,
1283 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1284 ptr, left, NULL, NULL);
1288 lpOTM->otmpFamilyName = 0;
1290 if(lpOTMW->otmpFaceName) {
1291 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1292 len = WideCharToMultiByte(CP_ACP, 0,
1293 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1294 ptr, left, NULL, NULL);
1298 lpOTM->otmpFaceName = 0;
1300 if(lpOTMW->otmpStyleName) {
1301 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1302 len = WideCharToMultiByte(CP_ACP, 0,
1303 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1304 ptr, left, NULL, NULL);
1308 lpOTM->otmpStyleName = 0;
1310 if(lpOTMW->otmpFullName) {
1311 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1312 len = WideCharToMultiByte(CP_ACP, 0,
1313 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1314 ptr, left, NULL, NULL);
1317 lpOTM->otmpFullName = 0;
1324 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1325 HeapFree(GetProcessHeap(), 0, lpOTMW);
1331 /***********************************************************************
1332 * GetOutlineTextMetricsW [GDI32.@]
1334 UINT WINAPI GetOutlineTextMetricsW(
1335 HDC hdc, /* [in] Handle of device context */
1336 UINT cbData, /* [in] Size of metric data array */
1337 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1339 DC *dc = DC_GetDCPtr( hdc );
1342 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1346 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1347 if(ret && ret <= cbData) {
1348 #define WDPTOLP(x) ((x<0)? \
1349 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1350 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1351 #define HDPTOLP(y) ((y<0)? \
1352 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1353 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1355 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1356 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1357 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1358 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1359 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1360 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1361 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1362 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1363 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1364 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1365 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1366 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1367 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1368 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1369 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1370 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1371 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1372 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1373 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1374 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1375 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1376 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1377 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1378 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1379 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1380 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1381 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1382 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1383 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1384 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1385 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1386 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1392 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1393 but really this should just be a return 0. */
1395 ret = sizeof(*lpOTM);
1400 memset(lpOTM, 0, ret);
1401 lpOTM->otmSize = sizeof(*lpOTM);
1402 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1404 Further fill of the structure not implemented,
1405 Needs real values for the structure members
1410 GDI_ReleaseObj(hdc);
1415 /***********************************************************************
1416 * GetCharWidthW (GDI32.@)
1417 * GetCharWidth32W (GDI32.@)
1419 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1424 DC * dc = DC_GetDCPtr( hdc );
1425 if (!dc) return FALSE;
1428 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1429 else if (dc->funcs->pGetCharWidth)
1430 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1434 /* convert device units to logical */
1436 extra = dc->vportExtX >> 1;
1437 for( i = firstChar; i <= lastChar; i++, buffer++ )
1438 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1441 GDI_ReleaseObj( hdc );
1446 /***********************************************************************
1447 * GetCharWidthA (GDI32.@)
1448 * GetCharWidth32A (GDI32.@)
1450 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1453 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1458 if(count <= 0) return FALSE;
1460 str = HeapAlloc(GetProcessHeap(), 0, count);
1461 for(i = 0; i < count; i++)
1462 str[i] = (BYTE)(firstChar + i);
1464 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1466 for(i = 0; i < wlen; i++)
1468 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1476 HeapFree(GetProcessHeap(), 0, str);
1477 HeapFree(GetProcessHeap(), 0, wstr);
1483 /* FIXME: all following APIs ******************************************/
1486 /***********************************************************************
1487 * SetMapperFlags (GDI32.@)
1489 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1491 DC *dc = DC_GetDCPtr( hDC );
1494 if(dc->funcs->pSetMapperFlags)
1495 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1497 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1498 GDI_ReleaseObj( hDC );
1502 /***********************************************************************
1503 * GetAspectRatioFilterEx (GDI.486)
1505 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1507 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1511 /***********************************************************************
1512 * GetAspectRatioFilterEx (GDI32.@)
1514 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1516 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1521 /***********************************************************************
1522 * GetCharABCWidthsA (GDI32.@)
1524 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1527 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1532 if(count <= 0) return FALSE;
1534 str = HeapAlloc(GetProcessHeap(), 0, count);
1535 for(i = 0; i < count; i++)
1536 str[i] = (BYTE)(firstChar + i);
1538 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1540 for(i = 0; i < wlen; i++)
1542 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1550 HeapFree(GetProcessHeap(), 0, str);
1551 HeapFree(GetProcessHeap(), 0, wstr);
1557 /******************************************************************************
1558 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1561 * hdc [I] Handle of device context
1562 * firstChar [I] First character in range to query
1563 * lastChar [I] Last character in range to query
1564 * abc [O] Address of character-width structure
1567 * Only works with TrueType fonts
1573 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1576 DC *dc = DC_GetDCPtr(hdc);
1582 for (i=firstChar;i<=lastChar;i++) {
1583 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1584 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1585 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1586 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1590 GDI_ReleaseObj(hdc);
1595 /***********************************************************************
1596 * GetGlyphOutline (GDI.309)
1598 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1599 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1600 LPVOID lpBuffer, const MAT2 *lpmat2 )
1602 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1603 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1604 return (DWORD)-1; /* failure */
1608 /***********************************************************************
1609 * GetGlyphOutlineA (GDI32.@)
1611 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1612 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1613 LPVOID lpBuffer, const MAT2 *lpmat2 )
1619 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1620 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1624 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1627 HeapFree(GetProcessHeap(), 0, p);
1631 /***********************************************************************
1632 * GetGlyphOutlineW (GDI32.@)
1634 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1635 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1636 LPVOID lpBuffer, const MAT2 *lpmat2 )
1638 DC *dc = DC_GetDCPtr(hdc);
1641 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1642 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1644 if(!dc) return GDI_ERROR;
1647 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1648 cbBuffer, lpBuffer, lpmat2);
1652 GDI_ReleaseObj(hdc);
1657 /***********************************************************************
1658 * CreateScalableFontResourceA (GDI32.@)
1660 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1661 LPCSTR lpszResourceFile,
1662 LPCSTR lpszFontFile,
1663 LPCSTR lpszCurrentPath )
1667 /* fHidden=1 - only visible for the calling app, read-only, not
1668 * enumbered with EnumFonts/EnumFontFamilies
1669 * lpszCurrentPath can be NULL
1671 FIXME("(%ld,%s,%s,%s): stub\n",
1672 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1673 debugstr_a(lpszCurrentPath) );
1675 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1676 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1678 SetLastError(ERROR_FILE_EXISTS);
1681 return FALSE; /* create failed */
1684 /***********************************************************************
1685 * CreateScalableFontResourceW (GDI32.@)
1687 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1688 LPCWSTR lpszResourceFile,
1689 LPCWSTR lpszFontFile,
1690 LPCWSTR lpszCurrentPath )
1692 FIXME("(%ld,%p,%p,%p): stub\n",
1693 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1694 return FALSE; /* create failed */
1698 /*************************************************************************
1699 * GetRasterizerCaps (GDI32.@)
1701 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1703 lprs->nSize = sizeof(RASTERIZER_STATUS);
1704 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1705 lprs->nLanguageID = 0;
1710 /*************************************************************************
1711 * GetKerningPairsA (GDI32.@)
1713 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1716 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1717 for (i = 0; i < cPairs; i++)
1718 lpKerningPairs[i].iKernAmount = 0;
1723 /*************************************************************************
1724 * GetKerningPairsW (GDI32.@)
1726 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1727 LPKERNINGPAIR lpKerningPairs )
1729 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1732 /*************************************************************************
1733 * TranslateCharsetInfo [GDI32.@]
1735 * Fills a CHARSETINFO structure for a character set, code page, or
1736 * font. This allows making the correspondance between different labelings
1737 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1738 * of the same encoding.
1740 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1741 * only one codepage should be set in *lpSrc.
1744 * TRUE on success, FALSE on failure.
1747 BOOL WINAPI TranslateCharsetInfo(
1748 LPDWORD lpSrc, /* [in]
1749 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1750 if flags == TCI_SRCCHARSET: a character set value
1751 if flags == TCI_SRCCODEPAGE: a code page value
1753 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1754 DWORD flags /* [in] determines interpretation of lpSrc */
1758 case TCI_SRCFONTSIG:
1759 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1761 case TCI_SRCCODEPAGE:
1762 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1764 case TCI_SRCCHARSET:
1765 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1770 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1771 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1775 /*************************************************************************
1776 * GetFontLanguageInfo (GDI32.@)
1778 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1780 FONTSIGNATURE fontsig;
1781 static const DWORD GCP_DBCS_MASK=0x003F0000,
1782 GCP_DIACRITIC_MASK=0x00000000,
1783 FLI_GLYPHS_MASK=0x00000000,
1784 GCP_GLYPHSHAPE_MASK=0x00000040,
1785 GCP_KASHIDA_MASK=0x00000000,
1786 GCP_LIGATE_MASK=0x00000000,
1787 GCP_USEKERNING_MASK=0x00000000,
1788 GCP_REORDER_MASK=0x00000060;
1792 GetTextCharsetInfo( hdc, &fontsig, 0 );
1793 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1795 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1798 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1799 result|=GCP_DIACRITIC;
1801 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1804 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1805 result|=GCP_GLYPHSHAPE;
1807 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1808 result|=GCP_KASHIDA;
1810 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1813 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1814 result|=GCP_USEKERNING;
1816 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1817 result|=GCP_REORDER;
1823 /*************************************************************************
1824 * GetFontData [GDI32.@] Retrieve data for TrueType font
1828 * success: Number of bytes returned
1829 * failure: GDI_ERROR
1833 * Calls SetLastError()
1836 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1837 LPVOID buffer, DWORD length)
1839 DC *dc = DC_GetDCPtr(hdc);
1840 DWORD ret = GDI_ERROR;
1842 if(!dc) return GDI_ERROR;
1845 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1847 GDI_ReleaseObj(hdc);
1851 /*************************************************************************
1852 * GetGlyphIndicesA [GDI32.@]
1854 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1855 LPWORD pgi, DWORD flags)
1861 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1862 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1864 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1865 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1866 HeapFree(GetProcessHeap(), 0, lpstrW);
1871 /*************************************************************************
1872 * GetGlyphIndicesW [GDI32.@]
1874 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1875 LPWORD pgi, DWORD flags)
1877 DC *dc = DC_GetDCPtr(hdc);
1878 DWORD ret = GDI_ERROR;
1880 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1881 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1883 if(!dc) return GDI_ERROR;
1886 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1888 GDI_ReleaseObj(hdc);
1892 /*************************************************************************
1893 * GetCharacterPlacementA [GDI32.@]
1896 * the web browser control of ie4 calls this with dwFlags=0
1899 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1900 INT nMaxExtent, GCP_RESULTSA *lpResults,
1905 GCP_RESULTSW resultsW;
1909 TRACE("%s, %d, %d, 0x%08lx\n",
1910 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1912 /* both structs are equal in size */
1913 memcpy(&resultsW, lpResults, sizeof(resultsW));
1915 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1916 if(lpResults->lpOutString)
1917 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1919 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1921 if(lpResults->lpOutString) {
1922 if(font_cp != CP_SYMBOL)
1923 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1924 lpResults->lpOutString, uCount, NULL, NULL );
1926 for(i = 0; i < uCount; i++)
1927 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1930 HeapFree(GetProcessHeap(), 0, lpStringW);
1931 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1936 /*************************************************************************
1937 * GetCharacterPlacementW [GDI32.@]
1939 * Retrieve information about a string. This includes the width, reordering,
1940 * Glyphing and so on.
1944 * The width and height of the string if succesful, 0 if failed.
1948 * All flags except GCP_REORDER are not yet implemented.
1949 * Reordering is not 100% complient to the Windows BiDi method.
1950 * Caret positioning is not yet implemented.
1951 * Classes are not yet implemented.
1955 GetCharacterPlacementW(
1956 HDC hdc, /* [in] Device context for which the rendering is to be done */
1957 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1958 INT uCount, /* [in] Number of WORDS in string. */
1959 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1960 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1961 DWORD dwFlags /* [in] Flags specifying how to process the string */
1968 TRACE("%s, %d, %d, 0x%08lx\n",
1969 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1971 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1972 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1973 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1974 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1975 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1977 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1978 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1979 if(lpResults->lpClass) FIXME("classes not implemented\n");
1981 nSet = (UINT)uCount;
1982 if(nSet > lpResults->nGlyphs)
1983 nSet = lpResults->nGlyphs;
1985 /* return number of initialized fields */
1986 lpResults->nGlyphs = nSet;
1990 /* Treat the case where no special handling was requested in a fastpath way */
1991 /* copy will do if the GCP_REORDER flag is not set */
1992 if(lpResults->lpOutString)
1993 for(i=0; i<nSet && lpString[i]!=0; ++i )
1994 lpResults->lpOutString[i]=lpString[i];
1996 if(lpResults->lpOrder)
1998 for(i = 0; i < nSet; i++)
1999 lpResults->lpOrder[i] = i;
2003 if((dwFlags&GCP_REORDER)!=0)
2007 /* Keep a static table that translates the C2 types to something meaningful */
2008 /* 1 - left to right
2009 * -1 - right to left
2012 static const int chardir[]={ 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, 0, 0 };
2014 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2015 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
2017 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2022 /* Fill in the order array with directionality values */
2023 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2025 /* The complete and correct (at least according to MS) BiDi algorythm is not
2026 * yet implemented here. Instead, we just make sure that consecutive runs of
2027 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2028 * that are between runs of opposing directions the base (ok, always LTR) dir.
2029 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2032 for( i=0; i<uCount; i+=run_end )
2034 for( run_end=1; i+run_end<uCount &&
2035 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2036 chardir[pwCharType[i+run_end]]==0); ++run_end )
2039 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2042 if(lpResults->lpOutString)
2045 for( j=0; j<run_end; j++ )
2047 lpResults->lpOutString[i+j]=lpString[i+j];
2051 if(lpResults->lpOrder)
2054 for( j=0; j<run_end; j++ )
2055 lpResults->lpOrder[i+j] = i+j;
2061 /* Since, at this stage, the paragraph context is always LTR,
2062 * remove any neutrals from the end of this run.
2064 if( chardir[pwCharType[i]]!=0 )
2065 while( chardir[pwCharType[i+run_end-1]]==0 )
2068 if(lpResults->lpOutString)
2071 for( j=0; j<run_end; j++ )
2073 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2077 if(lpResults->lpOrder)
2080 for( j=0; j<run_end; j++ )
2081 lpResults->lpOrder[i+j] = i+run_end-j-1;
2086 HeapFree(GetProcessHeap(), 0, pwCharType);
2089 /* FIXME: Will use the placement chars */
2090 if (lpResults->lpDx)
2093 for (i = 0; i < nSet; i++)
2095 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2096 lpResults->lpDx[i]= c;
2100 if(lpResults->lpGlyphs)
2101 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2103 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2104 ret = MAKELONG(size.cx, size.cy);
2109 /*************************************************************************
2110 * GetCharABCWidthsFloatA [GDI32.@]
2112 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2115 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2119 /*************************************************************************
2120 * GetCharABCWidthsFloatW [GDI32.@]
2122 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2123 UINT iLastChar, LPABCFLOAT lpABCF)
2125 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2129 /*************************************************************************
2130 * GetCharWidthFloatA [GDI32.@]
2132 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2133 UINT iLastChar, PFLOAT pxBuffer)
2135 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2139 /*************************************************************************
2140 * GetCharWidthFloatW [GDI32.@]
2142 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2143 UINT iLastChar, PFLOAT pxBuffer)
2145 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2150 /***********************************************************************
2152 * Font Resource API *
2154 ***********************************************************************/
2156 /***********************************************************************
2157 * AddFontResourceA (GDI32.@)
2159 INT WINAPI AddFontResourceA( LPCSTR str )
2161 return AddFontResourceExA( str, 0, NULL);
2164 /***********************************************************************
2165 * AddFontResourceW (GDI32.@)
2167 INT WINAPI AddFontResourceW( LPCWSTR str )
2169 return AddFontResourceExW(str, 0, NULL);
2173 /***********************************************************************
2174 * AddFontResourceExA (GDI32.@)
2176 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2178 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2179 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2182 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2183 ret = AddFontResourceExW(strW, fl, pdv);
2184 HeapFree(GetProcessHeap(), 0, strW);
2188 /***********************************************************************
2189 * AddFontResourceExW (GDI32.@)
2191 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2193 return WineEngAddFontResourceEx(str, fl, pdv);
2196 /***********************************************************************
2197 * RemoveFontResourceA (GDI32.@)
2199 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2201 return RemoveFontResourceExA(str, 0, 0);
2204 /***********************************************************************
2205 * RemoveFontResourceW (GDI32.@)
2207 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2209 return RemoveFontResourceExW(str, 0, 0);
2212 /***********************************************************************
2213 * RemoveFontResourceExA (GDI32.@)
2215 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2217 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2218 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2221 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2222 ret = RemoveFontResourceExW(strW, fl, pdv);
2223 HeapFree(GetProcessHeap(), 0, strW);
2227 /***********************************************************************
2228 * RemoveFontResourceExW (GDI32.@)
2230 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2232 return WineEngRemoveFontResourceEx(str, fl, pdv);