Added partial support for function pointers.
[wine/multimedia.git] / objects / font.c
blobdb1950fa234a8f8bbe8151a3777eb9d3bb72125a
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 "winbase.h"
31 #include "winnls.h"
32 #include "wownt32.h"
33 #include "gdi.h"
34 #include "wine/unicode.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(font);
38 WINE_DECLARE_DEBUG_CHANNEL(gdi);
40 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
41 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
43 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
44 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
46 static const struct gdi_obj_funcs font_funcs =
48 FONT_SelectObject, /* pSelectObject */
49 FONT_GetObject16, /* pGetObject16 */
50 FONT_GetObjectA, /* pGetObjectA */
51 FONT_GetObjectW, /* pGetObjectW */
52 NULL, /* pUnrealizeObject */
53 FONT_DeleteObject /* pDeleteObject */
56 #define ENUM_UNICODE 0x00000001
57 #define ENUM_CALLED 0x00000002
59 typedef struct
61 GDIOBJHDR header;
62 LOGFONTW logfont;
63 } FONTOBJ;
65 typedef struct
67 LPLOGFONT16 lpLogFontParam;
68 FONTENUMPROC16 lpEnumFunc;
69 LPARAM lpData;
71 LPNEWTEXTMETRICEX16 lpTextMetric;
72 LPENUMLOGFONTEX16 lpLogFont;
73 SEGPTR segTextMetric;
74 SEGPTR segLogFont;
75 DWORD dwFlags;
76 HDC hdc;
77 DC *dc;
78 PHYSDEV physDev;
79 } fontEnum16;
81 typedef struct
83 LPLOGFONTW lpLogFontParam;
84 FONTENUMPROCW lpEnumFunc;
85 LPARAM lpData;
86 DWORD dwFlags;
87 HDC hdc;
88 DC *dc;
89 PHYSDEV physDev;
90 } fontEnum32;
93 * For TranslateCharsetInfo
95 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
96 #define MAXTCIINDEX 32
97 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
98 /* ANSI */
99 { ANSI_CHARSET, 1252, FS(0)},
100 { EASTEUROPE_CHARSET, 1250, FS(1)},
101 { RUSSIAN_CHARSET, 1251, FS(2)},
102 { GREEK_CHARSET, 1253, FS(3)},
103 { TURKISH_CHARSET, 1254, FS(4)},
104 { HEBREW_CHARSET, 1255, FS(5)},
105 { ARABIC_CHARSET, 1256, FS(6)},
106 { BALTIC_CHARSET, 1257, FS(7)},
107 { VIETNAMESE_CHARSET, 1258, FS(8)},
108 /* reserved by ANSI */
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 { DEFAULT_CHARSET, 0, FS(0)},
116 /* ANSI and OEM */
117 { THAI_CHARSET, 874, FS(16)},
118 { SHIFTJIS_CHARSET, 932, FS(17)},
119 { GB2312_CHARSET, 936, FS(18)},
120 { HANGEUL_CHARSET, 949, FS(19)},
121 { CHINESEBIG5_CHARSET, 950, FS(20)},
122 { JOHAB_CHARSET, 1361, FS(21)},
123 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
132 /* reserved for system */
133 { DEFAULT_CHARSET, 0, FS(0)},
134 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
137 /***********************************************************************
138 * LOGFONT conversion functions.
140 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
142 font16->lfHeight = font32->lfHeight;
143 font16->lfWidth = font32->lfWidth;
144 font16->lfEscapement = font32->lfEscapement;
145 font16->lfOrientation = font32->lfOrientation;
146 font16->lfWeight = font32->lfWeight;
147 font16->lfItalic = font32->lfItalic;
148 font16->lfUnderline = font32->lfUnderline;
149 font16->lfStrikeOut = font32->lfStrikeOut;
150 font16->lfCharSet = font32->lfCharSet;
151 font16->lfOutPrecision = font32->lfOutPrecision;
152 font16->lfClipPrecision = font32->lfClipPrecision;
153 font16->lfQuality = font32->lfQuality;
154 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
155 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
156 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
157 font16->lfFaceName[LF_FACESIZE-1] = 0;
160 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
162 font32->lfHeight = font16->lfHeight;
163 font32->lfWidth = font16->lfWidth;
164 font32->lfEscapement = font16->lfEscapement;
165 font32->lfOrientation = font16->lfOrientation;
166 font32->lfWeight = font16->lfWeight;
167 font32->lfItalic = font16->lfItalic;
168 font32->lfUnderline = font16->lfUnderline;
169 font32->lfStrikeOut = font16->lfStrikeOut;
170 font32->lfCharSet = font16->lfCharSet;
171 font32->lfOutPrecision = font16->lfOutPrecision;
172 font32->lfClipPrecision = font16->lfClipPrecision;
173 font32->lfQuality = font16->lfQuality;
174 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
175 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
176 font32->lfFaceName[LF_FACESIZE-1] = 0;
179 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
181 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
182 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
183 LF_FACESIZE);
186 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
188 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
189 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
190 LF_FACESIZE, NULL, NULL);
193 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
195 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
197 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
198 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
199 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
200 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
201 font16->elfStyle, LF_FACESIZE, NULL, NULL );
202 font16->elfStyle[LF_FACESIZE-1] = '\0';
203 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
204 font16->elfScript, LF_FACESIZE, NULL, NULL );
205 font16->elfScript[LF_FACESIZE-1] = '\0';
208 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
210 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
212 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
213 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
214 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
215 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
216 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
217 fontA->elfStyle[LF_FACESIZE-1] = '\0';
218 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
219 fontA->elfScript, LF_FACESIZE, NULL, NULL );
220 fontA->elfScript[LF_FACESIZE-1] = '\0';
223 /***********************************************************************
224 * TEXTMETRIC conversion functions.
226 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
228 ptmA->tmHeight = ptmW->tmHeight;
229 ptmA->tmAscent = ptmW->tmAscent;
230 ptmA->tmDescent = ptmW->tmDescent;
231 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
232 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
233 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
234 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
235 ptmA->tmWeight = ptmW->tmWeight;
236 ptmA->tmOverhang = ptmW->tmOverhang;
237 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
238 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
239 ptmA->tmFirstChar = ptmW->tmFirstChar > 255 ? 255 : ptmW->tmFirstChar;
240 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
241 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
242 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : ptmW->tmBreakChar;
243 ptmA->tmItalic = ptmW->tmItalic;
244 ptmA->tmUnderlined = ptmW->tmUnderlined;
245 ptmA->tmStruckOut = ptmW->tmStruckOut;
246 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
247 ptmA->tmCharSet = ptmW->tmCharSet;
251 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
253 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
254 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
255 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
256 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
257 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
258 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
259 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
260 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
261 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
262 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
263 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
264 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
265 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
266 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
267 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
268 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
269 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
270 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
271 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
272 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
273 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
274 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
275 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
276 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
277 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
280 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
282 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
283 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
284 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
285 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
286 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
287 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
290 /***********************************************************************
291 * CreateFontIndirectA (GDI32.@)
293 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
295 LOGFONTW lfW;
297 if (plfA) {
298 FONT_LogFontAToW( plfA, &lfW );
299 return CreateFontIndirectW( &lfW );
300 } else
301 return CreateFontIndirectW( NULL );
305 /***********************************************************************
306 * CreateFontIndirectW (GDI32.@)
308 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
310 HFONT hFont = 0;
312 if (plf)
314 FONTOBJ* fontPtr;
315 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
316 (HGDIOBJ *)&hFont, &font_funcs )))
318 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
320 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
321 plf->lfHeight, plf->lfWidth,
322 plf->lfEscapement, plf->lfOrientation,
323 plf->lfPitchAndFamily,
324 plf->lfOutPrecision, plf->lfClipPrecision,
325 plf->lfQuality, plf->lfCharSet,
326 debugstr_w(plf->lfFaceName),
327 plf->lfWeight > 400 ? "Bold" : "",
328 plf->lfItalic ? "Italic" : "", hFont);
330 if (plf->lfEscapement != plf->lfOrientation) {
331 /* this should really depend on whether GM_ADVANCED is set */
332 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
333 WARN("orientation angle %f set to "
334 "escapement angle %f for new font %p\n",
335 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
337 GDI_ReleaseObj( hFont );
340 else WARN("(NULL) => NULL\n");
342 return hFont;
345 /*************************************************************************
346 * CreateFontA (GDI32.@)
348 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
349 INT orient, INT weight, DWORD italic,
350 DWORD underline, DWORD strikeout, DWORD charset,
351 DWORD outpres, DWORD clippres, DWORD quality,
352 DWORD pitch, LPCSTR name )
354 LOGFONTA logfont;
356 logfont.lfHeight = height;
357 logfont.lfWidth = width;
358 logfont.lfEscapement = esc;
359 logfont.lfOrientation = orient;
360 logfont.lfWeight = weight;
361 logfont.lfItalic = italic;
362 logfont.lfUnderline = underline;
363 logfont.lfStrikeOut = strikeout;
364 logfont.lfCharSet = charset;
365 logfont.lfOutPrecision = outpres;
366 logfont.lfClipPrecision = clippres;
367 logfont.lfQuality = quality;
368 logfont.lfPitchAndFamily = pitch;
370 if (name)
371 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
372 else
373 logfont.lfFaceName[0] = '\0';
375 return CreateFontIndirectA( &logfont );
378 /*************************************************************************
379 * CreateFontW (GDI32.@)
381 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
382 INT orient, INT weight, DWORD italic,
383 DWORD underline, DWORD strikeout, DWORD charset,
384 DWORD outpres, DWORD clippres, DWORD quality,
385 DWORD pitch, LPCWSTR name )
387 LOGFONTW logfont;
389 logfont.lfHeight = height;
390 logfont.lfWidth = width;
391 logfont.lfEscapement = esc;
392 logfont.lfOrientation = orient;
393 logfont.lfWeight = weight;
394 logfont.lfItalic = italic;
395 logfont.lfUnderline = underline;
396 logfont.lfStrikeOut = strikeout;
397 logfont.lfCharSet = charset;
398 logfont.lfOutPrecision = outpres;
399 logfont.lfClipPrecision = clippres;
400 logfont.lfQuality = quality;
401 logfont.lfPitchAndFamily = pitch;
403 if (name)
404 lstrcpynW(logfont.lfFaceName, name,
405 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
406 else
407 logfont.lfFaceName[0] = '\0';
409 return CreateFontIndirectW( &logfont );
413 /***********************************************************************
414 * FONT_SelectObject
416 * If the driver supports vector fonts we create a gdi font first and
417 * then call the driver to give it a chance to supply its own device
418 * font. If the driver wants to do this it returns TRUE and we can
419 * delete the gdi font, if the driver wants to use the gdi font it
420 * should return FALSE, to signal an error return GDI_ERROR. For
421 * drivers that don't support vector fonts they must supply their own
422 * font.
424 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
426 HGDIOBJ ret = 0;
427 DC *dc = DC_GetDCPtr( hdc );
429 if (!dc) return 0;
431 if (dc->hFont != handle || dc->gdiFont == NULL)
433 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
434 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
437 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
439 if (ret && dc->gdiFont) dc->gdiFont = 0;
441 if (ret == HGDI_ERROR)
442 ret = 0; /* SelectObject returns 0 on error */
443 else
445 ret = dc->hFont;
446 dc->hFont = handle;
448 GDI_ReleaseObj( hdc );
449 return ret;
453 /***********************************************************************
454 * FONT_GetObject16
456 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
458 FONTOBJ *font = obj;
459 LOGFONT16 lf16;
461 FONT_LogFontWTo16( &font->logfont, &lf16 );
463 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
464 memcpy( buffer, &lf16, count );
465 return count;
468 /***********************************************************************
469 * FONT_GetObjectA
471 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
473 FONTOBJ *font = obj;
474 LOGFONTA lfA;
476 if(!buffer)
477 return sizeof(lfA);
478 FONT_LogFontWToA( &font->logfont, &lfA );
480 if (count > sizeof(lfA)) count = sizeof(lfA);
481 memcpy( buffer, &lfA, count );
482 return count;
485 /***********************************************************************
486 * FONT_GetObjectW
488 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
490 FONTOBJ *font = obj;
491 if(!buffer)
492 return sizeof(LOGFONTW);
493 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
494 memcpy( buffer, &font->logfont, count );
495 return count;
499 /***********************************************************************
500 * FONT_DeleteObject
502 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
504 WineEngDestroyFontInstance( handle );
505 return GDI_FreeObject( handle, obj );
509 /***********************************************************************
510 * FONT_EnumInstance16
512 * Called by the device driver layer to pass font info
513 * down to the application.
515 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
516 DWORD fType, LPARAM lp )
518 fontEnum16 *pfe = (fontEnum16*)lp;
519 INT ret = 1;
520 DC *dc;
522 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
523 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
525 WORD args[7];
526 DWORD result;
528 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
529 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
530 pfe->dwFlags |= ENUM_CALLED;
531 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
533 args[6] = SELECTOROF(pfe->segLogFont);
534 args[5] = OFFSETOF(pfe->segLogFont);
535 args[4] = SELECTOROF(pfe->segTextMetric);
536 args[3] = OFFSETOF(pfe->segTextMetric);
537 args[2] = fType;
538 args[1] = HIWORD(pfe->lpData);
539 args[0] = LOWORD(pfe->lpData);
540 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
541 ret = LOWORD(result);
543 /* get the lock again and make sure the DC is still valid */
544 dc = DC_GetDCPtr( pfe->hdc );
545 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
547 if (dc) GDI_ReleaseObj( pfe->hdc );
548 pfe->hdc = 0; /* make sure we don't try to release it later on */
549 ret = 0;
552 return ret;
555 /***********************************************************************
556 * FONT_EnumInstance
558 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
559 DWORD fType, LPARAM lp )
561 fontEnum32 *pfe = (fontEnum32*)lp;
562 INT ret = 1;
563 DC *dc;
565 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
566 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
567 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
569 /* convert font metrics */
570 ENUMLOGFONTEXA logfont;
571 NEWTEXTMETRICEXA tmA;
573 pfe->dwFlags |= ENUM_CALLED;
574 if (!(pfe->dwFlags & ENUM_UNICODE))
576 FONT_EnumLogFontExWToA( plf, &logfont);
577 FONT_NewTextMetricExWToA( ptm, &tmA );
578 plf = (LPENUMLOGFONTEXW)&logfont;
579 ptm = (NEWTEXTMETRICEXW *)&tmA;
581 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
583 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
585 /* get the lock again and make sure the DC is still valid */
586 dc = DC_GetDCPtr( pfe->hdc );
587 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
589 if (dc) GDI_ReleaseObj( pfe->hdc );
590 pfe->hdc = 0; /* make sure we don't try to release it later on */
591 ret = 0;
594 return ret;
597 /***********************************************************************
598 * EnumFontFamiliesEx (GDI.613)
600 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
601 FONTENUMPROC16 efproc, LPARAM lParam,
602 DWORD dwFlags)
604 fontEnum16 fe16;
605 INT16 ret = 1, ret2;
606 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
607 NEWTEXTMETRICEX16 tm16;
608 ENUMLOGFONTEX16 lf16;
609 LOGFONTW lfW;
610 BOOL enum_gdi_fonts;
612 if (!dc) return 0;
613 FONT_LogFont16ToW(plf, &lfW);
615 fe16.hdc = HDC_32(hDC);
616 fe16.dc = dc;
617 fe16.physDev = dc->physDev;
618 fe16.lpLogFontParam = plf;
619 fe16.lpEnumFunc = efproc;
620 fe16.lpData = lParam;
621 fe16.lpTextMetric = &tm16;
622 fe16.lpLogFont = &lf16;
623 fe16.segTextMetric = MapLS( &tm16 );
624 fe16.segLogFont = MapLS( &lf16 );
625 fe16.dwFlags = 0;
627 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
629 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
631 ret = 0;
632 goto done;
635 if (enum_gdi_fonts)
636 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
637 fe16.dwFlags &= ~ENUM_CALLED;
638 if (ret && dc->funcs->pEnumDeviceFonts) {
639 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
640 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
641 ret = ret2;
643 done:
644 UnMapLS( fe16.segTextMetric );
645 UnMapLS( fe16.segLogFont );
646 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
647 return ret;
650 /***********************************************************************
651 * FONT_EnumFontFamiliesEx
653 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
654 FONTENUMPROCW efproc,
655 LPARAM lParam, DWORD dwUnicode)
657 INT ret = 1, ret2;
658 DC *dc = DC_GetDCPtr( hDC );
659 fontEnum32 fe32;
660 BOOL enum_gdi_fonts;
662 if (!dc) return 0;
664 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
665 plf->lfCharSet);
666 fe32.lpLogFontParam = plf;
667 fe32.lpEnumFunc = efproc;
668 fe32.lpData = lParam;
669 fe32.dwFlags = dwUnicode;
670 fe32.hdc = hDC;
671 fe32.dc = dc;
672 fe32.physDev = dc->physDev;
674 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
676 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
678 ret = 0;
679 goto done;
682 if (enum_gdi_fonts)
683 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
684 fe32.dwFlags &= ~ENUM_CALLED;
685 if (ret && dc->funcs->pEnumDeviceFonts) {
686 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
687 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
688 ret = ret2;
690 done:
691 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
692 return ret;
695 /***********************************************************************
696 * EnumFontFamiliesExW (GDI32.@)
698 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
699 FONTENUMPROCW efproc,
700 LPARAM lParam, DWORD dwFlags )
702 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
705 /***********************************************************************
706 * EnumFontFamiliesExA (GDI32.@)
708 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
709 FONTENUMPROCA efproc,
710 LPARAM lParam, DWORD dwFlags)
712 LOGFONTW lfW;
713 FONT_LogFontAToW( plf, &lfW );
715 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
718 /***********************************************************************
719 * EnumFontFamilies (GDI.330)
721 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
722 FONTENUMPROC16 efproc, LPARAM lpData )
724 LOGFONT16 lf;
726 lf.lfCharSet = DEFAULT_CHARSET;
727 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
728 else lf.lfFaceName[0] = '\0';
730 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
733 /***********************************************************************
734 * EnumFontFamiliesA (GDI32.@)
736 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
737 FONTENUMPROCA efproc, LPARAM lpData )
739 LOGFONTA lf;
741 lf.lfCharSet = DEFAULT_CHARSET;
742 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
743 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
745 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
748 /***********************************************************************
749 * EnumFontFamiliesW (GDI32.@)
751 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
752 FONTENUMPROCW efproc, LPARAM lpData )
754 LOGFONTW lf;
756 lf.lfCharSet = DEFAULT_CHARSET;
757 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
758 else lf.lfFaceName[0] = 0;
760 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
763 /***********************************************************************
764 * EnumFonts (GDI.70)
766 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
767 LPARAM lpData )
769 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
772 /***********************************************************************
773 * EnumFontsA (GDI32.@)
775 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
776 LPARAM lpData )
778 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
781 /***********************************************************************
782 * EnumFontsW (GDI32.@)
784 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
785 LPARAM lpData )
787 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
791 /***********************************************************************
792 * GetTextCharacterExtra (GDI32.@)
794 INT WINAPI GetTextCharacterExtra( HDC hdc )
796 INT ret;
797 DC *dc = DC_GetDCPtr( hdc );
798 if (!dc) return 0x80000000;
799 ret = dc->charExtra;
800 GDI_ReleaseObj( hdc );
801 return ret;
805 /***********************************************************************
806 * SetTextCharacterExtra (GDI32.@)
808 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
810 INT prev;
811 DC * dc = DC_GetDCPtr( hdc );
812 if (!dc) return 0x80000000;
813 if (dc->funcs->pSetTextCharacterExtra)
814 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
815 else
817 prev = dc->charExtra;
818 dc->charExtra = extra;
820 GDI_ReleaseObj( hdc );
821 return prev;
825 /***********************************************************************
826 * SetTextJustification (GDI32.@)
828 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
830 BOOL ret = TRUE;
831 DC * dc = DC_GetDCPtr( hdc );
832 if (!dc) return FALSE;
833 if (dc->funcs->pSetTextJustification)
834 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
835 else
837 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
838 if (!extra) breaks = 0;
839 dc->breakTotalExtra = extra;
840 dc->breakCount = breaks;
841 if (breaks)
843 dc->breakExtra = extra / breaks;
844 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
846 else
848 dc->breakExtra = 0;
849 dc->breakRem = 0;
852 GDI_ReleaseObj( hdc );
853 return ret;
857 /***********************************************************************
858 * GetTextFaceA (GDI32.@)
860 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
862 INT res = GetTextFaceW(hdc, 0, NULL);
863 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
864 GetTextFaceW( hdc, res, nameW );
866 if (name)
868 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
869 name[count-1] = 0;
870 res = strlen(name);
872 else
873 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
874 HeapFree( GetProcessHeap(), 0, nameW );
875 return res;
878 /***********************************************************************
879 * GetTextFaceW (GDI32.@)
881 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
883 FONTOBJ *font;
884 INT ret = 0;
886 DC * dc = DC_GetDCPtr( hdc );
887 if (!dc) return 0;
889 if(dc->gdiFont)
890 ret = WineEngGetTextFace(dc->gdiFont, count, name);
891 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
893 if (name)
895 lstrcpynW( name, font->logfont.lfFaceName, count );
896 ret = strlenW(name);
898 else ret = strlenW(font->logfont.lfFaceName) + 1;
899 GDI_ReleaseObj( dc->hFont );
901 GDI_ReleaseObj( hdc );
902 return ret;
906 /***********************************************************************
907 * GetTextExtentPoint32A (GDI32.@)
909 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
910 LPSIZE size )
912 BOOL ret = FALSE;
913 INT wlen;
914 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
916 if (p) {
917 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
918 HeapFree( GetProcessHeap(), 0, p );
921 TRACE("(%p %s %d %p): returning %ld x %ld\n",
922 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
923 return ret;
927 /***********************************************************************
928 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
930 * Computes width and height of the specified string.
932 * RETURNS
933 * Success: TRUE
934 * Failure: FALSE
936 BOOL WINAPI GetTextExtentPoint32W(
937 HDC hdc, /* [in] Handle of device context */
938 LPCWSTR str, /* [in] Address of text string */
939 INT count, /* [in] Number of characters in string */
940 LPSIZE size) /* [out] Address of structure for string size */
942 BOOL ret = FALSE;
943 DC * dc = DC_GetDCPtr( hdc );
944 if (!dc) return FALSE;
946 if(dc->gdiFont) {
947 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
948 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
949 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
951 else if(dc->funcs->pGetTextExtentPoint)
952 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
954 GDI_ReleaseObj( hdc );
956 TRACE("(%p %s %d %p): returning %ld x %ld\n",
957 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
958 return ret;
961 /***********************************************************************
962 * GetTextExtentPointI [GDI32.@]
964 * Computes width and height of the array of glyph indices.
966 * RETURNS
967 * Success: TRUE
968 * Failure: FALSE
970 BOOL WINAPI GetTextExtentPointI(
971 HDC hdc, /* [in] Handle of device context */
972 const WORD *indices, /* [in] Address of glyph index array */
973 INT count, /* [in] Number of glyphs in array */
974 LPSIZE size) /* [out] Address of structure for string size */
976 BOOL ret = FALSE;
977 DC * dc = DC_GetDCPtr( hdc );
978 if (!dc) return FALSE;
980 if(dc->gdiFont) {
981 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
982 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
983 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
985 else if(dc->funcs->pGetTextExtentPoint) {
986 FIXME("calling GetTextExtentPoint\n");
987 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
990 GDI_ReleaseObj( hdc );
992 TRACE("(%p %p %d %p): returning %ld x %ld\n",
993 hdc, indices, count, size, size->cx, size->cy );
994 return ret;
998 /***********************************************************************
999 * GetTextExtentPointA (GDI32.@)
1001 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1002 LPSIZE size )
1004 TRACE("not bug compatible.\n");
1005 return GetTextExtentPoint32A( hdc, str, count, size );
1008 /***********************************************************************
1009 * GetTextExtentPointW (GDI32.@)
1011 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1012 LPSIZE size )
1014 TRACE("not bug compatible.\n");
1015 return GetTextExtentPoint32W( hdc, str, count, size );
1019 /***********************************************************************
1020 * GetTextExtentExPointA (GDI32.@)
1022 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1023 INT maxExt, LPINT lpnFit,
1024 LPINT alpDx, LPSIZE size )
1026 BOOL ret;
1027 INT wlen;
1028 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1029 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1030 HeapFree( GetProcessHeap(), 0, p );
1031 return ret;
1035 /***********************************************************************
1036 * GetTextExtentExPointW (GDI32.@)
1038 * Return the size of the string as it would be if it was output properly by
1039 * e.g. TextOut.
1041 * This should include
1042 * - Intercharacter spacing
1043 * - justification spacing (not yet done)
1044 * - kerning? see below
1046 * Kerning. Since kerning would be carried out by the rendering code it should
1047 * be done by the driver. However they don't support it yet. Also I am not
1048 * yet persuaded that (certainly under Win95) any kerning is actually done.
1050 * str: According to MSDN this should be null-terminated. That is not true; a
1051 * null will not terminate it early.
1052 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1053 * than count. I have seen it be either the size of the full string or
1054 * 1 less than the size of the full string. I have not seen it bear any
1055 * resemblance to the portion that would fit.
1056 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1057 * trailing intercharacter spacing and any trailing justification.
1059 * FIXME
1060 * Currently we do this by measuring each character etc. We should do it by
1061 * passing the request to the driver, perhaps by extending the
1062 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1063 * thinking about kerning issues and rounding issues in the justification.
1066 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1067 INT maxExt, LPINT lpnFit,
1068 LPINT alpDx, LPSIZE size )
1070 int index, nFit, extent;
1071 SIZE tSize;
1072 BOOL ret = FALSE;
1074 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1076 size->cx = size->cy = nFit = extent = 0;
1077 for(index = 0; index < count; index++)
1079 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1080 /* GetTextExtentPoint includes intercharacter spacing. */
1081 /* FIXME - justification needs doing yet. Remember that the base
1082 * data will not be in logical coordinates.
1084 extent += tSize.cx;
1085 if( !lpnFit || extent <= maxExt )
1086 /* It is allowed to be equal. */
1088 nFit++;
1089 if( alpDx ) alpDx[index] = extent;
1091 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1092 str++;
1094 size->cx = extent;
1095 if(lpnFit) *lpnFit = nFit;
1096 ret = TRUE;
1098 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1100 done:
1101 return ret;
1104 /***********************************************************************
1105 * GetTextMetricsA (GDI32.@)
1107 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1109 TEXTMETRICW tm32;
1111 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1112 FONT_TextMetricWToA( &tm32, metrics );
1113 return TRUE;
1116 /***********************************************************************
1117 * GetTextMetricsW (GDI32.@)
1119 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1121 BOOL ret = FALSE;
1122 DC * dc = DC_GetDCPtr( hdc );
1123 if (!dc) return FALSE;
1125 if (dc->gdiFont)
1126 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1127 else if (dc->funcs->pGetTextMetrics)
1128 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1130 if (ret)
1132 /* device layer returns values in device units
1133 * therefore we have to convert them to logical */
1135 #define WDPTOLP(x) ((x<0)? \
1136 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1137 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1138 #define HDPTOLP(y) ((y<0)? \
1139 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1140 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1142 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1143 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1144 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1145 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1146 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1147 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1148 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1149 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1150 ret = TRUE;
1151 #undef WDPTOLP
1152 #undef HDPTOLP
1153 TRACE("text metrics:\n"
1154 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1155 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1156 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1157 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1158 " PitchAndFamily = %02x\n"
1159 " --------------------\n"
1160 " InternalLeading = %li\n"
1161 " Ascent = %li\n"
1162 " Descent = %li\n"
1163 " Height = %li\n",
1164 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1165 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1166 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1167 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1168 metrics->tmPitchAndFamily,
1169 metrics->tmInternalLeading,
1170 metrics->tmAscent,
1171 metrics->tmDescent,
1172 metrics->tmHeight );
1174 GDI_ReleaseObj( hdc );
1175 return ret;
1179 /***********************************************************************
1180 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1182 * NOTES
1183 * lpOTM should be LPOUTLINETEXTMETRIC
1185 * RETURNS
1186 * Success: Non-zero or size of required buffer
1187 * Failure: 0
1189 UINT16 WINAPI GetOutlineTextMetrics16(
1190 HDC16 hdc, /* [in] Handle of device context */
1191 UINT16 cbData, /* [in] Size of metric data array */
1192 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1194 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1195 return 0;
1199 /***********************************************************************
1200 * GetOutlineTextMetricsA (GDI32.@)
1201 * Gets metrics for TrueType fonts.
1204 * RETURNS
1205 * Success: Non-zero or size of required buffer
1206 * Failure: 0
1208 UINT WINAPI GetOutlineTextMetricsA(
1209 HDC hdc, /* [in] Handle of device context */
1210 UINT cbData, /* [in] Size of metric data array */
1211 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1213 char buf[512], *ptr;
1214 UINT ret, needed;
1215 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1216 INT left, len;
1218 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1219 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1220 return 0;
1221 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1222 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1225 needed = sizeof(OUTLINETEXTMETRICA);
1226 if(lpOTMW->otmpFamilyName)
1227 needed += WideCharToMultiByte(CP_ACP, 0,
1228 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1229 NULL, 0, NULL, NULL);
1230 if(lpOTMW->otmpFaceName)
1231 needed += WideCharToMultiByte(CP_ACP, 0,
1232 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1233 NULL, 0, NULL, NULL);
1234 if(lpOTMW->otmpStyleName)
1235 needed += WideCharToMultiByte(CP_ACP, 0,
1236 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1237 NULL, 0, NULL, NULL);
1238 if(lpOTMW->otmpFullName)
1239 needed += WideCharToMultiByte(CP_ACP, 0,
1240 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1241 NULL, 0, NULL, NULL);
1243 if(!lpOTM) {
1244 ret = needed;
1245 goto end;
1248 if(needed > cbData) {
1249 ret = 0;
1250 goto end;
1254 lpOTM->otmSize = needed;
1255 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1256 lpOTM->otmFiller = 0;
1257 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1258 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1259 lpOTM->otmfsType = lpOTMW->otmfsType;
1260 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1261 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1262 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1263 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1264 lpOTM->otmAscent = lpOTMW->otmAscent;
1265 lpOTM->otmDescent = lpOTMW->otmDescent;
1266 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1267 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1268 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1269 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1270 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1271 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1272 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1273 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1274 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1275 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1276 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1277 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1278 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1279 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1280 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1281 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1284 ptr = (char*)(lpOTM + 1);
1285 left = needed - sizeof(*lpOTM);
1287 if(lpOTMW->otmpFamilyName) {
1288 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1289 len = WideCharToMultiByte(CP_ACP, 0,
1290 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1291 ptr, left, NULL, NULL);
1292 left -= len;
1293 ptr += len;
1294 } else
1295 lpOTM->otmpFamilyName = 0;
1297 if(lpOTMW->otmpFaceName) {
1298 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1299 len = WideCharToMultiByte(CP_ACP, 0,
1300 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1301 ptr, left, NULL, NULL);
1302 left -= len;
1303 ptr += len;
1304 } else
1305 lpOTM->otmpFaceName = 0;
1307 if(lpOTMW->otmpStyleName) {
1308 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1309 len = WideCharToMultiByte(CP_ACP, 0,
1310 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1311 ptr, left, NULL, NULL);
1312 left -= len;
1313 ptr += len;
1314 } else
1315 lpOTM->otmpStyleName = 0;
1317 if(lpOTMW->otmpFullName) {
1318 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1319 len = WideCharToMultiByte(CP_ACP, 0,
1320 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1321 ptr, left, NULL, NULL);
1322 left -= len;
1323 } else
1324 lpOTM->otmpFullName = 0;
1326 assert(left == 0);
1328 ret = needed;
1330 end:
1331 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1332 HeapFree(GetProcessHeap(), 0, lpOTMW);
1334 return ret;
1338 /***********************************************************************
1339 * GetOutlineTextMetricsW [GDI32.@]
1341 UINT WINAPI GetOutlineTextMetricsW(
1342 HDC hdc, /* [in] Handle of device context */
1343 UINT cbData, /* [in] Size of metric data array */
1344 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1346 DC *dc = DC_GetDCPtr( hdc );
1347 UINT ret;
1349 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1350 if(!dc) return 0;
1352 if(dc->gdiFont) {
1353 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1354 if(ret && ret <= cbData) {
1355 #define WDPTOLP(x) ((x<0)? \
1356 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1357 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1358 #define HDPTOLP(y) ((y<0)? \
1359 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1360 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1362 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1363 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1364 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1365 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1366 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1367 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1368 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1369 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1370 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1371 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1372 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1373 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1374 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1375 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1376 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1377 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1378 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1379 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1380 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1381 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1382 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1383 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1384 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1385 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1386 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1387 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1388 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1389 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1390 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1391 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1392 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1393 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1394 #undef WDPTOLP
1395 #undef HDPTOLP
1399 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1400 but really this should just be a return 0. */
1402 ret = sizeof(*lpOTM);
1403 if (lpOTM) {
1404 if(cbData < ret)
1405 ret = 0;
1406 else {
1407 memset(lpOTM, 0, ret);
1408 lpOTM->otmSize = sizeof(*lpOTM);
1409 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1411 Further fill of the structure not implemented,
1412 Needs real values for the structure members
1417 GDI_ReleaseObj(hdc);
1418 return ret;
1422 /***********************************************************************
1423 * GetCharWidthW (GDI32.@)
1424 * GetCharWidth32W (GDI32.@)
1426 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1427 LPINT buffer )
1429 UINT i;
1430 BOOL ret = FALSE;
1431 DC * dc = DC_GetDCPtr( hdc );
1432 if (!dc) return FALSE;
1434 if (dc->gdiFont)
1435 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1436 else if (dc->funcs->pGetCharWidth)
1437 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1439 if (ret)
1441 /* convert device units to logical */
1442 for( i = firstChar; i <= lastChar; i++, buffer++ )
1443 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1444 ret = TRUE;
1446 GDI_ReleaseObj( hdc );
1447 return ret;
1451 /***********************************************************************
1452 * GetCharWidthA (GDI32.@)
1453 * GetCharWidth32A (GDI32.@)
1455 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1456 LPINT buffer )
1458 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1459 LPSTR str;
1460 LPWSTR wstr;
1461 BOOL ret = TRUE;
1463 if(count <= 0) return FALSE;
1465 str = HeapAlloc(GetProcessHeap(), 0, count);
1466 for(i = 0; i < count; i++)
1467 str[i] = (BYTE)(firstChar + i);
1469 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1471 for(i = 0; i < wlen; i++)
1473 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1475 ret = FALSE;
1476 break;
1478 buffer++;
1481 HeapFree(GetProcessHeap(), 0, str);
1482 HeapFree(GetProcessHeap(), 0, wstr);
1484 return ret;
1488 /* FIXME: all following APIs ******************************************/
1491 /***********************************************************************
1492 * SetMapperFlags (GDI32.@)
1494 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1496 DC *dc = DC_GetDCPtr( hDC );
1497 DWORD ret = 0;
1498 if(!dc) return 0;
1499 if(dc->funcs->pSetMapperFlags)
1500 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1501 else
1502 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1503 GDI_ReleaseObj( hDC );
1504 return ret;
1507 /***********************************************************************
1508 * GetAspectRatioFilterEx (GDI.486)
1510 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1512 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1513 return FALSE;
1516 /***********************************************************************
1517 * GetAspectRatioFilterEx (GDI32.@)
1519 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1521 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1522 return FALSE;
1526 /***********************************************************************
1527 * GetCharABCWidthsA (GDI32.@)
1529 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1530 LPABC abc )
1532 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1533 LPSTR str;
1534 LPWSTR wstr;
1535 BOOL ret = TRUE;
1537 if(count <= 0) return FALSE;
1539 str = HeapAlloc(GetProcessHeap(), 0, count);
1540 for(i = 0; i < count; i++)
1541 str[i] = (BYTE)(firstChar + i);
1543 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1545 for(i = 0; i < wlen; i++)
1547 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1549 ret = FALSE;
1550 break;
1552 abc++;
1555 HeapFree(GetProcessHeap(), 0, str);
1556 HeapFree(GetProcessHeap(), 0, wstr);
1558 return ret;
1562 /******************************************************************************
1563 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1565 * PARAMS
1566 * hdc [I] Handle of device context
1567 * firstChar [I] First character in range to query
1568 * lastChar [I] Last character in range to query
1569 * abc [O] Address of character-width structure
1571 * NOTES
1572 * Only works with TrueType fonts
1574 * RETURNS
1575 * Success: TRUE
1576 * Failure: FALSE
1578 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1579 LPABC abc )
1581 DC *dc = DC_GetDCPtr(hdc);
1582 int i;
1583 GLYPHMETRICS gm;
1584 BOOL ret = FALSE;
1586 if(dc->gdiFont) {
1587 for (i=firstChar;i<=lastChar;i++) {
1588 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1589 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1590 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1591 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1593 ret = TRUE;
1595 GDI_ReleaseObj(hdc);
1596 return ret;
1600 /***********************************************************************
1601 * GetGlyphOutline (GDI.309)
1603 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1604 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1605 LPVOID lpBuffer, const MAT2 *lpmat2 )
1607 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1608 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1609 return (DWORD)-1; /* failure */
1613 /***********************************************************************
1614 * GetGlyphOutlineA (GDI32.@)
1616 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1617 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1618 LPVOID lpBuffer, const MAT2 *lpmat2 )
1620 LPWSTR p = NULL;
1621 DWORD ret;
1622 UINT c;
1624 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1625 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1626 c = p[0];
1627 } else
1628 c = uChar;
1629 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1630 lpmat2);
1631 if(p)
1632 HeapFree(GetProcessHeap(), 0, p);
1633 return ret;
1636 /***********************************************************************
1637 * GetGlyphOutlineW (GDI32.@)
1639 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1640 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1641 LPVOID lpBuffer, const MAT2 *lpmat2 )
1643 DC *dc = DC_GetDCPtr(hdc);
1644 DWORD ret;
1646 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1647 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1649 if(!dc) return GDI_ERROR;
1651 if(dc->gdiFont)
1652 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1653 cbBuffer, lpBuffer, lpmat2);
1654 else
1655 ret = GDI_ERROR;
1657 GDI_ReleaseObj(hdc);
1658 return ret;
1662 /***********************************************************************
1663 * CreateScalableFontResourceA (GDI32.@)
1665 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1666 LPCSTR lpszResourceFile,
1667 LPCSTR lpszFontFile,
1668 LPCSTR lpszCurrentPath )
1670 HANDLE f;
1672 /* fHidden=1 - only visible for the calling app, read-only, not
1673 * enumbered with EnumFonts/EnumFontFamilies
1674 * lpszCurrentPath can be NULL
1676 FIXME("(%ld,%s,%s,%s): stub\n",
1677 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1678 debugstr_a(lpszCurrentPath) );
1680 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1681 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1682 CloseHandle(f);
1683 SetLastError(ERROR_FILE_EXISTS);
1684 return FALSE;
1686 return FALSE; /* create failed */
1689 /***********************************************************************
1690 * CreateScalableFontResourceW (GDI32.@)
1692 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1693 LPCWSTR lpszResourceFile,
1694 LPCWSTR lpszFontFile,
1695 LPCWSTR lpszCurrentPath )
1697 FIXME("(%ld,%p,%p,%p): stub\n",
1698 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1699 return FALSE; /* create failed */
1703 /*************************************************************************
1704 * GetRasterizerCaps (GDI32.@)
1706 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1708 lprs->nSize = sizeof(RASTERIZER_STATUS);
1709 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1710 lprs->nLanguageID = 0;
1711 return TRUE;
1715 /*************************************************************************
1716 * GetKerningPairsA (GDI32.@)
1718 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1719 LPKERNINGPAIR lpKerningPairs )
1721 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1725 /*************************************************************************
1726 * GetKerningPairsW (GDI32.@)
1728 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1729 LPKERNINGPAIR lpKerningPairs )
1731 int i;
1732 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1733 for (i = 0; i < cPairs; i++)
1734 lpKerningPairs[i].iKernAmount = 0;
1735 return 0;
1738 /*************************************************************************
1739 * TranslateCharsetInfo [GDI32.@]
1741 * Fills a CHARSETINFO structure for a character set, code page, or
1742 * font. This allows making the correspondance between different labelings
1743 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1744 * of the same encoding.
1746 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1747 * only one codepage should be set in *lpSrc.
1749 * RETURNS
1750 * TRUE on success, FALSE on failure.
1753 BOOL WINAPI TranslateCharsetInfo(
1754 LPDWORD lpSrc, /* [in]
1755 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1756 if flags == TCI_SRCCHARSET: a character set value
1757 if flags == TCI_SRCCODEPAGE: a code page value
1759 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1760 DWORD flags /* [in] determines interpretation of lpSrc */
1762 int index = 0;
1763 switch (flags) {
1764 case TCI_SRCFONTSIG:
1765 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1766 break;
1767 case TCI_SRCCODEPAGE:
1768 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1769 break;
1770 case TCI_SRCCHARSET:
1771 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1772 break;
1773 default:
1774 return FALSE;
1776 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1777 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1778 return TRUE;
1781 /*************************************************************************
1782 * GetFontLanguageInfo (GDI32.@)
1784 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1786 FONTSIGNATURE fontsig;
1787 static const DWORD GCP_DBCS_MASK=0x003F0000,
1788 GCP_DIACRITIC_MASK=0x00000000,
1789 FLI_GLYPHS_MASK=0x00000000,
1790 GCP_GLYPHSHAPE_MASK=0x00000040,
1791 GCP_KASHIDA_MASK=0x00000000,
1792 GCP_LIGATE_MASK=0x00000000,
1793 GCP_USEKERNING_MASK=0x00000000,
1794 GCP_REORDER_MASK=0x00000060;
1796 DWORD result=0;
1798 GetTextCharsetInfo( hdc, &fontsig, 0 );
1799 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1801 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1802 result|=GCP_DBCS;
1804 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1805 result|=GCP_DIACRITIC;
1807 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1808 result|=FLI_GLYPHS;
1810 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1811 result|=GCP_GLYPHSHAPE;
1813 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1814 result|=GCP_KASHIDA;
1816 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1817 result|=GCP_LIGATE;
1819 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1820 result|=GCP_USEKERNING;
1822 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1823 result|=GCP_REORDER;
1825 return result;
1829 /*************************************************************************
1830 * GetFontData [GDI32.@] Retrieve data for TrueType font
1832 * RETURNS
1834 * success: Number of bytes returned
1835 * failure: GDI_ERROR
1837 * NOTES
1839 * Calls SetLastError()
1842 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1843 LPVOID buffer, DWORD length)
1845 DC *dc = DC_GetDCPtr(hdc);
1846 DWORD ret = GDI_ERROR;
1848 if(!dc) return GDI_ERROR;
1850 if(dc->gdiFont)
1851 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1853 GDI_ReleaseObj(hdc);
1854 return ret;
1857 /*************************************************************************
1858 * GetGlyphIndicesA [GDI32.@]
1860 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1861 LPWORD pgi, DWORD flags)
1863 DWORD ret;
1864 WCHAR *lpstrW;
1865 INT countW;
1867 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1868 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1870 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1871 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1872 HeapFree(GetProcessHeap(), 0, lpstrW);
1874 return ret;
1877 /*************************************************************************
1878 * GetGlyphIndicesW [GDI32.@]
1880 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1881 LPWORD pgi, DWORD flags)
1883 DC *dc = DC_GetDCPtr(hdc);
1884 DWORD ret = GDI_ERROR;
1886 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1887 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1889 if(!dc) return GDI_ERROR;
1891 if(dc->gdiFont)
1892 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1894 GDI_ReleaseObj(hdc);
1895 return ret;
1898 /*************************************************************************
1899 * GetCharacterPlacementA [GDI32.@]
1901 * NOTES:
1902 * the web browser control of ie4 calls this with dwFlags=0
1904 DWORD WINAPI
1905 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1906 INT nMaxExtent, GCP_RESULTSA *lpResults,
1907 DWORD dwFlags)
1909 WCHAR *lpStringW;
1910 INT uCountW, i;
1911 GCP_RESULTSW resultsW;
1912 DWORD ret;
1913 UINT font_cp;
1915 TRACE("%s, %d, %d, 0x%08lx\n",
1916 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1918 /* both structs are equal in size */
1919 memcpy(&resultsW, lpResults, sizeof(resultsW));
1921 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1922 if(lpResults->lpOutString)
1923 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1925 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1927 if(lpResults->lpOutString) {
1928 if(font_cp != CP_SYMBOL)
1929 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1930 lpResults->lpOutString, uCount, NULL, NULL );
1931 else
1932 for(i = 0; i < uCount; i++)
1933 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1936 HeapFree(GetProcessHeap(), 0, lpStringW);
1937 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1939 return ret;
1942 /*************************************************************************
1943 * GetCharacterPlacementW [GDI32.@]
1945 * Retrieve information about a string. This includes the width, reordering,
1946 * Glyphing and so on.
1948 * RETURNS
1950 * The width and height of the string if successful, 0 if failed.
1952 * BUGS
1954 * All flags except GCP_REORDER are not yet implemented.
1955 * Reordering is not 100% complient to the Windows BiDi method.
1956 * Caret positioning is not yet implemented.
1957 * Classes are not yet implemented.
1960 DWORD WINAPI
1961 GetCharacterPlacementW(
1962 HDC hdc, /* [in] Device context for which the rendering is to be done */
1963 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1964 INT uCount, /* [in] Number of WORDS in string. */
1965 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1966 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1967 DWORD dwFlags /* [in] Flags specifying how to process the string */
1970 DWORD ret=0;
1971 SIZE size;
1972 UINT i, nSet;
1974 TRACE("%s, %d, %d, 0x%08lx\n",
1975 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1977 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1978 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1979 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1980 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1981 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1983 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1984 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1985 if(lpResults->lpClass) FIXME("classes not implemented\n");
1987 nSet = (UINT)uCount;
1988 if(nSet > lpResults->nGlyphs)
1989 nSet = lpResults->nGlyphs;
1991 /* return number of initialized fields */
1992 lpResults->nGlyphs = nSet;
1994 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1996 /* Treat the case where no special handling was requested in a fastpath way */
1997 /* copy will do if the GCP_REORDER flag is not set */
1998 if(lpResults->lpOutString)
1999 strncpyW( lpResults->lpOutString, lpString, nSet );
2001 if(lpResults->lpOrder)
2003 for(i = 0; i < nSet; i++)
2004 lpResults->lpOrder[i] = i;
2006 } else
2008 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2009 nSet, lpResults->lpOrder );
2012 /* FIXME: Will use the placement chars */
2013 if (lpResults->lpDx)
2015 int c;
2016 for (i = 0; i < nSet; i++)
2018 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2019 lpResults->lpDx[i]= c;
2023 if(lpResults->lpGlyphs)
2024 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2026 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2027 ret = MAKELONG(size.cx, size.cy);
2029 return ret;
2032 /*************************************************************************
2033 * GetCharABCWidthsFloatA [GDI32.@]
2035 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2036 LPABCFLOAT lpABCF)
2038 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2039 return 0;
2042 /*************************************************************************
2043 * GetCharABCWidthsFloatW [GDI32.@]
2045 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2046 UINT iLastChar, LPABCFLOAT lpABCF)
2048 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2049 return 0;
2052 /*************************************************************************
2053 * GetCharWidthFloatA [GDI32.@]
2055 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2056 UINT iLastChar, PFLOAT pxBuffer)
2058 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2059 return 0;
2062 /*************************************************************************
2063 * GetCharWidthFloatW [GDI32.@]
2065 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2066 UINT iLastChar, PFLOAT pxBuffer)
2068 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2069 return 0;
2073 /***********************************************************************
2075 * Font Resource API *
2077 ***********************************************************************/
2079 /***********************************************************************
2080 * AddFontResourceA (GDI32.@)
2082 INT WINAPI AddFontResourceA( LPCSTR str )
2084 return AddFontResourceExA( str, 0, NULL);
2087 /***********************************************************************
2088 * AddFontResourceW (GDI32.@)
2090 INT WINAPI AddFontResourceW( LPCWSTR str )
2092 return AddFontResourceExW(str, 0, NULL);
2096 /***********************************************************************
2097 * AddFontResourceExA (GDI32.@)
2099 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2101 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2102 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2103 INT ret;
2105 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2106 ret = AddFontResourceExW(strW, fl, pdv);
2107 HeapFree(GetProcessHeap(), 0, strW);
2108 return ret;
2111 /***********************************************************************
2112 * AddFontResourceExW (GDI32.@)
2114 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2116 return WineEngAddFontResourceEx(str, fl, pdv);
2119 /***********************************************************************
2120 * RemoveFontResourceA (GDI32.@)
2122 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2124 return RemoveFontResourceExA(str, 0, 0);
2127 /***********************************************************************
2128 * RemoveFontResourceW (GDI32.@)
2130 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2132 return RemoveFontResourceExW(str, 0, 0);
2135 /***********************************************************************
2136 * RemoveFontResourceExA (GDI32.@)
2138 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2140 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2141 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2142 INT ret;
2144 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2145 ret = RemoveFontResourceExW(strW, fl, pdv);
2146 HeapFree(GetProcessHeap(), 0, strW);
2147 return ret;
2150 /***********************************************************************
2151 * RemoveFontResourceExW (GDI32.@)
2153 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2155 return WineEngRemoveFontResourceEx(str, fl, pdv);
2158 /***********************************************************************
2159 * GetTextCharset (GDI32.@)
2161 UINT WINAPI GetTextCharset(HDC hdc)
2163 /* MSDN docs say this is equivalent */
2164 return GetTextCharsetInfo(hdc, NULL, 0);
2167 /***********************************************************************
2168 * GetTextCharsetInfo (GDI32.@)
2170 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2172 UINT ret = DEFAULT_CHARSET;
2173 DC *dc = DC_GetDCPtr(hdc);
2175 if (!dc) goto done;
2177 if (dc->gdiFont)
2178 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2180 GDI_ReleaseObj(hdc);
2182 done:
2183 if (ret == DEFAULT_CHARSET && fs)
2184 memset(fs, 0, sizeof(FONTSIGNATURE));
2185 return ret;