Some broken games do not put the TEXTURE flags in the surface caps.
[wine/multimedia.git] / objects / font.c
blobd0063aa54a88fb3acd7db41db3fe6f5e0a1e98fe
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
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
23 #include "config.h"
24 #include "wine/port.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include "winerror.h"
30 #include "winnls.h"
31 #include "wownt32.h"
32 #include "gdi.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
58 typedef struct
60 GDIOBJHDR header;
61 LOGFONTW logfont;
62 } FONTOBJ;
64 typedef struct
66 LPLOGFONT16 lpLogFontParam;
67 FONTENUMPROC16 lpEnumFunc;
68 LPARAM lpData;
70 LPNEWTEXTMETRICEX16 lpTextMetric;
71 LPENUMLOGFONTEX16 lpLogFont;
72 SEGPTR segTextMetric;
73 SEGPTR segLogFont;
74 DWORD dwFlags;
75 HDC hdc;
76 DC *dc;
77 PHYSDEV physDev;
78 } fontEnum16;
80 typedef struct
82 LPLOGFONTW lpLogFontParam;
83 FONTENUMPROCW lpEnumFunc;
84 LPARAM lpData;
85 DWORD dwFlags;
86 HDC hdc;
87 DC *dc;
88 PHYSDEV physDev;
89 } fontEnum32;
92 * For TranslateCharsetInfo
94 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
95 #define MAXTCIINDEX 32
96 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
97 /* ANSI */
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)},
115 /* ANSI and OEM */
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,
182 LF_FACESIZE);
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 )
294 LOGFONTW lfW;
296 if (plfA) {
297 FONT_LogFontAToW( plfA, &lfW );
298 return CreateFontIndirectW( &lfW );
299 } else
300 return CreateFontIndirectW( NULL );
304 /***********************************************************************
305 * CreateFontIndirectW (GDI32.@)
307 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
309 HFONT hFont = 0;
311 if (plf)
313 FONTOBJ* fontPtr;
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");
341 return hFont;
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 )
353 LOGFONTA logfont;
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;
369 if (name)
370 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
371 else
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 )
386 LOGFONTW logfont;
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;
402 if (name)
403 lstrcpynW(logfont.lfFaceName, name,
404 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
405 else
406 logfont.lfFaceName[0] = '\0';
408 return CreateFontIndirectW( &logfont );
412 /***********************************************************************
413 * FONT_SelectObject
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
421 * font.
423 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
425 HGDIOBJ ret = 0;
426 DC *dc = DC_GetDCPtr( hdc );
428 if (!dc) return 0;
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 */
442 else
444 ret = dc->hFont;
445 dc->hFont = handle;
447 GDI_ReleaseObj( hdc );
448 return ret;
452 /***********************************************************************
453 * FONT_GetObject16
455 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
457 FONTOBJ *font = obj;
458 LOGFONT16 lf16;
460 FONT_LogFontWTo16( &font->logfont, &lf16 );
462 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
463 memcpy( buffer, &lf16, count );
464 return count;
467 /***********************************************************************
468 * FONT_GetObjectA
470 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
472 FONTOBJ *font = obj;
473 LOGFONTA lfA;
475 FONT_LogFontWToA( &font->logfont, &lfA );
477 if (count > sizeof(lfA)) count = sizeof(lfA);
478 if(buffer)
479 memcpy( buffer, &lfA, count );
480 return count;
483 /***********************************************************************
484 * FONT_GetObjectW
486 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
488 FONTOBJ *font = obj;
489 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
490 if(buffer)
491 memcpy( buffer, &font->logfont, count );
492 return count;
496 /***********************************************************************
497 * FONT_DeleteObject
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;
516 INT ret = 1;
517 DC *dc;
519 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
520 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
522 WORD args[7];
523 DWORD result;
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);
534 args[2] = fType;
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 */
546 ret = 0;
549 return ret;
552 /***********************************************************************
553 * FONT_EnumInstance
555 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
556 DWORD fType, LPARAM lp )
558 fontEnum32 *pfe = (fontEnum32*)lp;
559 INT ret = 1;
560 DC *dc;
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 */
588 ret = 0;
591 return ret;
594 /***********************************************************************
595 * EnumFontFamiliesEx (GDI.613)
597 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
598 FONTENUMPROC16 efproc, LPARAM lParam,
599 DWORD dwFlags)
601 fontEnum16 fe16;
602 INT16 ret = 1, ret2;
603 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
604 NEWTEXTMETRICEX16 tm16;
605 ENUMLOGFONTEX16 lf16;
606 LOGFONTW lfW;
607 BOOL enum_gdi_fonts;
609 if (!dc) return 0;
610 FONT_LogFont16ToW(plf, &lfW);
612 fe16.hdc = HDC_32(hDC);
613 fe16.dc = dc;
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 );
622 fe16.dwFlags = 0;
624 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
626 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
628 ret = 0;
629 goto done;
632 if (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 */
638 ret = ret2;
640 done:
641 UnMapLS( fe16.segTextMetric );
642 UnMapLS( fe16.segLogFont );
643 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
644 return ret;
647 /***********************************************************************
648 * FONT_EnumFontFamiliesEx
650 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
651 FONTENUMPROCW efproc,
652 LPARAM lParam, DWORD dwUnicode)
654 INT ret = 1, ret2;
655 DC *dc = DC_GetDCPtr( hDC );
656 fontEnum32 fe32;
657 BOOL enum_gdi_fonts;
659 if (!dc) return 0;
661 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
662 plf->lfCharSet);
663 fe32.lpLogFontParam = plf;
664 fe32.lpEnumFunc = efproc;
665 fe32.lpData = lParam;
666 fe32.dwFlags = dwUnicode;
667 fe32.hdc = hDC;
668 fe32.dc = dc;
669 fe32.physDev = dc->physDev;
671 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
673 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
675 ret = 0;
676 goto done;
679 if (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 */
685 ret = ret2;
687 done:
688 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
689 return ret;
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)
709 LOGFONTW lfW;
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 )
721 LOGFONT16 lf;
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 )
736 LOGFONTA lf;
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 )
751 LOGFONTW lf;
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 /***********************************************************************
761 * EnumFonts (GDI.70)
763 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
764 LPARAM lpData )
766 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
769 /***********************************************************************
770 * EnumFontsA (GDI32.@)
772 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
773 LPARAM lpData )
775 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
778 /***********************************************************************
779 * EnumFontsW (GDI32.@)
781 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
782 LPARAM lpData )
784 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
788 /***********************************************************************
789 * GetTextCharacterExtra (GDI32.@)
791 INT WINAPI GetTextCharacterExtra( HDC hdc )
793 INT ret;
794 DC *dc = DC_GetDCPtr( hdc );
795 if (!dc) return 0x80000000;
796 ret = dc->charExtra;
797 GDI_ReleaseObj( hdc );
798 return ret;
802 /***********************************************************************
803 * SetTextCharacterExtra (GDI32.@)
805 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
807 INT prev;
808 DC * dc = DC_GetDCPtr( hdc );
809 if (!dc) return 0x80000000;
810 if (dc->funcs->pSetTextCharacterExtra)
811 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
812 else
814 prev = dc->charExtra;
815 dc->charExtra = extra;
817 GDI_ReleaseObj( hdc );
818 return prev;
822 /***********************************************************************
823 * SetTextJustification (GDI32.@)
825 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
827 BOOL ret = TRUE;
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 );
832 else
834 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
835 if (!extra) breaks = 0;
836 dc->breakTotalExtra = extra;
837 dc->breakCount = breaks;
838 if (breaks)
840 dc->breakExtra = extra / breaks;
841 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
843 else
845 dc->breakExtra = 0;
846 dc->breakRem = 0;
849 GDI_ReleaseObj( hdc );
850 return ret;
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 );
863 if (name)
865 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
866 name[count-1] = 0;
867 res = strlen(name);
869 else
870 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
871 HeapFree( GetProcessHeap(), 0, nameW );
872 return res;
875 /***********************************************************************
876 * GetTextFaceW (GDI32.@)
878 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
880 FONTOBJ *font;
881 INT ret = 0;
883 DC * dc = DC_GetDCPtr( hdc );
884 if (!dc) return 0;
886 if(dc->gdiFont)
887 ret = WineEngGetTextFace(dc->gdiFont, count, name);
888 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
890 if (name)
892 lstrcpynW( name, font->logfont.lfFaceName, count );
893 ret = strlenW(name);
895 else ret = strlenW(font->logfont.lfFaceName) + 1;
896 GDI_ReleaseObj( dc->hFont );
898 GDI_ReleaseObj( hdc );
899 return ret;
903 /***********************************************************************
904 * GetTextExtentPoint32A (GDI32.@)
906 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
907 LPSIZE size )
909 BOOL ret = FALSE;
910 INT wlen;
911 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
913 if (p) {
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 );
920 return ret;
924 /***********************************************************************
925 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
927 * Computes width and height of the specified string.
929 * RETURNS
930 * Success: TRUE
931 * Failure: FALSE
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 */
939 BOOL ret = FALSE;
940 DC * dc = DC_GetDCPtr( hdc );
941 if (!dc) return FALSE;
943 if(dc->gdiFont) {
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 );
955 return ret;
958 /***********************************************************************
959 * GetTextExtentPointI [GDI32.@]
961 * Computes width and height of the array of glyph indices.
963 * RETURNS
964 * Success: TRUE
965 * Failure: FALSE
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 */
973 BOOL ret = FALSE;
974 DC * dc = DC_GetDCPtr( hdc );
975 if (!dc) return FALSE;
977 if(dc->gdiFont) {
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 );
991 return ret;
995 /***********************************************************************
996 * GetTextExtentPointA (GDI32.@)
998 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
999 LPSIZE size )
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,
1009 LPSIZE size )
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 )
1023 BOOL ret;
1024 INT wlen;
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 );
1028 return ret;
1032 /***********************************************************************
1033 * GetTextExtentExPointW (GDI32.@)
1035 * Return the size of the string as it would be if it was output properly by
1036 * e.g. TextOut.
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.
1056 * FIXME
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;
1068 SIZE tSize;
1069 BOOL ret = FALSE;
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.
1081 extent += tSize.cx;
1082 if( !lpnFit || extent <= maxExt )
1083 /* It is allowed to be equal. */
1085 nFit++;
1086 if( alpDx ) alpDx[index] = extent;
1088 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1089 str++;
1091 size->cx = extent;
1092 if(lpnFit) *lpnFit = nFit;
1093 ret = TRUE;
1095 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1097 done:
1098 return ret;
1101 /***********************************************************************
1102 * GetTextMetricsA (GDI32.@)
1104 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1106 TEXTMETRICW tm32;
1108 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1109 FONT_TextMetricWToA( &tm32, metrics );
1110 return TRUE;
1113 /***********************************************************************
1114 * GetTextMetricsW (GDI32.@)
1116 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1118 BOOL ret = FALSE;
1119 DC * dc = DC_GetDCPtr( hdc );
1120 if (!dc) return FALSE;
1122 if (dc->gdiFont)
1123 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1124 else if (dc->funcs->pGetTextMetrics)
1125 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1127 if (ret)
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);
1147 ret = TRUE;
1148 #undef WDPTOLP
1149 #undef HDPTOLP
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"
1158 " Ascent = %li\n"
1159 " Descent = %li\n"
1160 " Height = %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,
1167 metrics->tmAscent,
1168 metrics->tmDescent,
1169 metrics->tmHeight );
1171 GDI_ReleaseObj( hdc );
1172 return ret;
1176 /***********************************************************************
1177 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1179 * NOTES
1180 * lpOTM should be LPOUTLINETEXTMETRIC
1182 * RETURNS
1183 * Success: Non-zero or size of required buffer
1184 * Failure: 0
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);
1192 return 0;
1196 /***********************************************************************
1197 * GetOutlineTextMetricsA (GDI32.@)
1198 * Gets metrics for TrueType fonts.
1201 * RETURNS
1202 * Success: Non-zero or size of required buffer
1203 * Failure: 0
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;
1211 UINT ret, needed;
1212 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1213 INT left, len;
1215 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1216 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1217 return 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);
1240 if(!lpOTM) {
1241 ret = needed;
1242 goto end;
1245 if(needed > cbData) {
1246 ret = 0;
1247 goto end;
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);
1289 left -= len;
1290 ptr += len;
1291 } else
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);
1299 left -= len;
1300 ptr += len;
1301 } else
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);
1309 left -= len;
1310 ptr += len;
1311 } else
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);
1319 left -= len;
1320 } else
1321 lpOTM->otmpFullName = 0;
1323 assert(left == 0);
1325 ret = needed;
1327 end:
1328 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1329 HeapFree(GetProcessHeap(), 0, lpOTMW);
1331 return ret;
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 );
1344 UINT ret;
1346 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1347 if(!dc) return 0;
1349 if(dc->gdiFont) {
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);
1391 #undef WDPTOLP
1392 #undef HDPTOLP
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);
1400 if (lpOTM) {
1401 if(cbData < ret)
1402 ret = 0;
1403 else {
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);
1415 return ret;
1419 /***********************************************************************
1420 * GetCharWidthW (GDI32.@)
1421 * GetCharWidth32W (GDI32.@)
1423 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1424 LPINT buffer )
1426 UINT i, extra;
1427 BOOL ret = FALSE;
1428 DC * dc = DC_GetDCPtr( hdc );
1429 if (!dc) return FALSE;
1431 if (dc->gdiFont)
1432 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1433 else if (dc->funcs->pGetCharWidth)
1434 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1436 if (ret)
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;
1443 ret = TRUE;
1445 GDI_ReleaseObj( hdc );
1446 return ret;
1450 /***********************************************************************
1451 * GetCharWidthA (GDI32.@)
1452 * GetCharWidth32A (GDI32.@)
1454 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1455 LPINT buffer )
1457 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1458 LPSTR str;
1459 LPWSTR wstr;
1460 BOOL ret = TRUE;
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))
1474 ret = FALSE;
1475 break;
1477 buffer++;
1480 HeapFree(GetProcessHeap(), 0, str);
1481 HeapFree(GetProcessHeap(), 0, wstr);
1483 return ret;
1487 /* FIXME: all following APIs ******************************************/
1490 /***********************************************************************
1491 * SetMapperFlags (GDI32.@)
1493 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1495 DC *dc = DC_GetDCPtr( hDC );
1496 DWORD ret = 0;
1497 if(!dc) return 0;
1498 if(dc->funcs->pSetMapperFlags)
1499 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1500 else
1501 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1502 GDI_ReleaseObj( hDC );
1503 return ret;
1506 /***********************************************************************
1507 * GetAspectRatioFilterEx (GDI.486)
1509 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1511 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1512 return FALSE;
1515 /***********************************************************************
1516 * GetAspectRatioFilterEx (GDI32.@)
1518 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1520 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1521 return FALSE;
1525 /***********************************************************************
1526 * GetCharABCWidthsA (GDI32.@)
1528 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1529 LPABC abc )
1531 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1532 LPSTR str;
1533 LPWSTR wstr;
1534 BOOL ret = TRUE;
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))
1548 ret = FALSE;
1549 break;
1551 abc++;
1554 HeapFree(GetProcessHeap(), 0, str);
1555 HeapFree(GetProcessHeap(), 0, wstr);
1557 return ret;
1561 /******************************************************************************
1562 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1564 * PARAMS
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
1570 * NOTES
1571 * Only works with TrueType fonts
1573 * RETURNS
1574 * Success: TRUE
1575 * Failure: FALSE
1577 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1578 LPABC abc )
1580 DC *dc = DC_GetDCPtr(hdc);
1581 int i;
1582 GLYPHMETRICS gm;
1583 BOOL ret = FALSE;
1585 if(dc->gdiFont) {
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;
1592 ret = TRUE;
1594 GDI_ReleaseObj(hdc);
1595 return ret;
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 )
1619 LPWSTR p = NULL;
1620 DWORD ret;
1621 UINT c;
1623 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1624 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1625 c = p[0];
1626 } else
1627 c = uChar;
1628 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1629 lpmat2);
1630 if(p)
1631 HeapFree(GetProcessHeap(), 0, p);
1632 return ret;
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);
1643 DWORD ret;
1645 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1646 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1648 if(!dc) return GDI_ERROR;
1650 if(dc->gdiFont)
1651 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1652 cbBuffer, lpBuffer, lpmat2);
1653 else
1654 ret = GDI_ERROR;
1656 GDI_ReleaseObj(hdc);
1657 return ret;
1661 /***********************************************************************
1662 * CreateScalableFontResourceA (GDI32.@)
1664 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1665 LPCSTR lpszResourceFile,
1666 LPCSTR lpszFontFile,
1667 LPCSTR lpszCurrentPath )
1669 HANDLE f;
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) {
1681 CloseHandle(f);
1682 SetLastError(ERROR_FILE_EXISTS);
1683 return FALSE;
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;
1710 return TRUE;
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 )
1730 int i;
1731 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1732 for (i = 0; i < cPairs; i++)
1733 lpKerningPairs[i].iKernAmount = 0;
1734 return 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.
1748 * RETURNS
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 */
1761 int index = 0;
1762 switch (flags) {
1763 case TCI_SRCFONTSIG:
1764 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1765 break;
1766 case TCI_SRCCODEPAGE:
1767 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1768 break;
1769 case TCI_SRCCHARSET:
1770 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1771 break;
1772 default:
1773 return FALSE;
1775 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1776 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1777 return TRUE;
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;
1795 DWORD result=0;
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 )
1801 result|=GCP_DBCS;
1803 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1804 result|=GCP_DIACRITIC;
1806 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1807 result|=FLI_GLYPHS;
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 )
1816 result|=GCP_LIGATE;
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;
1824 return result;
1828 /*************************************************************************
1829 * GetFontData [GDI32.@] Retrieve data for TrueType font
1831 * RETURNS
1833 * success: Number of bytes returned
1834 * failure: GDI_ERROR
1836 * NOTES
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;
1849 if(dc->gdiFont)
1850 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1852 GDI_ReleaseObj(hdc);
1853 return ret;
1856 /*************************************************************************
1857 * GetGlyphIndicesA [GDI32.@]
1859 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1860 LPWORD pgi, DWORD flags)
1862 DWORD ret;
1863 WCHAR *lpstrW;
1864 INT countW;
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);
1873 return ret;
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;
1890 if(dc->gdiFont)
1891 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1893 GDI_ReleaseObj(hdc);
1894 return ret;
1897 /*************************************************************************
1898 * GetCharacterPlacementA [GDI32.@]
1900 * NOTES:
1901 * the web browser control of ie4 calls this with dwFlags=0
1903 DWORD WINAPI
1904 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1905 INT nMaxExtent, GCP_RESULTSA *lpResults,
1906 DWORD dwFlags)
1908 WCHAR *lpStringW;
1909 INT uCountW, i;
1910 GCP_RESULTSW resultsW;
1911 DWORD ret;
1912 UINT font_cp;
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 );
1930 else
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);
1938 return ret;
1941 /*************************************************************************
1942 * GetCharacterPlacementW [GDI32.@]
1944 * Retrieve information about a string. This includes the width, reordering,
1945 * Glyphing and so on.
1947 * RETURNS
1949 * The width and height of the string if successful, 0 if failed.
1951 * BUGS
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.
1959 DWORD WINAPI
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 */
1969 DWORD ret=0;
1970 SIZE size;
1971 UINT i, nSet;
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;
2005 } else
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)
2014 int c;
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);
2028 return ret;
2031 /*************************************************************************
2032 * GetCharABCWidthsFloatA [GDI32.@]
2034 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2035 LPABCFLOAT lpABCF)
2037 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2038 return 0;
2041 /*************************************************************************
2042 * GetCharABCWidthsFloatW [GDI32.@]
2044 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2045 UINT iLastChar, LPABCFLOAT lpABCF)
2047 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2048 return 0;
2051 /*************************************************************************
2052 * GetCharWidthFloatA [GDI32.@]
2054 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2055 UINT iLastChar, PFLOAT pxBuffer)
2057 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2058 return 0;
2061 /*************************************************************************
2062 * GetCharWidthFloatW [GDI32.@]
2064 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2065 UINT iLastChar, PFLOAT pxBuffer)
2067 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2068 return 0;
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));
2102 INT ret;
2104 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2105 ret = AddFontResourceExW(strW, fl, pdv);
2106 HeapFree(GetProcessHeap(), 0, strW);
2107 return ret;
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));
2141 INT ret;
2143 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2144 ret = RemoveFontResourceExW(strW, fl, pdv);
2145 HeapFree(GetProcessHeap(), 0, strW);
2146 return ret;
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);
2174 if (!dc) goto done;
2176 if (dc->gdiFont)
2177 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2179 GDI_ReleaseObj(hdc);
2181 done:
2182 if (ret == DEFAULT_CHARSET && fs)
2183 memset(fs, 0, sizeof(FONTSIGNATURE));
2184 return ret;