Ownerdraw buttons should erase themselves in WM_ERASEBKGND.
[wine.git] / objects / font.c
blob2587f979e137755dee03a8b32f2e3687ad83b018
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 <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <assert.h>
30 #include "winerror.h"
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34 #include "wownt32.h"
35 #include "gdi.h"
36 #include "wine/unicode.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(font);
40 WINE_DECLARE_DEBUG_CHANNEL(gdi);
42 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
43 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
44 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
45 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
46 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
48 static const struct gdi_obj_funcs font_funcs =
50 FONT_SelectObject, /* pSelectObject */
51 FONT_GetObject16, /* pGetObject16 */
52 FONT_GetObjectA, /* pGetObjectA */
53 FONT_GetObjectW, /* pGetObjectW */
54 NULL, /* pUnrealizeObject */
55 FONT_DeleteObject /* pDeleteObject */
58 #define ENUM_UNICODE 0x00000001
59 #define ENUM_CALLED 0x00000002
61 typedef struct
63 GDIOBJHDR header;
64 LOGFONTW logfont;
65 } FONTOBJ;
67 typedef struct
69 LPLOGFONT16 lpLogFontParam;
70 FONTENUMPROC16 lpEnumFunc;
71 LPARAM lpData;
73 LPNEWTEXTMETRICEX16 lpTextMetric;
74 LPENUMLOGFONTEX16 lpLogFont;
75 SEGPTR segTextMetric;
76 SEGPTR segLogFont;
77 DWORD dwFlags;
78 HDC hdc;
79 DC *dc;
80 PHYSDEV physDev;
81 } fontEnum16;
83 typedef struct
85 LPLOGFONTW lpLogFontParam;
86 FONTENUMPROCW lpEnumFunc;
87 LPARAM lpData;
88 DWORD dwFlags;
89 HDC hdc;
90 DC *dc;
91 PHYSDEV physDev;
92 } fontEnum32;
95 * For TranslateCharsetInfo
97 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
98 #define MAXTCIINDEX 32
99 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
100 /* ANSI */
101 { ANSI_CHARSET, 1252, FS(0)},
102 { EASTEUROPE_CHARSET, 1250, FS(1)},
103 { RUSSIAN_CHARSET, 1251, FS(2)},
104 { GREEK_CHARSET, 1253, FS(3)},
105 { TURKISH_CHARSET, 1254, FS(4)},
106 { HEBREW_CHARSET, 1255, FS(5)},
107 { ARABIC_CHARSET, 1256, FS(6)},
108 { BALTIC_CHARSET, 1257, FS(7)},
109 { VIETNAMESE_CHARSET, 1258, FS(8)},
110 /* reserved by ANSI */
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 { DEFAULT_CHARSET, 0, FS(0)},
116 { DEFAULT_CHARSET, 0, FS(0)},
117 { DEFAULT_CHARSET, 0, FS(0)},
118 /* ANSI and OEM */
119 { THAI_CHARSET, 874, FS(16)},
120 { SHIFTJIS_CHARSET, 932, FS(17)},
121 { GB2312_CHARSET, 936, FS(18)},
122 { HANGEUL_CHARSET, 949, FS(19)},
123 { CHINESEBIG5_CHARSET, 950, FS(20)},
124 { JOHAB_CHARSET, 1361, FS(21)},
125 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
132 { DEFAULT_CHARSET, 0, FS(0)},
133 { DEFAULT_CHARSET, 0, FS(0)},
134 /* reserved for system */
135 { DEFAULT_CHARSET, 0, FS(0)},
136 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
139 /***********************************************************************
140 * LOGFONT conversion functions.
142 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
144 font16->lfHeight = font32->lfHeight;
145 font16->lfWidth = font32->lfWidth;
146 font16->lfEscapement = font32->lfEscapement;
147 font16->lfOrientation = font32->lfOrientation;
148 font16->lfWeight = font32->lfWeight;
149 font16->lfItalic = font32->lfItalic;
150 font16->lfUnderline = font32->lfUnderline;
151 font16->lfStrikeOut = font32->lfStrikeOut;
152 font16->lfCharSet = font32->lfCharSet;
153 font16->lfOutPrecision = font32->lfOutPrecision;
154 font16->lfClipPrecision = font32->lfClipPrecision;
155 font16->lfQuality = font32->lfQuality;
156 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
157 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
158 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
159 font16->lfFaceName[LF_FACESIZE-1] = 0;
162 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
164 font32->lfHeight = font16->lfHeight;
165 font32->lfWidth = font16->lfWidth;
166 font32->lfEscapement = font16->lfEscapement;
167 font32->lfOrientation = font16->lfOrientation;
168 font32->lfWeight = font16->lfWeight;
169 font32->lfItalic = font16->lfItalic;
170 font32->lfUnderline = font16->lfUnderline;
171 font32->lfStrikeOut = font16->lfStrikeOut;
172 font32->lfCharSet = font16->lfCharSet;
173 font32->lfOutPrecision = font16->lfOutPrecision;
174 font32->lfClipPrecision = font16->lfClipPrecision;
175 font32->lfQuality = font16->lfQuality;
176 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
177 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
178 font32->lfFaceName[LF_FACESIZE-1] = 0;
181 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
183 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
184 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
185 LF_FACESIZE);
188 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
190 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
191 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
192 LF_FACESIZE, NULL, NULL);
195 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
197 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
200 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
201 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
203 font16->elfStyle, LF_FACESIZE, NULL, NULL );
204 font16->elfStyle[LF_FACESIZE-1] = '\0';
205 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
206 font16->elfScript, LF_FACESIZE, NULL, NULL );
207 font16->elfScript[LF_FACESIZE-1] = '\0';
210 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
212 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
215 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
216 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
218 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
219 fontA->elfStyle[LF_FACESIZE-1] = '\0';
220 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
221 fontA->elfScript, LF_FACESIZE, NULL, NULL );
222 fontA->elfScript[LF_FACESIZE-1] = '\0';
225 /***********************************************************************
226 * TEXTMETRIC conversion functions.
228 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
230 ptmA->tmHeight = ptmW->tmHeight;
231 ptmA->tmAscent = ptmW->tmAscent;
232 ptmA->tmDescent = ptmW->tmDescent;
233 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
234 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
235 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
236 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
237 ptmA->tmWeight = ptmW->tmWeight;
238 ptmA->tmOverhang = ptmW->tmOverhang;
239 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
240 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
241 ptmA->tmFirstChar = ptmW->tmFirstChar > 255 ? 255 : ptmW->tmFirstChar;
242 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
243 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
244 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : ptmW->tmBreakChar;
245 ptmA->tmItalic = ptmW->tmItalic;
246 ptmA->tmUnderlined = ptmW->tmUnderlined;
247 ptmA->tmStruckOut = ptmW->tmStruckOut;
248 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
249 ptmA->tmCharSet = ptmW->tmCharSet;
253 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
255 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
256 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
257 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
258 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
259 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
260 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
261 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
262 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
263 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
264 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
265 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
266 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
267 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
268 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
269 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
270 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
271 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
272 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
273 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
274 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
275 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
276 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
277 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
278 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
279 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
282 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
284 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
285 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
286 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
287 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
288 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
289 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
292 /***********************************************************************
293 * CreateFontIndirectA (GDI32.@)
295 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
297 LOGFONTW lfW;
299 if (plfA) {
300 FONT_LogFontAToW( plfA, &lfW );
301 return CreateFontIndirectW( &lfW );
302 } else
303 return CreateFontIndirectW( NULL );
307 /***********************************************************************
308 * CreateFontIndirectW (GDI32.@)
310 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
312 HFONT hFont = 0;
314 if (plf)
316 FONTOBJ* fontPtr;
317 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
318 (HGDIOBJ *)&hFont, &font_funcs )))
320 static const WCHAR ItalicW[] = {' ','I','t','a','l','i','c','\0'};
321 static const WCHAR BoldW[] = {' ','B','o','l','d','\0'};
322 WCHAR *pFaceNameItalicSuffix, *pFaceNameBoldSuffix;
323 WCHAR* pFaceNameSuffix = NULL;
325 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
327 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
328 plf->lfHeight, plf->lfWidth,
329 plf->lfEscapement, plf->lfOrientation,
330 plf->lfPitchAndFamily,
331 plf->lfOutPrecision, plf->lfClipPrecision,
332 plf->lfQuality, plf->lfCharSet,
333 debugstr_w(plf->lfFaceName),
334 plf->lfWeight > 400 ? "Bold" : "",
335 plf->lfItalic ? "Italic" : "", hFont);
337 if (plf->lfEscapement != plf->lfOrientation) {
338 /* this should really depend on whether GM_ADVANCED is set */
339 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
340 WARN("orientation angle %f set to "
341 "escapement angle %f for new font %p\n",
342 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
345 pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
346 if (pFaceNameItalicSuffix) {
347 fontPtr->logfont.lfItalic = TRUE;
348 pFaceNameSuffix = pFaceNameItalicSuffix;
351 pFaceNameBoldSuffix = strstrW(fontPtr->logfont.lfFaceName, BoldW);
352 if (pFaceNameBoldSuffix) {
353 if (fontPtr->logfont.lfWeight < FW_BOLD) {
354 fontPtr->logfont.lfWeight = FW_BOLD;
356 if (!pFaceNameSuffix ||
357 (pFaceNameBoldSuffix < pFaceNameSuffix)) {
358 pFaceNameSuffix = pFaceNameBoldSuffix;
362 if (pFaceNameSuffix) *pFaceNameSuffix = 0;
364 GDI_ReleaseObj( hFont );
367 else WARN("(NULL) => NULL\n");
369 return hFont;
372 /*************************************************************************
373 * CreateFontA (GDI32.@)
375 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
376 INT orient, INT weight, DWORD italic,
377 DWORD underline, DWORD strikeout, DWORD charset,
378 DWORD outpres, DWORD clippres, DWORD quality,
379 DWORD pitch, LPCSTR name )
381 LOGFONTA logfont;
383 logfont.lfHeight = height;
384 logfont.lfWidth = width;
385 logfont.lfEscapement = esc;
386 logfont.lfOrientation = orient;
387 logfont.lfWeight = weight;
388 logfont.lfItalic = italic;
389 logfont.lfUnderline = underline;
390 logfont.lfStrikeOut = strikeout;
391 logfont.lfCharSet = charset;
392 logfont.lfOutPrecision = outpres;
393 logfont.lfClipPrecision = clippres;
394 logfont.lfQuality = quality;
395 logfont.lfPitchAndFamily = pitch;
397 if (name)
398 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
399 else
400 logfont.lfFaceName[0] = '\0';
402 return CreateFontIndirectA( &logfont );
405 /*************************************************************************
406 * CreateFontW (GDI32.@)
408 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
409 INT orient, INT weight, DWORD italic,
410 DWORD underline, DWORD strikeout, DWORD charset,
411 DWORD outpres, DWORD clippres, DWORD quality,
412 DWORD pitch, LPCWSTR name )
414 LOGFONTW logfont;
416 logfont.lfHeight = height;
417 logfont.lfWidth = width;
418 logfont.lfEscapement = esc;
419 logfont.lfOrientation = orient;
420 logfont.lfWeight = weight;
421 logfont.lfItalic = italic;
422 logfont.lfUnderline = underline;
423 logfont.lfStrikeOut = strikeout;
424 logfont.lfCharSet = charset;
425 logfont.lfOutPrecision = outpres;
426 logfont.lfClipPrecision = clippres;
427 logfont.lfQuality = quality;
428 logfont.lfPitchAndFamily = pitch;
430 if (name)
431 lstrcpynW(logfont.lfFaceName, name,
432 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
433 else
434 logfont.lfFaceName[0] = '\0';
436 return CreateFontIndirectW( &logfont );
440 /***********************************************************************
441 * FONT_SelectObject
443 * If the driver supports vector fonts we create a gdi font first and
444 * then call the driver to give it a chance to supply its own device
445 * font. If the driver wants to do this it returns TRUE and we can
446 * delete the gdi font, if the driver wants to use the gdi font it
447 * should return FALSE, to signal an error return GDI_ERROR. For
448 * drivers that don't support vector fonts they must supply their own
449 * font.
451 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
453 HGDIOBJ ret = 0;
454 DC *dc = DC_GetDCPtr( hdc );
456 if (!dc) return 0;
458 if (dc->hFont != handle || dc->gdiFont == NULL)
460 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
461 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
464 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
466 if (ret && dc->gdiFont) dc->gdiFont = 0;
468 if (ret == HGDI_ERROR)
469 ret = 0; /* SelectObject returns 0 on error */
470 else
472 ret = dc->hFont;
473 dc->hFont = handle;
475 GDI_ReleaseObj( hdc );
476 return ret;
480 /***********************************************************************
481 * FONT_GetObject16
483 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
485 FONTOBJ *font = obj;
486 LOGFONT16 lf16;
488 FONT_LogFontWTo16( &font->logfont, &lf16 );
490 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
491 memcpy( buffer, &lf16, count );
492 return count;
495 /***********************************************************************
496 * FONT_GetObjectA
498 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
500 FONTOBJ *font = obj;
501 LOGFONTA lfA;
503 if(!buffer)
504 return sizeof(lfA);
505 FONT_LogFontWToA( &font->logfont, &lfA );
507 if (count > sizeof(lfA)) count = sizeof(lfA);
508 memcpy( buffer, &lfA, count );
509 return count;
512 /***********************************************************************
513 * FONT_GetObjectW
515 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
517 FONTOBJ *font = obj;
518 if(!buffer)
519 return sizeof(LOGFONTW);
520 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
521 memcpy( buffer, &font->logfont, count );
522 return count;
526 /***********************************************************************
527 * FONT_DeleteObject
529 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
531 WineEngDestroyFontInstance( handle );
532 return GDI_FreeObject( handle, obj );
536 /***********************************************************************
537 * FONT_EnumInstance16
539 * Called by the device driver layer to pass font info
540 * down to the application.
542 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
543 DWORD fType, LPARAM lp )
545 fontEnum16 *pfe = (fontEnum16*)lp;
546 INT ret = 1;
547 DC *dc;
549 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
550 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
552 WORD args[7];
553 DWORD result;
555 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
556 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
557 pfe->dwFlags |= ENUM_CALLED;
558 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
560 args[6] = SELECTOROF(pfe->segLogFont);
561 args[5] = OFFSETOF(pfe->segLogFont);
562 args[4] = SELECTOROF(pfe->segTextMetric);
563 args[3] = OFFSETOF(pfe->segTextMetric);
564 args[2] = fType;
565 args[1] = HIWORD(pfe->lpData);
566 args[0] = LOWORD(pfe->lpData);
567 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
568 ret = LOWORD(result);
570 /* get the lock again and make sure the DC is still valid */
571 dc = DC_GetDCPtr( pfe->hdc );
572 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
574 if (dc) GDI_ReleaseObj( pfe->hdc );
575 pfe->hdc = 0; /* make sure we don't try to release it later on */
576 ret = 0;
579 return ret;
582 /***********************************************************************
583 * FONT_EnumInstance
585 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
586 DWORD fType, LPARAM lp )
588 fontEnum32 *pfe = (fontEnum32*)lp;
589 INT ret = 1;
590 DC *dc;
592 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
593 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
594 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
596 /* convert font metrics */
597 ENUMLOGFONTEXA logfont;
598 NEWTEXTMETRICEXA tmA;
600 pfe->dwFlags |= ENUM_CALLED;
601 if (!(pfe->dwFlags & ENUM_UNICODE))
603 FONT_EnumLogFontExWToA( plf, &logfont);
604 FONT_NewTextMetricExWToA( ptm, &tmA );
605 plf = (LPENUMLOGFONTEXW)&logfont;
606 ptm = (NEWTEXTMETRICEXW *)&tmA;
608 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
610 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
612 /* get the lock again and make sure the DC is still valid */
613 dc = DC_GetDCPtr( pfe->hdc );
614 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
616 if (dc) GDI_ReleaseObj( pfe->hdc );
617 pfe->hdc = 0; /* make sure we don't try to release it later on */
618 ret = 0;
621 return ret;
624 /***********************************************************************
625 * EnumFontFamiliesEx (GDI.613)
627 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
628 FONTENUMPROC16 efproc, LPARAM lParam,
629 DWORD dwFlags)
631 fontEnum16 fe16;
632 INT16 ret = 1, ret2;
633 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
634 NEWTEXTMETRICEX16 tm16;
635 ENUMLOGFONTEX16 lf16;
636 LOGFONTW lfW;
637 BOOL enum_gdi_fonts;
639 if (!dc) return 0;
640 FONT_LogFont16ToW(plf, &lfW);
642 fe16.hdc = HDC_32(hDC);
643 fe16.dc = dc;
644 fe16.physDev = dc->physDev;
645 fe16.lpLogFontParam = plf;
646 fe16.lpEnumFunc = efproc;
647 fe16.lpData = lParam;
648 fe16.lpTextMetric = &tm16;
649 fe16.lpLogFont = &lf16;
650 fe16.segTextMetric = MapLS( &tm16 );
651 fe16.segLogFont = MapLS( &lf16 );
652 fe16.dwFlags = 0;
654 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
656 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
658 ret = 0;
659 goto done;
662 if (enum_gdi_fonts)
663 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
664 fe16.dwFlags &= ~ENUM_CALLED;
665 if (ret && dc->funcs->pEnumDeviceFonts) {
666 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
667 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
668 ret = ret2;
670 done:
671 UnMapLS( fe16.segTextMetric );
672 UnMapLS( fe16.segLogFont );
673 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
674 return ret;
677 /***********************************************************************
678 * FONT_EnumFontFamiliesEx
680 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
681 FONTENUMPROCW efproc,
682 LPARAM lParam, DWORD dwUnicode)
684 INT ret = 1, ret2;
685 DC *dc = DC_GetDCPtr( hDC );
686 fontEnum32 fe32;
687 BOOL enum_gdi_fonts;
689 if (!dc) return 0;
691 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
692 plf->lfCharSet);
693 fe32.lpLogFontParam = plf;
694 fe32.lpEnumFunc = efproc;
695 fe32.lpData = lParam;
696 fe32.dwFlags = dwUnicode;
697 fe32.hdc = hDC;
698 fe32.dc = dc;
699 fe32.physDev = dc->physDev;
701 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
703 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
705 ret = 0;
706 goto done;
709 if (enum_gdi_fonts)
710 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
711 fe32.dwFlags &= ~ENUM_CALLED;
712 if (ret && dc->funcs->pEnumDeviceFonts) {
713 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
714 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
715 ret = ret2;
717 done:
718 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
719 return ret;
722 /***********************************************************************
723 * EnumFontFamiliesExW (GDI32.@)
725 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
726 FONTENUMPROCW efproc,
727 LPARAM lParam, DWORD dwFlags )
729 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
732 /***********************************************************************
733 * EnumFontFamiliesExA (GDI32.@)
735 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
736 FONTENUMPROCA efproc,
737 LPARAM lParam, DWORD dwFlags)
739 LOGFONTW lfW;
740 FONT_LogFontAToW( plf, &lfW );
742 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
745 /***********************************************************************
746 * EnumFontFamilies (GDI.330)
748 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
749 FONTENUMPROC16 efproc, LPARAM lpData )
751 LOGFONT16 lf;
753 lf.lfCharSet = DEFAULT_CHARSET;
754 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
755 else lf.lfFaceName[0] = '\0';
757 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
760 /***********************************************************************
761 * EnumFontFamiliesA (GDI32.@)
763 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
764 FONTENUMPROCA efproc, LPARAM lpData )
766 LOGFONTA lf;
768 lf.lfCharSet = DEFAULT_CHARSET;
769 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
770 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
772 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
775 /***********************************************************************
776 * EnumFontFamiliesW (GDI32.@)
778 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
779 FONTENUMPROCW efproc, LPARAM lpData )
781 LOGFONTW lf;
783 lf.lfCharSet = DEFAULT_CHARSET;
784 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
785 else lf.lfFaceName[0] = 0;
787 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
790 /***********************************************************************
791 * EnumFonts (GDI.70)
793 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
794 LPARAM lpData )
796 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
799 /***********************************************************************
800 * EnumFontsA (GDI32.@)
802 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
803 LPARAM lpData )
805 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
808 /***********************************************************************
809 * EnumFontsW (GDI32.@)
811 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
812 LPARAM lpData )
814 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
818 /***********************************************************************
819 * GetTextCharacterExtra (GDI32.@)
821 INT WINAPI GetTextCharacterExtra( HDC hdc )
823 INT ret;
824 DC *dc = DC_GetDCPtr( hdc );
825 if (!dc) return 0x80000000;
826 ret = dc->charExtra;
827 GDI_ReleaseObj( hdc );
828 return ret;
832 /***********************************************************************
833 * SetTextCharacterExtra (GDI32.@)
835 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
837 INT prev;
838 DC * dc = DC_GetDCPtr( hdc );
839 if (!dc) return 0x80000000;
840 if (dc->funcs->pSetTextCharacterExtra)
841 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
842 else
844 prev = dc->charExtra;
845 dc->charExtra = extra;
847 GDI_ReleaseObj( hdc );
848 return prev;
852 /***********************************************************************
853 * SetTextJustification (GDI32.@)
855 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
857 BOOL ret = TRUE;
858 DC * dc = DC_GetDCPtr( hdc );
859 if (!dc) return FALSE;
860 if (dc->funcs->pSetTextJustification)
861 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
862 else
864 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
865 if (!extra) breaks = 0;
866 dc->breakTotalExtra = extra;
867 dc->breakCount = breaks;
868 if (breaks)
870 dc->breakExtra = extra / breaks;
871 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
873 else
875 dc->breakExtra = 0;
876 dc->breakRem = 0;
879 GDI_ReleaseObj( hdc );
880 return ret;
884 /***********************************************************************
885 * GetTextFaceA (GDI32.@)
887 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
889 INT res = GetTextFaceW(hdc, 0, NULL);
890 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
891 GetTextFaceW( hdc, res, nameW );
893 if (name)
895 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
896 name[count-1] = 0;
897 res = strlen(name);
899 else
900 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
901 HeapFree( GetProcessHeap(), 0, nameW );
902 return res;
905 /***********************************************************************
906 * GetTextFaceW (GDI32.@)
908 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
910 FONTOBJ *font;
911 INT ret = 0;
913 DC * dc = DC_GetDCPtr( hdc );
914 if (!dc) return 0;
916 if(dc->gdiFont)
917 ret = WineEngGetTextFace(dc->gdiFont, count, name);
918 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
920 if (name)
922 lstrcpynW( name, font->logfont.lfFaceName, count );
923 ret = strlenW(name);
925 else ret = strlenW(font->logfont.lfFaceName) + 1;
926 GDI_ReleaseObj( dc->hFont );
928 GDI_ReleaseObj( hdc );
929 return ret;
933 /***********************************************************************
934 * GetTextExtentPoint32A (GDI32.@)
936 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
937 LPSIZE size )
939 BOOL ret = FALSE;
940 INT wlen;
941 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
943 if (p) {
944 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
945 HeapFree( GetProcessHeap(), 0, p );
948 TRACE("(%p %s %d %p): returning %ld x %ld\n",
949 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
950 return ret;
954 /***********************************************************************
955 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
957 * Computes width and height of the specified string.
959 * RETURNS
960 * Success: TRUE
961 * Failure: FALSE
963 BOOL WINAPI GetTextExtentPoint32W(
964 HDC hdc, /* [in] Handle of device context */
965 LPCWSTR str, /* [in] Address of text string */
966 INT count, /* [in] Number of characters in string */
967 LPSIZE size) /* [out] Address of structure for string size */
969 BOOL ret = FALSE;
970 DC * dc = DC_GetDCPtr( hdc );
971 if (!dc) return FALSE;
973 if(dc->gdiFont) {
974 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
975 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
976 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
978 else if(dc->funcs->pGetTextExtentPoint)
979 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
981 GDI_ReleaseObj( hdc );
983 TRACE("(%p %s %d %p): returning %ld x %ld\n",
984 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
985 return ret;
988 /***********************************************************************
989 * GetTextExtentPointI [GDI32.@]
991 * Computes width and height of the array of glyph indices.
993 * RETURNS
994 * Success: TRUE
995 * Failure: FALSE
997 BOOL WINAPI GetTextExtentPointI(
998 HDC hdc, /* [in] Handle of device context */
999 const WORD *indices, /* [in] Address of glyph index array */
1000 INT count, /* [in] Number of glyphs in array */
1001 LPSIZE size) /* [out] Address of structure for string size */
1003 BOOL ret = FALSE;
1004 DC * dc = DC_GetDCPtr( hdc );
1005 if (!dc) return FALSE;
1007 if(dc->gdiFont) {
1008 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1009 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1010 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1012 else if(dc->funcs->pGetTextExtentPoint) {
1013 FIXME("calling GetTextExtentPoint\n");
1014 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1017 GDI_ReleaseObj( hdc );
1019 TRACE("(%p %p %d %p): returning %ld x %ld\n",
1020 hdc, indices, count, size, size->cx, size->cy );
1021 return ret;
1025 /***********************************************************************
1026 * GetTextExtentPointA (GDI32.@)
1028 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1029 LPSIZE size )
1031 TRACE("not bug compatible.\n");
1032 return GetTextExtentPoint32A( hdc, str, count, size );
1035 /***********************************************************************
1036 * GetTextExtentPointW (GDI32.@)
1038 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1039 LPSIZE size )
1041 TRACE("not bug compatible.\n");
1042 return GetTextExtentPoint32W( hdc, str, count, size );
1046 /***********************************************************************
1047 * GetTextExtentExPointA (GDI32.@)
1049 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1050 INT maxExt, LPINT lpnFit,
1051 LPINT alpDx, LPSIZE size )
1053 BOOL ret;
1054 INT wlen;
1055 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1056 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1057 HeapFree( GetProcessHeap(), 0, p );
1058 return ret;
1062 /***********************************************************************
1063 * GetTextExtentExPointW (GDI32.@)
1065 * Return the size of the string as it would be if it was output properly by
1066 * e.g. TextOut.
1068 * This should include
1069 * - Intercharacter spacing
1070 * - justification spacing (not yet done)
1071 * - kerning? see below
1073 * Kerning. Since kerning would be carried out by the rendering code it should
1074 * be done by the driver. However they don't support it yet. Also I am not
1075 * yet persuaded that (certainly under Win95) any kerning is actually done.
1077 * str: According to MSDN this should be null-terminated. That is not true; a
1078 * null will not terminate it early.
1079 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1080 * than count. I have seen it be either the size of the full string or
1081 * 1 less than the size of the full string. I have not seen it bear any
1082 * resemblance to the portion that would fit.
1083 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1084 * trailing intercharacter spacing and any trailing justification.
1086 * FIXME
1087 * Currently we do this by measuring each character etc. We should do it by
1088 * passing the request to the driver, perhaps by extending the
1089 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1090 * thinking about kerning issues and rounding issues in the justification.
1093 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1094 INT maxExt, LPINT lpnFit,
1095 LPINT alpDx, LPSIZE size )
1097 int index, nFit, extent;
1098 SIZE tSize;
1099 BOOL ret = FALSE;
1101 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1103 size->cx = size->cy = nFit = extent = 0;
1104 for(index = 0; index < count; index++)
1106 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1107 /* GetTextExtentPoint includes intercharacter spacing. */
1108 /* FIXME - justification needs doing yet. Remember that the base
1109 * data will not be in logical coordinates.
1111 extent += tSize.cx;
1112 if( !lpnFit || extent <= maxExt )
1113 /* It is allowed to be equal. */
1115 nFit++;
1116 if( alpDx ) alpDx[index] = extent;
1118 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1119 str++;
1121 size->cx = extent;
1122 if(lpnFit) *lpnFit = nFit;
1123 ret = TRUE;
1125 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1127 done:
1128 return ret;
1131 /***********************************************************************
1132 * GetTextMetricsA (GDI32.@)
1134 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1136 TEXTMETRICW tm32;
1138 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1139 FONT_TextMetricWToA( &tm32, metrics );
1140 return TRUE;
1143 /***********************************************************************
1144 * GetTextMetricsW (GDI32.@)
1146 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1148 BOOL ret = FALSE;
1149 DC * dc = DC_GetDCPtr( hdc );
1150 if (!dc) return FALSE;
1152 if (dc->gdiFont)
1153 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1154 else if (dc->funcs->pGetTextMetrics)
1155 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1157 if (ret)
1159 /* device layer returns values in device units
1160 * therefore we have to convert them to logical */
1162 #define WDPTOLP(x) ((x<0)? \
1163 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1164 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1165 #define HDPTOLP(y) ((y<0)? \
1166 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1167 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1169 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1170 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1171 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1172 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1173 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1174 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1175 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1176 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1177 ret = TRUE;
1178 #undef WDPTOLP
1179 #undef HDPTOLP
1180 TRACE("text metrics:\n"
1181 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1182 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1183 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1184 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1185 " PitchAndFamily = %02x\n"
1186 " --------------------\n"
1187 " InternalLeading = %li\n"
1188 " Ascent = %li\n"
1189 " Descent = %li\n"
1190 " Height = %li\n",
1191 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1192 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1193 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1194 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1195 metrics->tmPitchAndFamily,
1196 metrics->tmInternalLeading,
1197 metrics->tmAscent,
1198 metrics->tmDescent,
1199 metrics->tmHeight );
1201 GDI_ReleaseObj( hdc );
1202 return ret;
1206 /***********************************************************************
1207 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1209 * NOTES
1210 * lpOTM should be LPOUTLINETEXTMETRIC
1212 * RETURNS
1213 * Success: Non-zero or size of required buffer
1214 * Failure: 0
1216 UINT16 WINAPI GetOutlineTextMetrics16(
1217 HDC16 hdc, /* [in] Handle of device context */
1218 UINT16 cbData, /* [in] Size of metric data array */
1219 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1221 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1222 return 0;
1226 /***********************************************************************
1227 * GetOutlineTextMetricsA (GDI32.@)
1228 * Gets metrics for TrueType fonts.
1231 * RETURNS
1232 * Success: Non-zero or size of required buffer
1233 * Failure: 0
1235 UINT WINAPI GetOutlineTextMetricsA(
1236 HDC hdc, /* [in] Handle of device context */
1237 UINT cbData, /* [in] Size of metric data array */
1238 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1240 char buf[512], *ptr;
1241 UINT ret, needed;
1242 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1243 INT left, len;
1245 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1246 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1247 return 0;
1248 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1249 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1252 needed = sizeof(OUTLINETEXTMETRICA);
1253 if(lpOTMW->otmpFamilyName)
1254 needed += WideCharToMultiByte(CP_ACP, 0,
1255 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1256 NULL, 0, NULL, NULL);
1257 if(lpOTMW->otmpFaceName)
1258 needed += WideCharToMultiByte(CP_ACP, 0,
1259 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1260 NULL, 0, NULL, NULL);
1261 if(lpOTMW->otmpStyleName)
1262 needed += WideCharToMultiByte(CP_ACP, 0,
1263 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1264 NULL, 0, NULL, NULL);
1265 if(lpOTMW->otmpFullName)
1266 needed += WideCharToMultiByte(CP_ACP, 0,
1267 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1268 NULL, 0, NULL, NULL);
1270 if(!lpOTM) {
1271 ret = needed;
1272 goto end;
1275 if(needed > cbData) {
1276 ret = 0;
1277 goto end;
1281 lpOTM->otmSize = needed;
1282 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1283 lpOTM->otmFiller = 0;
1284 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1285 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1286 lpOTM->otmfsType = lpOTMW->otmfsType;
1287 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1288 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1289 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1290 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1291 lpOTM->otmAscent = lpOTMW->otmAscent;
1292 lpOTM->otmDescent = lpOTMW->otmDescent;
1293 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1294 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1295 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1296 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1297 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1298 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1299 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1300 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1301 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1302 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1303 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1304 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1305 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1306 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1307 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1308 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1311 ptr = (char*)(lpOTM + 1);
1312 left = needed - sizeof(*lpOTM);
1314 if(lpOTMW->otmpFamilyName) {
1315 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1316 len = WideCharToMultiByte(CP_ACP, 0,
1317 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1318 ptr, left, NULL, NULL);
1319 left -= len;
1320 ptr += len;
1321 } else
1322 lpOTM->otmpFamilyName = 0;
1324 if(lpOTMW->otmpFaceName) {
1325 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1326 len = WideCharToMultiByte(CP_ACP, 0,
1327 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1328 ptr, left, NULL, NULL);
1329 left -= len;
1330 ptr += len;
1331 } else
1332 lpOTM->otmpFaceName = 0;
1334 if(lpOTMW->otmpStyleName) {
1335 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1336 len = WideCharToMultiByte(CP_ACP, 0,
1337 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1338 ptr, left, NULL, NULL);
1339 left -= len;
1340 ptr += len;
1341 } else
1342 lpOTM->otmpStyleName = 0;
1344 if(lpOTMW->otmpFullName) {
1345 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1346 len = WideCharToMultiByte(CP_ACP, 0,
1347 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1348 ptr, left, NULL, NULL);
1349 left -= len;
1350 } else
1351 lpOTM->otmpFullName = 0;
1353 assert(left == 0);
1355 ret = needed;
1357 end:
1358 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1359 HeapFree(GetProcessHeap(), 0, lpOTMW);
1361 return ret;
1365 /***********************************************************************
1366 * GetOutlineTextMetricsW [GDI32.@]
1368 UINT WINAPI GetOutlineTextMetricsW(
1369 HDC hdc, /* [in] Handle of device context */
1370 UINT cbData, /* [in] Size of metric data array */
1371 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1373 DC *dc = DC_GetDCPtr( hdc );
1374 UINT ret;
1376 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1377 if(!dc) return 0;
1379 if(dc->gdiFont) {
1380 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1381 if(ret && ret <= cbData) {
1382 #define WDPTOLP(x) ((x<0)? \
1383 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1384 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1385 #define HDPTOLP(y) ((y<0)? \
1386 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1387 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1389 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1390 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1391 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1392 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1393 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1394 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1395 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1396 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1397 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1398 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1399 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1400 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1401 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1402 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1403 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1404 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1405 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1406 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1407 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1408 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1409 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1410 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1411 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1412 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1413 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1414 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1415 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1416 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1417 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1418 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1419 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1420 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1421 #undef WDPTOLP
1422 #undef HDPTOLP
1426 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1427 but really this should just be a return 0. */
1429 ret = sizeof(*lpOTM);
1430 if (lpOTM) {
1431 if(cbData < ret)
1432 ret = 0;
1433 else {
1434 memset(lpOTM, 0, ret);
1435 lpOTM->otmSize = sizeof(*lpOTM);
1436 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1438 Further fill of the structure not implemented,
1439 Needs real values for the structure members
1444 GDI_ReleaseObj(hdc);
1445 return ret;
1449 /***********************************************************************
1450 * GetCharWidthW (GDI32.@)
1451 * GetCharWidth32W (GDI32.@)
1453 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1454 LPINT buffer )
1456 UINT i;
1457 BOOL ret = FALSE;
1458 DC * dc = DC_GetDCPtr( hdc );
1459 if (!dc) return FALSE;
1461 if (dc->gdiFont)
1462 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1463 else if (dc->funcs->pGetCharWidth)
1464 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1466 if (ret)
1468 /* convert device units to logical */
1469 for( i = firstChar; i <= lastChar; i++, buffer++ )
1470 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1471 ret = TRUE;
1473 GDI_ReleaseObj( hdc );
1474 return ret;
1478 /***********************************************************************
1479 * GetCharWidthA (GDI32.@)
1480 * GetCharWidth32A (GDI32.@)
1482 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1483 LPINT buffer )
1485 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1486 LPSTR str;
1487 LPWSTR wstr;
1488 BOOL ret = TRUE;
1490 if(count <= 0) return FALSE;
1492 str = HeapAlloc(GetProcessHeap(), 0, count);
1493 for(i = 0; i < count; i++)
1494 str[i] = (BYTE)(firstChar + i);
1496 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1498 for(i = 0; i < wlen; i++)
1500 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1502 ret = FALSE;
1503 break;
1505 buffer++;
1508 HeapFree(GetProcessHeap(), 0, str);
1509 HeapFree(GetProcessHeap(), 0, wstr);
1511 return ret;
1515 /* FIXME: all following APIs ******************************************/
1518 /***********************************************************************
1519 * SetMapperFlags (GDI32.@)
1521 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1523 DC *dc = DC_GetDCPtr( hDC );
1524 DWORD ret = 0;
1525 if(!dc) return 0;
1526 if(dc->funcs->pSetMapperFlags)
1527 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1528 else
1529 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1530 GDI_ReleaseObj( hDC );
1531 return ret;
1534 /***********************************************************************
1535 * GetAspectRatioFilterEx (GDI.486)
1537 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1539 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1540 return FALSE;
1543 /***********************************************************************
1544 * GetAspectRatioFilterEx (GDI32.@)
1546 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1548 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1549 return FALSE;
1553 /***********************************************************************
1554 * GetCharABCWidthsA (GDI32.@)
1556 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1557 LPABC abc )
1559 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1560 LPSTR str;
1561 LPWSTR wstr;
1562 BOOL ret = TRUE;
1564 if(count <= 0) return FALSE;
1566 str = HeapAlloc(GetProcessHeap(), 0, count);
1567 for(i = 0; i < count; i++)
1568 str[i] = (BYTE)(firstChar + i);
1570 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1572 for(i = 0; i < wlen; i++)
1574 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1576 ret = FALSE;
1577 break;
1579 abc++;
1582 HeapFree(GetProcessHeap(), 0, str);
1583 HeapFree(GetProcessHeap(), 0, wstr);
1585 return ret;
1589 /******************************************************************************
1590 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1592 * PARAMS
1593 * hdc [I] Handle of device context
1594 * firstChar [I] First character in range to query
1595 * lastChar [I] Last character in range to query
1596 * abc [O] Address of character-width structure
1598 * NOTES
1599 * Only works with TrueType fonts
1601 * RETURNS
1602 * Success: TRUE
1603 * Failure: FALSE
1605 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1606 LPABC abc )
1608 DC *dc = DC_GetDCPtr(hdc);
1609 int i;
1610 GLYPHMETRICS gm;
1611 BOOL ret = FALSE;
1613 if(dc->gdiFont) {
1614 for (i=firstChar;i<=lastChar;i++) {
1615 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1616 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1617 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1618 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1620 ret = TRUE;
1622 GDI_ReleaseObj(hdc);
1623 return ret;
1627 /***********************************************************************
1628 * GetGlyphOutline (GDI.309)
1630 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1631 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1632 LPVOID lpBuffer, const MAT2 *lpmat2 )
1634 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1635 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1636 return (DWORD)-1; /* failure */
1640 /***********************************************************************
1641 * GetGlyphOutlineA (GDI32.@)
1643 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1644 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1645 LPVOID lpBuffer, const MAT2 *lpmat2 )
1647 LPWSTR p = NULL;
1648 DWORD ret;
1649 UINT c;
1651 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1652 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1653 c = p[0];
1654 } else
1655 c = uChar;
1656 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1657 lpmat2);
1658 if(p)
1659 HeapFree(GetProcessHeap(), 0, p);
1660 return ret;
1663 /***********************************************************************
1664 * GetGlyphOutlineW (GDI32.@)
1666 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1667 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1668 LPVOID lpBuffer, const MAT2 *lpmat2 )
1670 DC *dc = DC_GetDCPtr(hdc);
1671 DWORD ret;
1673 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1674 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1676 if(!dc) return GDI_ERROR;
1678 if(dc->gdiFont)
1679 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1680 cbBuffer, lpBuffer, lpmat2);
1681 else
1682 ret = GDI_ERROR;
1684 GDI_ReleaseObj(hdc);
1685 return ret;
1689 /***********************************************************************
1690 * CreateScalableFontResourceA (GDI32.@)
1692 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1693 LPCSTR lpszResourceFile,
1694 LPCSTR lpszFontFile,
1695 LPCSTR lpszCurrentPath )
1697 HANDLE f;
1699 /* fHidden=1 - only visible for the calling app, read-only, not
1700 * enumbered with EnumFonts/EnumFontFamilies
1701 * lpszCurrentPath can be NULL
1703 FIXME("(%ld,%s,%s,%s): stub\n",
1704 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1705 debugstr_a(lpszCurrentPath) );
1707 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1708 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1709 CloseHandle(f);
1710 SetLastError(ERROR_FILE_EXISTS);
1711 return FALSE;
1713 return FALSE; /* create failed */
1716 /***********************************************************************
1717 * CreateScalableFontResourceW (GDI32.@)
1719 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1720 LPCWSTR lpszResourceFile,
1721 LPCWSTR lpszFontFile,
1722 LPCWSTR lpszCurrentPath )
1724 FIXME("(%ld,%p,%p,%p): stub\n",
1725 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1726 return FALSE; /* create failed */
1730 /*************************************************************************
1731 * GetRasterizerCaps (GDI32.@)
1733 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1735 lprs->nSize = sizeof(RASTERIZER_STATUS);
1736 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1737 lprs->nLanguageID = 0;
1738 return TRUE;
1742 /*************************************************************************
1743 * GetKerningPairsA (GDI32.@)
1745 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1746 LPKERNINGPAIR lpKerningPairs )
1748 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1752 /*************************************************************************
1753 * GetKerningPairsW (GDI32.@)
1755 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1756 LPKERNINGPAIR lpKerningPairs )
1758 int i;
1759 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1760 for (i = 0; i < cPairs; i++)
1761 lpKerningPairs[i].iKernAmount = 0;
1762 return 0;
1765 /*************************************************************************
1766 * TranslateCharsetInfo [GDI32.@]
1768 * Fills a CHARSETINFO structure for a character set, code page, or
1769 * font. This allows making the correspondance between different labelings
1770 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1771 * of the same encoding.
1773 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1774 * only one codepage should be set in *lpSrc.
1776 * RETURNS
1777 * TRUE on success, FALSE on failure.
1780 BOOL WINAPI TranslateCharsetInfo(
1781 LPDWORD lpSrc, /* [in]
1782 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1783 if flags == TCI_SRCCHARSET: a character set value
1784 if flags == TCI_SRCCODEPAGE: a code page value
1786 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1787 DWORD flags /* [in] determines interpretation of lpSrc */
1789 int index = 0;
1790 switch (flags) {
1791 case TCI_SRCFONTSIG:
1792 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1793 break;
1794 case TCI_SRCCODEPAGE:
1795 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1796 break;
1797 case TCI_SRCCHARSET:
1798 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1799 break;
1800 default:
1801 return FALSE;
1803 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1804 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1805 return TRUE;
1808 /*************************************************************************
1809 * GetFontLanguageInfo (GDI32.@)
1811 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1813 FONTSIGNATURE fontsig;
1814 static const DWORD GCP_DBCS_MASK=0x003F0000,
1815 GCP_DIACRITIC_MASK=0x00000000,
1816 FLI_GLYPHS_MASK=0x00000000,
1817 GCP_GLYPHSHAPE_MASK=0x00000040,
1818 GCP_KASHIDA_MASK=0x00000000,
1819 GCP_LIGATE_MASK=0x00000000,
1820 GCP_USEKERNING_MASK=0x00000000,
1821 GCP_REORDER_MASK=0x00000060;
1823 DWORD result=0;
1825 GetTextCharsetInfo( hdc, &fontsig, 0 );
1826 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1828 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1829 result|=GCP_DBCS;
1831 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1832 result|=GCP_DIACRITIC;
1834 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1835 result|=FLI_GLYPHS;
1837 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1838 result|=GCP_GLYPHSHAPE;
1840 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1841 result|=GCP_KASHIDA;
1843 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1844 result|=GCP_LIGATE;
1846 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1847 result|=GCP_USEKERNING;
1849 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1850 result|=GCP_REORDER;
1852 return result;
1856 /*************************************************************************
1857 * GetFontData [GDI32.@] Retrieve data for TrueType font
1859 * RETURNS
1861 * success: Number of bytes returned
1862 * failure: GDI_ERROR
1864 * NOTES
1866 * Calls SetLastError()
1869 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1870 LPVOID buffer, DWORD length)
1872 DC *dc = DC_GetDCPtr(hdc);
1873 DWORD ret = GDI_ERROR;
1875 if(!dc) return GDI_ERROR;
1877 if(dc->gdiFont)
1878 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1880 GDI_ReleaseObj(hdc);
1881 return ret;
1884 /*************************************************************************
1885 * GetGlyphIndicesA [GDI32.@]
1887 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1888 LPWORD pgi, DWORD flags)
1890 DWORD ret;
1891 WCHAR *lpstrW;
1892 INT countW;
1894 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1895 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1897 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1898 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1899 HeapFree(GetProcessHeap(), 0, lpstrW);
1901 return ret;
1904 /*************************************************************************
1905 * GetGlyphIndicesW [GDI32.@]
1907 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1908 LPWORD pgi, DWORD flags)
1910 DC *dc = DC_GetDCPtr(hdc);
1911 DWORD ret = GDI_ERROR;
1913 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1914 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1916 if(!dc) return GDI_ERROR;
1918 if(dc->gdiFont)
1919 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1921 GDI_ReleaseObj(hdc);
1922 return ret;
1925 /*************************************************************************
1926 * GetCharacterPlacementA [GDI32.@]
1928 * NOTES:
1929 * the web browser control of ie4 calls this with dwFlags=0
1931 DWORD WINAPI
1932 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1933 INT nMaxExtent, GCP_RESULTSA *lpResults,
1934 DWORD dwFlags)
1936 WCHAR *lpStringW;
1937 INT uCountW, i;
1938 GCP_RESULTSW resultsW;
1939 DWORD ret;
1940 UINT font_cp;
1942 TRACE("%s, %d, %d, 0x%08lx\n",
1943 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1945 /* both structs are equal in size */
1946 memcpy(&resultsW, lpResults, sizeof(resultsW));
1948 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1949 if(lpResults->lpOutString)
1950 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1952 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1954 if(lpResults->lpOutString) {
1955 if(font_cp != CP_SYMBOL)
1956 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1957 lpResults->lpOutString, uCount, NULL, NULL );
1958 else
1959 for(i = 0; i < uCount; i++)
1960 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1963 HeapFree(GetProcessHeap(), 0, lpStringW);
1964 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1966 return ret;
1969 /*************************************************************************
1970 * GetCharacterPlacementW [GDI32.@]
1972 * Retrieve information about a string. This includes the width, reordering,
1973 * Glyphing and so on.
1975 * RETURNS
1977 * The width and height of the string if successful, 0 if failed.
1979 * BUGS
1981 * All flags except GCP_REORDER are not yet implemented.
1982 * Reordering is not 100% complient to the Windows BiDi method.
1983 * Caret positioning is not yet implemented.
1984 * Classes are not yet implemented.
1987 DWORD WINAPI
1988 GetCharacterPlacementW(
1989 HDC hdc, /* [in] Device context for which the rendering is to be done */
1990 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1991 INT uCount, /* [in] Number of WORDS in string. */
1992 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1993 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1994 DWORD dwFlags /* [in] Flags specifying how to process the string */
1997 DWORD ret=0;
1998 SIZE size;
1999 UINT i, nSet;
2001 TRACE("%s, %d, %d, 0x%08lx\n",
2002 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2004 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2005 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2006 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2007 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2008 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2010 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2011 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2012 if(lpResults->lpClass) FIXME("classes not implemented\n");
2014 nSet = (UINT)uCount;
2015 if(nSet > lpResults->nGlyphs)
2016 nSet = lpResults->nGlyphs;
2018 /* return number of initialized fields */
2019 lpResults->nGlyphs = nSet;
2021 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
2023 /* Treat the case where no special handling was requested in a fastpath way */
2024 /* copy will do if the GCP_REORDER flag is not set */
2025 if(lpResults->lpOutString)
2026 strncpyW( lpResults->lpOutString, lpString, nSet );
2028 if(lpResults->lpOrder)
2030 for(i = 0; i < nSet; i++)
2031 lpResults->lpOrder[i] = i;
2033 } else
2035 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2036 nSet, lpResults->lpOrder );
2039 /* FIXME: Will use the placement chars */
2040 if (lpResults->lpDx)
2042 int c;
2043 for (i = 0; i < nSet; i++)
2045 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2046 lpResults->lpDx[i]= c;
2050 if(lpResults->lpGlyphs)
2051 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2053 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2054 ret = MAKELONG(size.cx, size.cy);
2056 return ret;
2059 /*************************************************************************
2060 * GetCharABCWidthsFloatA [GDI32.@]
2062 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2063 LPABCFLOAT lpABCF)
2065 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2066 return 0;
2069 /*************************************************************************
2070 * GetCharABCWidthsFloatW [GDI32.@]
2072 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2073 UINT iLastChar, LPABCFLOAT lpABCF)
2075 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2076 return 0;
2079 /*************************************************************************
2080 * GetCharWidthFloatA [GDI32.@]
2082 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2083 UINT iLastChar, PFLOAT pxBuffer)
2085 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2086 return 0;
2089 /*************************************************************************
2090 * GetCharWidthFloatW [GDI32.@]
2092 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2093 UINT iLastChar, PFLOAT pxBuffer)
2095 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2096 return 0;
2100 /***********************************************************************
2102 * Font Resource API *
2104 ***********************************************************************/
2106 /***********************************************************************
2107 * AddFontResourceA (GDI32.@)
2109 INT WINAPI AddFontResourceA( LPCSTR str )
2111 return AddFontResourceExA( str, 0, NULL);
2114 /***********************************************************************
2115 * AddFontResourceW (GDI32.@)
2117 INT WINAPI AddFontResourceW( LPCWSTR str )
2119 return AddFontResourceExW(str, 0, NULL);
2123 /***********************************************************************
2124 * AddFontResourceExA (GDI32.@)
2126 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2128 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2129 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2130 INT ret;
2132 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2133 ret = AddFontResourceExW(strW, fl, pdv);
2134 HeapFree(GetProcessHeap(), 0, strW);
2135 return ret;
2138 /***********************************************************************
2139 * AddFontResourceExW (GDI32.@)
2141 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2143 return WineEngAddFontResourceEx(str, fl, pdv);
2146 /***********************************************************************
2147 * RemoveFontResourceA (GDI32.@)
2149 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2151 return RemoveFontResourceExA(str, 0, 0);
2154 /***********************************************************************
2155 * RemoveFontResourceW (GDI32.@)
2157 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2159 return RemoveFontResourceExW(str, 0, 0);
2162 /***********************************************************************
2163 * RemoveFontResourceExA (GDI32.@)
2165 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2167 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2168 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2169 INT ret;
2171 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2172 ret = RemoveFontResourceExW(strW, fl, pdv);
2173 HeapFree(GetProcessHeap(), 0, strW);
2174 return ret;
2177 /***********************************************************************
2178 * RemoveFontResourceExW (GDI32.@)
2180 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2182 return WineEngRemoveFontResourceEx(str, fl, pdv);
2185 /***********************************************************************
2186 * GetTextCharset (GDI32.@)
2188 UINT WINAPI GetTextCharset(HDC hdc)
2190 /* MSDN docs say this is equivalent */
2191 return GetTextCharsetInfo(hdc, NULL, 0);
2194 /***********************************************************************
2195 * GetTextCharsetInfo (GDI32.@)
2197 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2199 UINT ret = DEFAULT_CHARSET;
2200 DC *dc = DC_GetDCPtr(hdc);
2202 if (!dc) goto done;
2204 if (dc->gdiFont)
2205 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2207 GDI_ReleaseObj(hdc);
2209 done:
2210 if (ret == DEFAULT_CHARSET && fs)
2211 memset(fs, 0, sizeof(FONTSIGNATURE));
2212 return ret;