4 * Copyright 1993 Alexandre Julliard
6 * Copyright 2002,2003 Shachar Shemesh
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wine/port.h"
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(font);
37 WINE_DECLARE_DEBUG_CHANNEL(gdi);
39 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
40 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
43 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
45 static const struct gdi_obj_funcs font_funcs =
47 FONT_SelectObject, /* pSelectObject */
48 FONT_GetObject16, /* pGetObject16 */
49 FONT_GetObjectA, /* pGetObjectA */
50 FONT_GetObjectW, /* pGetObjectW */
51 NULL, /* pUnrealizeObject */
52 FONT_DeleteObject /* pDeleteObject */
55 #define ENUM_UNICODE 0x00000001
56 #define ENUM_CALLED 0x00000002
66 LPLOGFONT16 lpLogFontParam;
67 FONTENUMPROC16 lpEnumFunc;
70 LPNEWTEXTMETRICEX16 lpTextMetric;
71 LPENUMLOGFONTEX16 lpLogFont;
82 LPLOGFONTW lpLogFontParam;
83 FONTENUMPROCW lpEnumFunc;
92 * For TranslateCharsetInfo
94 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
95 #define MAXTCIINDEX 32
96 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
98 { ANSI_CHARSET, 1252, FS(0)},
99 { EASTEUROPE_CHARSET, 1250, FS(1)},
100 { RUSSIAN_CHARSET, 1251, FS(2)},
101 { GREEK_CHARSET, 1253, FS(3)},
102 { TURKISH_CHARSET, 1254, FS(4)},
103 { HEBREW_CHARSET, 1255, FS(5)},
104 { ARABIC_CHARSET, 1256, FS(6)},
105 { BALTIC_CHARSET, 1257, FS(7)},
106 { VIETNAMESE_CHARSET, 1258, FS(8)},
107 /* reserved by ANSI */
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)},
114 { DEFAULT_CHARSET, 0, FS(0)},
116 { THAI_CHARSET, 874, FS(16)},
117 { SHIFTJIS_CHARSET, 932, FS(17)},
118 { GB2312_CHARSET, 936, FS(18)},
119 { HANGEUL_CHARSET, 949, FS(19)},
120 { CHINESEBIG5_CHARSET, 950, FS(20)},
121 { JOHAB_CHARSET, 1361, FS(21)},
122 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
131 /* reserved for system */
132 { DEFAULT_CHARSET, 0, FS(0)},
133 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
136 /***********************************************************************
137 * LOGFONT conversion functions.
139 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
141 font16->lfHeight = font32->lfHeight;
142 font16->lfWidth = font32->lfWidth;
143 font16->lfEscapement = font32->lfEscapement;
144 font16->lfOrientation = font32->lfOrientation;
145 font16->lfWeight = font32->lfWeight;
146 font16->lfItalic = font32->lfItalic;
147 font16->lfUnderline = font32->lfUnderline;
148 font16->lfStrikeOut = font32->lfStrikeOut;
149 font16->lfCharSet = font32->lfCharSet;
150 font16->lfOutPrecision = font32->lfOutPrecision;
151 font16->lfClipPrecision = font32->lfClipPrecision;
152 font16->lfQuality = font32->lfQuality;
153 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
154 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
155 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
156 font16->lfFaceName[LF_FACESIZE-1] = 0;
159 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
161 font32->lfHeight = font16->lfHeight;
162 font32->lfWidth = font16->lfWidth;
163 font32->lfEscapement = font16->lfEscapement;
164 font32->lfOrientation = font16->lfOrientation;
165 font32->lfWeight = font16->lfWeight;
166 font32->lfItalic = font16->lfItalic;
167 font32->lfUnderline = font16->lfUnderline;
168 font32->lfStrikeOut = font16->lfStrikeOut;
169 font32->lfCharSet = font16->lfCharSet;
170 font32->lfOutPrecision = font16->lfOutPrecision;
171 font32->lfClipPrecision = font16->lfClipPrecision;
172 font32->lfQuality = font16->lfQuality;
173 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
174 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
175 font32->lfFaceName[LF_FACESIZE-1] = 0;
178 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
180 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
181 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
185 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
187 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
188 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
189 LF_FACESIZE, NULL, NULL);
192 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
194 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
196 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
197 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
198 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
200 font16->elfStyle, LF_FACESIZE, NULL, NULL );
201 font16->elfStyle[LF_FACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
203 font16->elfScript, LF_FACESIZE, NULL, NULL );
204 font16->elfScript[LF_FACESIZE-1] = '\0';
207 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
209 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
211 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
212 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
213 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
215 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
216 fontA->elfStyle[LF_FACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
218 fontA->elfScript, LF_FACESIZE, NULL, NULL );
219 fontA->elfScript[LF_FACESIZE-1] = '\0';
222 /***********************************************************************
223 * TEXTMETRIC conversion functions.
225 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
227 ptmA->tmHeight = ptmW->tmHeight;
228 ptmA->tmAscent = ptmW->tmAscent;
229 ptmA->tmDescent = ptmW->tmDescent;
230 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
231 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
232 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
233 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
234 ptmA->tmWeight = ptmW->tmWeight;
235 ptmA->tmOverhang = ptmW->tmOverhang;
236 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
237 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
238 ptmA->tmFirstChar = ptmW->tmFirstChar;
239 ptmA->tmLastChar = ptmW->tmLastChar;
240 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
241 ptmA->tmBreakChar = ptmW->tmBreakChar;
242 ptmA->tmItalic = ptmW->tmItalic;
243 ptmA->tmUnderlined = ptmW->tmUnderlined;
244 ptmA->tmStruckOut = ptmW->tmStruckOut;
245 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
246 ptmA->tmCharSet = ptmW->tmCharSet;
250 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
252 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
253 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
254 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
255 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
256 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
257 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
258 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
259 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
260 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
261 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
262 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
263 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
264 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
265 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
266 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
267 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
268 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
269 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
270 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
271 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
272 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
273 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
274 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
275 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
276 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
279 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
281 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
282 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
283 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
284 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
285 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
286 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
289 /***********************************************************************
290 * CreateFontIndirectA (GDI32.@)
292 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
297 FONT_LogFontAToW( plfA, &lfW );
298 return CreateFontIndirectW( &lfW );
300 return CreateFontIndirectW( NULL );
304 /***********************************************************************
305 * CreateFontIndirectW (GDI32.@)
307 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
314 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
315 (HGDIOBJ *)&hFont, &font_funcs )))
317 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
319 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
320 plf->lfHeight, plf->lfWidth,
321 plf->lfEscapement, plf->lfOrientation,
322 plf->lfPitchAndFamily,
323 plf->lfOutPrecision, plf->lfClipPrecision,
324 plf->lfQuality, plf->lfCharSet,
325 debugstr_w(plf->lfFaceName),
326 plf->lfWeight > 400 ? "Bold" : "",
327 plf->lfItalic ? "Italic" : "", hFont);
329 if (plf->lfEscapement != plf->lfOrientation) {
330 /* this should really depend on whether GM_ADVANCED is set */
331 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
332 WARN("orientation angle %f set to "
333 "escapement angle %f for new font %p\n",
334 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
336 GDI_ReleaseObj( hFont );
339 else WARN("(NULL) => NULL\n");
344 /*************************************************************************
345 * CreateFontA (GDI32.@)
347 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
348 INT orient, INT weight, DWORD italic,
349 DWORD underline, DWORD strikeout, DWORD charset,
350 DWORD outpres, DWORD clippres, DWORD quality,
351 DWORD pitch, LPCSTR name )
355 logfont.lfHeight = height;
356 logfont.lfWidth = width;
357 logfont.lfEscapement = esc;
358 logfont.lfOrientation = orient;
359 logfont.lfWeight = weight;
360 logfont.lfItalic = italic;
361 logfont.lfUnderline = underline;
362 logfont.lfStrikeOut = strikeout;
363 logfont.lfCharSet = charset;
364 logfont.lfOutPrecision = outpres;
365 logfont.lfClipPrecision = clippres;
366 logfont.lfQuality = quality;
367 logfont.lfPitchAndFamily = pitch;
370 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
372 logfont.lfFaceName[0] = '\0';
374 return CreateFontIndirectA( &logfont );
377 /*************************************************************************
378 * CreateFontW (GDI32.@)
380 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
381 INT orient, INT weight, DWORD italic,
382 DWORD underline, DWORD strikeout, DWORD charset,
383 DWORD outpres, DWORD clippres, DWORD quality,
384 DWORD pitch, LPCWSTR name )
388 logfont.lfHeight = height;
389 logfont.lfWidth = width;
390 logfont.lfEscapement = esc;
391 logfont.lfOrientation = orient;
392 logfont.lfWeight = weight;
393 logfont.lfItalic = italic;
394 logfont.lfUnderline = underline;
395 logfont.lfStrikeOut = strikeout;
396 logfont.lfCharSet = charset;
397 logfont.lfOutPrecision = outpres;
398 logfont.lfClipPrecision = clippres;
399 logfont.lfQuality = quality;
400 logfont.lfPitchAndFamily = pitch;
403 lstrcpynW(logfont.lfFaceName, name,
404 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
406 logfont.lfFaceName[0] = '\0';
408 return CreateFontIndirectW( &logfont );
412 /***********************************************************************
415 * If the driver supports vector fonts we create a gdi font first and
416 * then call the driver to give it a chance to supply its own device
417 * font. If the driver wants to do this it returns TRUE and we can
418 * delete the gdi font, if the driver wants to use the gdi font it
419 * should return FALSE, to signal an error return GDI_ERROR. For
420 * drivers that don't support vector fonts they must supply their own
423 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
426 DC *dc = DC_GetDCPtr( hdc );
430 if (dc->hFont != handle || dc->gdiFont == NULL)
432 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
433 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
436 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
438 if (ret && dc->gdiFont) dc->gdiFont = 0;
440 if (ret == HGDI_ERROR)
441 ret = 0; /* SelectObject returns 0 on error */
447 GDI_ReleaseObj( hdc );
452 /***********************************************************************
455 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
460 FONT_LogFontWTo16( &font->logfont, &lf16 );
462 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
463 memcpy( buffer, &lf16, count );
467 /***********************************************************************
470 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
475 FONT_LogFontWToA( &font->logfont, &lfA );
477 if (count > sizeof(lfA)) count = sizeof(lfA);
479 memcpy( buffer, &lfA, count );
483 /***********************************************************************
486 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
489 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
491 memcpy( buffer, &font->logfont, count );
496 /***********************************************************************
499 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
501 WineEngDestroyFontInstance( handle );
502 return GDI_FreeObject( handle, obj );
506 /***********************************************************************
507 * FONT_EnumInstance16
509 * Called by the device driver layer to pass font info
510 * down to the application.
512 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
513 DWORD fType, LPARAM lp )
515 fontEnum16 *pfe = (fontEnum16*)lp;
519 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
520 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
525 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
526 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
527 pfe->dwFlags |= ENUM_CALLED;
528 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
530 args[6] = SELECTOROF(pfe->segLogFont);
531 args[5] = OFFSETOF(pfe->segLogFont);
532 args[4] = SELECTOROF(pfe->segTextMetric);
533 args[3] = OFFSETOF(pfe->segTextMetric);
535 args[1] = HIWORD(pfe->lpData);
536 args[0] = LOWORD(pfe->lpData);
537 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
538 ret = LOWORD(result);
540 /* get the lock again and make sure the DC is still valid */
541 dc = DC_GetDCPtr( pfe->hdc );
542 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
544 if (dc) GDI_ReleaseObj( pfe->hdc );
545 pfe->hdc = 0; /* make sure we don't try to release it later on */
552 /***********************************************************************
555 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
556 DWORD fType, LPARAM lp )
558 fontEnum32 *pfe = (fontEnum32*)lp;
562 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
563 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
564 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
566 /* convert font metrics */
567 ENUMLOGFONTEXA logfont;
568 NEWTEXTMETRICEXA tmA;
570 pfe->dwFlags |= ENUM_CALLED;
571 if (!(pfe->dwFlags & ENUM_UNICODE))
573 FONT_EnumLogFontExWToA( plf, &logfont);
574 FONT_NewTextMetricExWToA( ptm, &tmA );
575 plf = (LPENUMLOGFONTEXW)&logfont;
576 ptm = (NEWTEXTMETRICEXW *)&tmA;
578 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
580 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
582 /* get the lock again and make sure the DC is still valid */
583 dc = DC_GetDCPtr( pfe->hdc );
584 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
586 if (dc) GDI_ReleaseObj( pfe->hdc );
587 pfe->hdc = 0; /* make sure we don't try to release it later on */
594 /***********************************************************************
595 * EnumFontFamiliesEx (GDI.613)
597 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
598 FONTENUMPROC16 efproc, LPARAM lParam,
603 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
604 NEWTEXTMETRICEX16 tm16;
605 ENUMLOGFONTEX16 lf16;
610 FONT_LogFont16ToW(plf, &lfW);
612 fe16.hdc = HDC_32(hDC);
614 fe16.physDev = dc->physDev;
615 fe16.lpLogFontParam = plf;
616 fe16.lpEnumFunc = efproc;
617 fe16.lpData = lParam;
618 fe16.lpTextMetric = &tm16;
619 fe16.lpLogFont = &lf16;
620 fe16.segTextMetric = MapLS( &tm16 );
621 fe16.segLogFont = MapLS( &lf16 );
624 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
626 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
633 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
634 fe16.dwFlags &= ~ENUM_CALLED;
635 if (ret && dc->funcs->pEnumDeviceFonts) {
636 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
637 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
641 UnMapLS( fe16.segTextMetric );
642 UnMapLS( fe16.segLogFont );
643 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
647 /***********************************************************************
648 * FONT_EnumFontFamiliesEx
650 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
651 FONTENUMPROCW efproc,
652 LPARAM lParam, DWORD dwUnicode)
655 DC *dc = DC_GetDCPtr( hDC );
661 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
663 fe32.lpLogFontParam = plf;
664 fe32.lpEnumFunc = efproc;
665 fe32.lpData = lParam;
666 fe32.dwFlags = dwUnicode;
669 fe32.physDev = dc->physDev;
671 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
673 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
680 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
681 fe32.dwFlags &= ~ENUM_CALLED;
682 if (ret && dc->funcs->pEnumDeviceFonts) {
683 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
684 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
688 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
692 /***********************************************************************
693 * EnumFontFamiliesExW (GDI32.@)
695 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
696 FONTENUMPROCW efproc,
697 LPARAM lParam, DWORD dwFlags )
699 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
702 /***********************************************************************
703 * EnumFontFamiliesExA (GDI32.@)
705 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
706 FONTENUMPROCA efproc,
707 LPARAM lParam, DWORD dwFlags)
710 FONT_LogFontAToW( plf, &lfW );
712 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
715 /***********************************************************************
716 * EnumFontFamilies (GDI.330)
718 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
719 FONTENUMPROC16 efproc, LPARAM lpData )
723 lf.lfCharSet = DEFAULT_CHARSET;
724 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
725 else lf.lfFaceName[0] = '\0';
727 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
730 /***********************************************************************
731 * EnumFontFamiliesA (GDI32.@)
733 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
734 FONTENUMPROCA efproc, LPARAM lpData )
738 lf.lfCharSet = DEFAULT_CHARSET;
739 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
740 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
742 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
745 /***********************************************************************
746 * EnumFontFamiliesW (GDI32.@)
748 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
749 FONTENUMPROCW efproc, LPARAM lpData )
753 lf.lfCharSet = DEFAULT_CHARSET;
754 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
755 else lf.lfFaceName[0] = 0;
757 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
760 /***********************************************************************
763 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
766 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
769 /***********************************************************************
770 * EnumFontsA (GDI32.@)
772 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
775 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
778 /***********************************************************************
779 * EnumFontsW (GDI32.@)
781 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
784 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
788 /***********************************************************************
789 * GetTextCharacterExtra (GDI32.@)
791 INT WINAPI GetTextCharacterExtra( HDC hdc )
794 DC *dc = DC_GetDCPtr( hdc );
795 if (!dc) return 0x80000000;
797 GDI_ReleaseObj( hdc );
802 /***********************************************************************
803 * SetTextCharacterExtra (GDI32.@)
805 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
808 DC * dc = DC_GetDCPtr( hdc );
809 if (!dc) return 0x80000000;
810 if (dc->funcs->pSetTextCharacterExtra)
811 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
814 prev = dc->charExtra;
815 dc->charExtra = extra;
817 GDI_ReleaseObj( hdc );
822 /***********************************************************************
823 * SetTextJustification (GDI32.@)
825 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
828 DC * dc = DC_GetDCPtr( hdc );
829 if (!dc) return FALSE;
830 if (dc->funcs->pSetTextJustification)
831 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
834 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
835 if (!extra) breaks = 0;
836 dc->breakTotalExtra = extra;
837 dc->breakCount = breaks;
840 dc->breakExtra = extra / breaks;
841 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
849 GDI_ReleaseObj( hdc );
854 /***********************************************************************
855 * GetTextFaceA (GDI32.@)
857 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
859 INT res = GetTextFaceW(hdc, 0, NULL);
860 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
861 GetTextFaceW( hdc, res, nameW );
865 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
870 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
871 HeapFree( GetProcessHeap(), 0, nameW );
875 /***********************************************************************
876 * GetTextFaceW (GDI32.@)
878 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
883 DC * dc = DC_GetDCPtr( hdc );
887 ret = WineEngGetTextFace(dc->gdiFont, count, name);
888 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
892 lstrcpynW( name, font->logfont.lfFaceName, count );
895 else ret = strlenW(font->logfont.lfFaceName) + 1;
896 GDI_ReleaseObj( dc->hFont );
898 GDI_ReleaseObj( hdc );
903 /***********************************************************************
904 * GetTextExtentPoint32A (GDI32.@)
906 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
911 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
914 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
915 HeapFree( GetProcessHeap(), 0, p );
918 TRACE("(%p %s %d %p): returning %ld x %ld\n",
919 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
924 /***********************************************************************
925 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
927 * Computes width and height of the specified string.
933 BOOL WINAPI GetTextExtentPoint32W(
934 HDC hdc, /* [in] Handle of device context */
935 LPCWSTR str, /* [in] Address of text string */
936 INT count, /* [in] Number of characters in string */
937 LPSIZE size) /* [out] Address of structure for string size */
940 DC * dc = DC_GetDCPtr( hdc );
941 if (!dc) return FALSE;
944 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
945 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
946 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
948 else if(dc->funcs->pGetTextExtentPoint)
949 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
951 GDI_ReleaseObj( hdc );
953 TRACE("(%p %s %d %p): returning %ld x %ld\n",
954 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
958 /***********************************************************************
959 * GetTextExtentPointI [GDI32.@]
961 * Computes width and height of the array of glyph indices.
967 BOOL WINAPI GetTextExtentPointI(
968 HDC hdc, /* [in] Handle of device context */
969 const WORD *indices, /* [in] Address of glyph index array */
970 INT count, /* [in] Number of glyphs in array */
971 LPSIZE size) /* [out] Address of structure for string size */
974 DC * dc = DC_GetDCPtr( hdc );
975 if (!dc) return FALSE;
978 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
979 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
980 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
982 else if(dc->funcs->pGetTextExtentPoint) {
983 FIXME("calling GetTextExtentPoint\n");
984 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
987 GDI_ReleaseObj( hdc );
989 TRACE("(%p %p %d %p): returning %ld x %ld\n",
990 hdc, indices, count, size, size->cx, size->cy );
995 /***********************************************************************
996 * GetTextExtentPointA (GDI32.@)
998 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1001 TRACE("not bug compatible.\n");
1002 return GetTextExtentPoint32A( hdc, str, count, size );
1005 /***********************************************************************
1006 * GetTextExtentPointW (GDI32.@)
1008 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1011 TRACE("not bug compatible.\n");
1012 return GetTextExtentPoint32W( hdc, str, count, size );
1016 /***********************************************************************
1017 * GetTextExtentExPointA (GDI32.@)
1019 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1020 INT maxExt, LPINT lpnFit,
1021 LPINT alpDx, LPSIZE size )
1025 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1026 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1027 HeapFree( GetProcessHeap(), 0, p );
1032 /***********************************************************************
1033 * GetTextExtentExPointW (GDI32.@)
1035 * Return the size of the string as it would be if it was output properly by
1038 * This should include
1039 * - Intercharacter spacing
1040 * - justification spacing (not yet done)
1041 * - kerning? see below
1043 * Kerning. Since kerning would be carried out by the rendering code it should
1044 * be done by the driver. However they don't support it yet. Also I am not
1045 * yet persuaded that (certainly under Win95) any kerning is actually done.
1047 * str: According to MSDN this should be null-terminated. That is not true; a
1048 * null will not terminate it early.
1049 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1050 * than count. I have seen it be either the size of the full string or
1051 * 1 less than the size of the full string. I have not seen it bear any
1052 * resemblance to the portion that would fit.
1053 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1054 * trailing intercharacter spacing and any trailing justification.
1057 * Currently we do this by measuring each character etc. We should do it by
1058 * passing the request to the driver, perhaps by extending the
1059 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1060 * thinking about kerning issues and rounding issues in the justification.
1063 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1064 INT maxExt, LPINT lpnFit,
1065 LPINT alpDx, LPSIZE size )
1067 int index, nFit, extent;
1071 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1073 size->cx = size->cy = nFit = extent = 0;
1074 for(index = 0; index < count; index++)
1076 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1077 /* GetTextExtentPoint includes intercharacter spacing. */
1078 /* FIXME - justification needs doing yet. Remember that the base
1079 * data will not be in logical coordinates.
1082 if( !lpnFit || extent <= maxExt )
1083 /* It is allowed to be equal. */
1086 if( alpDx ) alpDx[index] = extent;
1088 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1092 if(lpnFit) *lpnFit = nFit;
1095 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1101 /***********************************************************************
1102 * GetTextMetricsA (GDI32.@)
1104 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1108 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1109 FONT_TextMetricWToA( &tm32, metrics );
1113 /***********************************************************************
1114 * GetTextMetricsW (GDI32.@)
1116 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1119 DC * dc = DC_GetDCPtr( hdc );
1120 if (!dc) return FALSE;
1123 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1124 else if (dc->funcs->pGetTextMetrics)
1125 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1129 /* device layer returns values in device units
1130 * therefore we have to convert them to logical */
1132 #define WDPTOLP(x) ((x<0)? \
1133 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1134 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1135 #define HDPTOLP(y) ((y<0)? \
1136 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1137 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1139 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1140 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1141 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1142 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1143 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1144 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1145 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1146 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1150 TRACE("text metrics:\n"
1151 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1152 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1153 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1154 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1155 " PitchAndFamily = %02x\n"
1156 " --------------------\n"
1157 " InternalLeading = %li\n"
1161 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1162 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1163 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1164 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1165 metrics->tmPitchAndFamily,
1166 metrics->tmInternalLeading,
1169 metrics->tmHeight );
1171 GDI_ReleaseObj( hdc );
1176 /***********************************************************************
1177 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1180 * lpOTM should be LPOUTLINETEXTMETRIC
1183 * Success: Non-zero or size of required buffer
1186 UINT16 WINAPI GetOutlineTextMetrics16(
1187 HDC16 hdc, /* [in] Handle of device context */
1188 UINT16 cbData, /* [in] Size of metric data array */
1189 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1191 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1196 /***********************************************************************
1197 * GetOutlineTextMetricsA (GDI32.@)
1198 * Gets metrics for TrueType fonts.
1202 * Success: Non-zero or size of required buffer
1205 UINT WINAPI GetOutlineTextMetricsA(
1206 HDC hdc, /* [in] Handle of device context */
1207 UINT cbData, /* [in] Size of metric data array */
1208 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1210 char buf[512], *ptr;
1212 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1215 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1216 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1218 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1219 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1222 needed = sizeof(OUTLINETEXTMETRICA);
1223 if(lpOTMW->otmpFamilyName)
1224 needed += WideCharToMultiByte(CP_ACP, 0,
1225 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1226 NULL, 0, NULL, NULL);
1227 if(lpOTMW->otmpFaceName)
1228 needed += WideCharToMultiByte(CP_ACP, 0,
1229 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1230 NULL, 0, NULL, NULL);
1231 if(lpOTMW->otmpStyleName)
1232 needed += WideCharToMultiByte(CP_ACP, 0,
1233 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1234 NULL, 0, NULL, NULL);
1235 if(lpOTMW->otmpFullName)
1236 needed += WideCharToMultiByte(CP_ACP, 0,
1237 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1238 NULL, 0, NULL, NULL);
1245 if(needed > cbData) {
1251 lpOTM->otmSize = needed;
1252 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1253 lpOTM->otmFiller = 0;
1254 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1255 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1256 lpOTM->otmfsType = lpOTMW->otmfsType;
1257 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1258 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1259 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1260 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1261 lpOTM->otmAscent = lpOTMW->otmAscent;
1262 lpOTM->otmDescent = lpOTMW->otmDescent;
1263 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1264 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1265 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1266 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1267 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1268 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1269 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1270 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1271 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1272 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1273 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1274 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1275 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1276 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1277 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1278 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1281 ptr = (char*)(lpOTM + 1);
1282 left = needed - sizeof(*lpOTM);
1284 if(lpOTMW->otmpFamilyName) {
1285 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1286 len = WideCharToMultiByte(CP_ACP, 0,
1287 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1288 ptr, left, NULL, NULL);
1292 lpOTM->otmpFamilyName = 0;
1294 if(lpOTMW->otmpFaceName) {
1295 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1296 len = WideCharToMultiByte(CP_ACP, 0,
1297 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1298 ptr, left, NULL, NULL);
1302 lpOTM->otmpFaceName = 0;
1304 if(lpOTMW->otmpStyleName) {
1305 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1306 len = WideCharToMultiByte(CP_ACP, 0,
1307 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1308 ptr, left, NULL, NULL);
1312 lpOTM->otmpStyleName = 0;
1314 if(lpOTMW->otmpFullName) {
1315 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1316 len = WideCharToMultiByte(CP_ACP, 0,
1317 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1318 ptr, left, NULL, NULL);
1321 lpOTM->otmpFullName = 0;
1328 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1329 HeapFree(GetProcessHeap(), 0, lpOTMW);
1335 /***********************************************************************
1336 * GetOutlineTextMetricsW [GDI32.@]
1338 UINT WINAPI GetOutlineTextMetricsW(
1339 HDC hdc, /* [in] Handle of device context */
1340 UINT cbData, /* [in] Size of metric data array */
1341 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1343 DC *dc = DC_GetDCPtr( hdc );
1346 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1350 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1351 if(ret && ret <= cbData) {
1352 #define WDPTOLP(x) ((x<0)? \
1353 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1354 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1355 #define HDPTOLP(y) ((y<0)? \
1356 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1357 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1359 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1360 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1361 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1362 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1363 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1364 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1365 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1366 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1367 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1368 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1369 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1370 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1371 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1372 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1373 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1374 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1375 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1376 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1377 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1378 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1379 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1380 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1381 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1382 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1383 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1384 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1385 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1386 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1387 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1388 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1389 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1390 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1396 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1397 but really this should just be a return 0. */
1399 ret = sizeof(*lpOTM);
1404 memset(lpOTM, 0, ret);
1405 lpOTM->otmSize = sizeof(*lpOTM);
1406 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1408 Further fill of the structure not implemented,
1409 Needs real values for the structure members
1414 GDI_ReleaseObj(hdc);
1419 /***********************************************************************
1420 * GetCharWidthW (GDI32.@)
1421 * GetCharWidth32W (GDI32.@)
1423 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1428 DC * dc = DC_GetDCPtr( hdc );
1429 if (!dc) return FALSE;
1432 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1433 else if (dc->funcs->pGetCharWidth)
1434 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1438 /* convert device units to logical */
1440 extra = dc->vportExtX >> 1;
1441 for( i = firstChar; i <= lastChar; i++, buffer++ )
1442 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1445 GDI_ReleaseObj( hdc );
1450 /***********************************************************************
1451 * GetCharWidthA (GDI32.@)
1452 * GetCharWidth32A (GDI32.@)
1454 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1457 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1462 if(count <= 0) return FALSE;
1464 str = HeapAlloc(GetProcessHeap(), 0, count);
1465 for(i = 0; i < count; i++)
1466 str[i] = (BYTE)(firstChar + i);
1468 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1470 for(i = 0; i < wlen; i++)
1472 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1480 HeapFree(GetProcessHeap(), 0, str);
1481 HeapFree(GetProcessHeap(), 0, wstr);
1487 /* FIXME: all following APIs ******************************************/
1490 /***********************************************************************
1491 * SetMapperFlags (GDI32.@)
1493 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1495 DC *dc = DC_GetDCPtr( hDC );
1498 if(dc->funcs->pSetMapperFlags)
1499 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1501 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1502 GDI_ReleaseObj( hDC );
1506 /***********************************************************************
1507 * GetAspectRatioFilterEx (GDI.486)
1509 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1511 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1515 /***********************************************************************
1516 * GetAspectRatioFilterEx (GDI32.@)
1518 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1520 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1525 /***********************************************************************
1526 * GetCharABCWidthsA (GDI32.@)
1528 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1531 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1536 if(count <= 0) return FALSE;
1538 str = HeapAlloc(GetProcessHeap(), 0, count);
1539 for(i = 0; i < count; i++)
1540 str[i] = (BYTE)(firstChar + i);
1542 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1544 for(i = 0; i < wlen; i++)
1546 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1554 HeapFree(GetProcessHeap(), 0, str);
1555 HeapFree(GetProcessHeap(), 0, wstr);
1561 /******************************************************************************
1562 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1565 * hdc [I] Handle of device context
1566 * firstChar [I] First character in range to query
1567 * lastChar [I] Last character in range to query
1568 * abc [O] Address of character-width structure
1571 * Only works with TrueType fonts
1577 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1580 DC *dc = DC_GetDCPtr(hdc);
1586 for (i=firstChar;i<=lastChar;i++) {
1587 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1588 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1589 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1590 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1594 GDI_ReleaseObj(hdc);
1599 /***********************************************************************
1600 * GetGlyphOutline (GDI.309)
1602 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1603 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1604 LPVOID lpBuffer, const MAT2 *lpmat2 )
1606 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1607 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1608 return (DWORD)-1; /* failure */
1612 /***********************************************************************
1613 * GetGlyphOutlineA (GDI32.@)
1615 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1616 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1617 LPVOID lpBuffer, const MAT2 *lpmat2 )
1623 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1624 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1628 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1631 HeapFree(GetProcessHeap(), 0, p);
1635 /***********************************************************************
1636 * GetGlyphOutlineW (GDI32.@)
1638 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1639 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1640 LPVOID lpBuffer, const MAT2 *lpmat2 )
1642 DC *dc = DC_GetDCPtr(hdc);
1645 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1646 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1648 if(!dc) return GDI_ERROR;
1651 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1652 cbBuffer, lpBuffer, lpmat2);
1656 GDI_ReleaseObj(hdc);
1661 /***********************************************************************
1662 * CreateScalableFontResourceA (GDI32.@)
1664 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1665 LPCSTR lpszResourceFile,
1666 LPCSTR lpszFontFile,
1667 LPCSTR lpszCurrentPath )
1671 /* fHidden=1 - only visible for the calling app, read-only, not
1672 * enumbered with EnumFonts/EnumFontFamilies
1673 * lpszCurrentPath can be NULL
1675 FIXME("(%ld,%s,%s,%s): stub\n",
1676 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1677 debugstr_a(lpszCurrentPath) );
1679 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1680 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1682 SetLastError(ERROR_FILE_EXISTS);
1685 return FALSE; /* create failed */
1688 /***********************************************************************
1689 * CreateScalableFontResourceW (GDI32.@)
1691 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1692 LPCWSTR lpszResourceFile,
1693 LPCWSTR lpszFontFile,
1694 LPCWSTR lpszCurrentPath )
1696 FIXME("(%ld,%p,%p,%p): stub\n",
1697 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1698 return FALSE; /* create failed */
1702 /*************************************************************************
1703 * GetRasterizerCaps (GDI32.@)
1705 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1707 lprs->nSize = sizeof(RASTERIZER_STATUS);
1708 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1709 lprs->nLanguageID = 0;
1714 /*************************************************************************
1715 * GetKerningPairsA (GDI32.@)
1717 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1718 LPKERNINGPAIR lpKerningPairs )
1720 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1724 /*************************************************************************
1725 * GetKerningPairsW (GDI32.@)
1727 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1728 LPKERNINGPAIR lpKerningPairs )
1731 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1732 for (i = 0; i < cPairs; i++)
1733 lpKerningPairs[i].iKernAmount = 0;
1737 /*************************************************************************
1738 * TranslateCharsetInfo [GDI32.@]
1740 * Fills a CHARSETINFO structure for a character set, code page, or
1741 * font. This allows making the correspondance between different labelings
1742 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1743 * of the same encoding.
1745 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1746 * only one codepage should be set in *lpSrc.
1749 * TRUE on success, FALSE on failure.
1752 BOOL WINAPI TranslateCharsetInfo(
1753 LPDWORD lpSrc, /* [in]
1754 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1755 if flags == TCI_SRCCHARSET: a character set value
1756 if flags == TCI_SRCCODEPAGE: a code page value
1758 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1759 DWORD flags /* [in] determines interpretation of lpSrc */
1763 case TCI_SRCFONTSIG:
1764 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1766 case TCI_SRCCODEPAGE:
1767 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1769 case TCI_SRCCHARSET:
1770 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1775 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1776 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1780 /*************************************************************************
1781 * GetFontLanguageInfo (GDI32.@)
1783 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1785 FONTSIGNATURE fontsig;
1786 static const DWORD GCP_DBCS_MASK=0x003F0000,
1787 GCP_DIACRITIC_MASK=0x00000000,
1788 FLI_GLYPHS_MASK=0x00000000,
1789 GCP_GLYPHSHAPE_MASK=0x00000040,
1790 GCP_KASHIDA_MASK=0x00000000,
1791 GCP_LIGATE_MASK=0x00000000,
1792 GCP_USEKERNING_MASK=0x00000000,
1793 GCP_REORDER_MASK=0x00000060;
1797 GetTextCharsetInfo( hdc, &fontsig, 0 );
1798 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1800 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1803 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1804 result|=GCP_DIACRITIC;
1806 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1809 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1810 result|=GCP_GLYPHSHAPE;
1812 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1813 result|=GCP_KASHIDA;
1815 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1818 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1819 result|=GCP_USEKERNING;
1821 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1822 result|=GCP_REORDER;
1828 /*************************************************************************
1829 * GetFontData [GDI32.@] Retrieve data for TrueType font
1833 * success: Number of bytes returned
1834 * failure: GDI_ERROR
1838 * Calls SetLastError()
1841 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1842 LPVOID buffer, DWORD length)
1844 DC *dc = DC_GetDCPtr(hdc);
1845 DWORD ret = GDI_ERROR;
1847 if(!dc) return GDI_ERROR;
1850 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1852 GDI_ReleaseObj(hdc);
1856 /*************************************************************************
1857 * GetGlyphIndicesA [GDI32.@]
1859 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1860 LPWORD pgi, DWORD flags)
1866 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1867 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1869 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1870 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1871 HeapFree(GetProcessHeap(), 0, lpstrW);
1876 /*************************************************************************
1877 * GetGlyphIndicesW [GDI32.@]
1879 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1880 LPWORD pgi, DWORD flags)
1882 DC *dc = DC_GetDCPtr(hdc);
1883 DWORD ret = GDI_ERROR;
1885 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1886 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1888 if(!dc) return GDI_ERROR;
1891 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1893 GDI_ReleaseObj(hdc);
1897 /*************************************************************************
1898 * GetCharacterPlacementA [GDI32.@]
1901 * the web browser control of ie4 calls this with dwFlags=0
1904 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1905 INT nMaxExtent, GCP_RESULTSA *lpResults,
1910 GCP_RESULTSW resultsW;
1914 TRACE("%s, %d, %d, 0x%08lx\n",
1915 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1917 /* both structs are equal in size */
1918 memcpy(&resultsW, lpResults, sizeof(resultsW));
1920 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1921 if(lpResults->lpOutString)
1922 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1924 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1926 if(lpResults->lpOutString) {
1927 if(font_cp != CP_SYMBOL)
1928 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1929 lpResults->lpOutString, uCount, NULL, NULL );
1931 for(i = 0; i < uCount; i++)
1932 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1935 HeapFree(GetProcessHeap(), 0, lpStringW);
1936 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1941 /*************************************************************************
1942 * GetCharacterPlacementW [GDI32.@]
1944 * Retrieve information about a string. This includes the width, reordering,
1945 * Glyphing and so on.
1949 * The width and height of the string if successful, 0 if failed.
1953 * All flags except GCP_REORDER are not yet implemented.
1954 * Reordering is not 100% complient to the Windows BiDi method.
1955 * Caret positioning is not yet implemented.
1956 * Classes are not yet implemented.
1960 GetCharacterPlacementW(
1961 HDC hdc, /* [in] Device context for which the rendering is to be done */
1962 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1963 INT uCount, /* [in] Number of WORDS in string. */
1964 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1965 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1966 DWORD dwFlags /* [in] Flags specifying how to process the string */
1973 TRACE("%s, %d, %d, 0x%08lx\n",
1974 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1976 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1977 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1978 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1979 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1980 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1982 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1983 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1984 if(lpResults->lpClass) FIXME("classes not implemented\n");
1986 nSet = (UINT)uCount;
1987 if(nSet > lpResults->nGlyphs)
1988 nSet = lpResults->nGlyphs;
1990 /* return number of initialized fields */
1991 lpResults->nGlyphs = nSet;
1993 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1995 /* Treat the case where no special handling was requested in a fastpath way */
1996 /* copy will do if the GCP_REORDER flag is not set */
1997 if(lpResults->lpOutString)
1998 strncpyW( lpResults->lpOutString, lpString, nSet );
2000 if(lpResults->lpOrder)
2002 for(i = 0; i < nSet; i++)
2003 lpResults->lpOrder[i] = i;
2007 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2008 nSet, lpResults->lpOrder );
2011 /* FIXME: Will use the placement chars */
2012 if (lpResults->lpDx)
2015 for (i = 0; i < nSet; i++)
2017 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2018 lpResults->lpDx[i]= c;
2022 if(lpResults->lpGlyphs)
2023 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2025 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2026 ret = MAKELONG(size.cx, size.cy);
2031 /*************************************************************************
2032 * GetCharABCWidthsFloatA [GDI32.@]
2034 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2037 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2041 /*************************************************************************
2042 * GetCharABCWidthsFloatW [GDI32.@]
2044 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2045 UINT iLastChar, LPABCFLOAT lpABCF)
2047 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2051 /*************************************************************************
2052 * GetCharWidthFloatA [GDI32.@]
2054 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2055 UINT iLastChar, PFLOAT pxBuffer)
2057 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2061 /*************************************************************************
2062 * GetCharWidthFloatW [GDI32.@]
2064 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2065 UINT iLastChar, PFLOAT pxBuffer)
2067 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2072 /***********************************************************************
2074 * Font Resource API *
2076 ***********************************************************************/
2078 /***********************************************************************
2079 * AddFontResourceA (GDI32.@)
2081 INT WINAPI AddFontResourceA( LPCSTR str )
2083 return AddFontResourceExA( str, 0, NULL);
2086 /***********************************************************************
2087 * AddFontResourceW (GDI32.@)
2089 INT WINAPI AddFontResourceW( LPCWSTR str )
2091 return AddFontResourceExW(str, 0, NULL);
2095 /***********************************************************************
2096 * AddFontResourceExA (GDI32.@)
2098 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2100 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2101 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2104 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2105 ret = AddFontResourceExW(strW, fl, pdv);
2106 HeapFree(GetProcessHeap(), 0, strW);
2110 /***********************************************************************
2111 * AddFontResourceExW (GDI32.@)
2113 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2115 return WineEngAddFontResourceEx(str, fl, pdv);
2118 /***********************************************************************
2119 * RemoveFontResourceA (GDI32.@)
2121 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2123 return RemoveFontResourceExA(str, 0, 0);
2126 /***********************************************************************
2127 * RemoveFontResourceW (GDI32.@)
2129 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2131 return RemoveFontResourceExW(str, 0, 0);
2134 /***********************************************************************
2135 * RemoveFontResourceExA (GDI32.@)
2137 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2139 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2140 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2143 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2144 ret = RemoveFontResourceExW(strW, fl, pdv);
2145 HeapFree(GetProcessHeap(), 0, strW);
2149 /***********************************************************************
2150 * RemoveFontResourceExW (GDI32.@)
2152 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2154 return WineEngRemoveFontResourceEx(str, fl, pdv);
2157 /***********************************************************************
2158 * GetTextCharset (GDI32.@)
2160 UINT WINAPI GetTextCharset(HDC hdc)
2162 /* MSDN docs say this is equivalent */
2163 return GetTextCharsetInfo(hdc, NULL, 0);
2166 /***********************************************************************
2167 * GetTextCharsetInfo (GDI32.@)
2169 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2171 UINT ret = DEFAULT_CHARSET;
2172 DC *dc = DC_GetDCPtr(hdc);
2177 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2179 GDI_ReleaseObj(hdc);
2182 if (ret == DEFAULT_CHARSET && fs)
2183 memset(fs, 0, sizeof(FONTSIGNATURE));