Merge the non-obsolete bits from wine.texinfo into the Wine Developers
[wine/multimedia.git] / objects / font.c
blob382585f56f08029b8524dbcb5d0034aa17fe8ccd
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 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
322 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
323 plf->lfHeight, plf->lfWidth,
324 plf->lfEscapement, plf->lfOrientation,
325 plf->lfPitchAndFamily,
326 plf->lfOutPrecision, plf->lfClipPrecision,
327 plf->lfQuality, plf->lfCharSet,
328 debugstr_w(plf->lfFaceName),
329 plf->lfWeight > 400 ? "Bold" : "",
330 plf->lfItalic ? "Italic" : "", hFont);
332 if (plf->lfEscapement != plf->lfOrientation) {
333 /* this should really depend on whether GM_ADVANCED is set */
334 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
335 WARN("orientation angle %f set to "
336 "escapement angle %f for new font %p\n",
337 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
339 GDI_ReleaseObj( hFont );
342 else WARN("(NULL) => NULL\n");
344 return hFont;
347 /*************************************************************************
348 * CreateFontA (GDI32.@)
350 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
351 INT orient, INT weight, DWORD italic,
352 DWORD underline, DWORD strikeout, DWORD charset,
353 DWORD outpres, DWORD clippres, DWORD quality,
354 DWORD pitch, LPCSTR name )
356 LOGFONTA logfont;
358 logfont.lfHeight = height;
359 logfont.lfWidth = width;
360 logfont.lfEscapement = esc;
361 logfont.lfOrientation = orient;
362 logfont.lfWeight = weight;
363 logfont.lfItalic = italic;
364 logfont.lfUnderline = underline;
365 logfont.lfStrikeOut = strikeout;
366 logfont.lfCharSet = charset;
367 logfont.lfOutPrecision = outpres;
368 logfont.lfClipPrecision = clippres;
369 logfont.lfQuality = quality;
370 logfont.lfPitchAndFamily = pitch;
372 if (name)
373 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
374 else
375 logfont.lfFaceName[0] = '\0';
377 return CreateFontIndirectA( &logfont );
380 /*************************************************************************
381 * CreateFontW (GDI32.@)
383 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
384 INT orient, INT weight, DWORD italic,
385 DWORD underline, DWORD strikeout, DWORD charset,
386 DWORD outpres, DWORD clippres, DWORD quality,
387 DWORD pitch, LPCWSTR name )
389 LOGFONTW logfont;
391 logfont.lfHeight = height;
392 logfont.lfWidth = width;
393 logfont.lfEscapement = esc;
394 logfont.lfOrientation = orient;
395 logfont.lfWeight = weight;
396 logfont.lfItalic = italic;
397 logfont.lfUnderline = underline;
398 logfont.lfStrikeOut = strikeout;
399 logfont.lfCharSet = charset;
400 logfont.lfOutPrecision = outpres;
401 logfont.lfClipPrecision = clippres;
402 logfont.lfQuality = quality;
403 logfont.lfPitchAndFamily = pitch;
405 if (name)
406 lstrcpynW(logfont.lfFaceName, name,
407 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
408 else
409 logfont.lfFaceName[0] = '\0';
411 return CreateFontIndirectW( &logfont );
415 /***********************************************************************
416 * FONT_SelectObject
418 * If the driver supports vector fonts we create a gdi font first and
419 * then call the driver to give it a chance to supply its own device
420 * font. If the driver wants to do this it returns TRUE and we can
421 * delete the gdi font, if the driver wants to use the gdi font it
422 * should return FALSE, to signal an error return GDI_ERROR. For
423 * drivers that don't support vector fonts they must supply their own
424 * font.
426 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
428 HGDIOBJ ret = 0;
429 DC *dc = DC_GetDCPtr( hdc );
431 if (!dc) return 0;
433 if (dc->hFont != handle || dc->gdiFont == NULL)
435 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
436 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
439 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
441 if (ret && dc->gdiFont) dc->gdiFont = 0;
443 if (ret == HGDI_ERROR)
444 ret = 0; /* SelectObject returns 0 on error */
445 else
447 ret = dc->hFont;
448 dc->hFont = handle;
450 GDI_ReleaseObj( hdc );
451 return ret;
455 /***********************************************************************
456 * FONT_GetObject16
458 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
460 FONTOBJ *font = obj;
461 LOGFONT16 lf16;
463 FONT_LogFontWTo16( &font->logfont, &lf16 );
465 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
466 memcpy( buffer, &lf16, count );
467 return count;
470 /***********************************************************************
471 * FONT_GetObjectA
473 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
475 FONTOBJ *font = obj;
476 LOGFONTA lfA;
478 if(!buffer)
479 return sizeof(lfA);
480 FONT_LogFontWToA( &font->logfont, &lfA );
482 if (count > sizeof(lfA)) count = sizeof(lfA);
483 memcpy( buffer, &lfA, count );
484 return count;
487 /***********************************************************************
488 * FONT_GetObjectW
490 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
492 FONTOBJ *font = obj;
493 if(!buffer)
494 return sizeof(LOGFONTW);
495 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
496 memcpy( buffer, &font->logfont, count );
497 return count;
501 /***********************************************************************
502 * FONT_DeleteObject
504 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
506 WineEngDestroyFontInstance( handle );
507 return GDI_FreeObject( handle, obj );
511 /***********************************************************************
512 * FONT_EnumInstance16
514 * Called by the device driver layer to pass font info
515 * down to the application.
517 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
518 DWORD fType, LPARAM lp )
520 fontEnum16 *pfe = (fontEnum16*)lp;
521 INT ret = 1;
522 DC *dc;
524 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
525 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
527 WORD args[7];
528 DWORD result;
530 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
531 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
532 pfe->dwFlags |= ENUM_CALLED;
533 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
535 args[6] = SELECTOROF(pfe->segLogFont);
536 args[5] = OFFSETOF(pfe->segLogFont);
537 args[4] = SELECTOROF(pfe->segTextMetric);
538 args[3] = OFFSETOF(pfe->segTextMetric);
539 args[2] = fType;
540 args[1] = HIWORD(pfe->lpData);
541 args[0] = LOWORD(pfe->lpData);
542 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
543 ret = LOWORD(result);
545 /* get the lock again and make sure the DC is still valid */
546 dc = DC_GetDCPtr( pfe->hdc );
547 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
549 if (dc) GDI_ReleaseObj( pfe->hdc );
550 pfe->hdc = 0; /* make sure we don't try to release it later on */
551 ret = 0;
554 return ret;
557 /***********************************************************************
558 * FONT_EnumInstance
560 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
561 DWORD fType, LPARAM lp )
563 fontEnum32 *pfe = (fontEnum32*)lp;
564 INT ret = 1;
565 DC *dc;
567 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
568 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
569 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
571 /* convert font metrics */
572 ENUMLOGFONTEXA logfont;
573 NEWTEXTMETRICEXA tmA;
575 pfe->dwFlags |= ENUM_CALLED;
576 if (!(pfe->dwFlags & ENUM_UNICODE))
578 FONT_EnumLogFontExWToA( plf, &logfont);
579 FONT_NewTextMetricExWToA( ptm, &tmA );
580 plf = (LPENUMLOGFONTEXW)&logfont;
581 ptm = (NEWTEXTMETRICEXW *)&tmA;
583 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
585 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
587 /* get the lock again and make sure the DC is still valid */
588 dc = DC_GetDCPtr( pfe->hdc );
589 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
591 if (dc) GDI_ReleaseObj( pfe->hdc );
592 pfe->hdc = 0; /* make sure we don't try to release it later on */
593 ret = 0;
596 return ret;
599 /***********************************************************************
600 * EnumFontFamiliesEx (GDI.613)
602 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
603 FONTENUMPROC16 efproc, LPARAM lParam,
604 DWORD dwFlags)
606 fontEnum16 fe16;
607 INT16 ret = 1, ret2;
608 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
609 NEWTEXTMETRICEX16 tm16;
610 ENUMLOGFONTEX16 lf16;
611 LOGFONTW lfW;
612 BOOL enum_gdi_fonts;
614 if (!dc) return 0;
615 FONT_LogFont16ToW(plf, &lfW);
617 fe16.hdc = HDC_32(hDC);
618 fe16.dc = dc;
619 fe16.physDev = dc->physDev;
620 fe16.lpLogFontParam = plf;
621 fe16.lpEnumFunc = efproc;
622 fe16.lpData = lParam;
623 fe16.lpTextMetric = &tm16;
624 fe16.lpLogFont = &lf16;
625 fe16.segTextMetric = MapLS( &tm16 );
626 fe16.segLogFont = MapLS( &lf16 );
627 fe16.dwFlags = 0;
629 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
631 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
633 ret = 0;
634 goto done;
637 if (enum_gdi_fonts)
638 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
639 fe16.dwFlags &= ~ENUM_CALLED;
640 if (ret && dc->funcs->pEnumDeviceFonts) {
641 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
642 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
643 ret = ret2;
645 done:
646 UnMapLS( fe16.segTextMetric );
647 UnMapLS( fe16.segLogFont );
648 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
649 return ret;
652 /***********************************************************************
653 * FONT_EnumFontFamiliesEx
655 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
656 FONTENUMPROCW efproc,
657 LPARAM lParam, DWORD dwUnicode)
659 INT ret = 1, ret2;
660 DC *dc = DC_GetDCPtr( hDC );
661 fontEnum32 fe32;
662 BOOL enum_gdi_fonts;
664 if (!dc) return 0;
666 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
667 plf->lfCharSet);
668 fe32.lpLogFontParam = plf;
669 fe32.lpEnumFunc = efproc;
670 fe32.lpData = lParam;
671 fe32.dwFlags = dwUnicode;
672 fe32.hdc = hDC;
673 fe32.dc = dc;
674 fe32.physDev = dc->physDev;
676 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
678 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
680 ret = 0;
681 goto done;
684 if (enum_gdi_fonts)
685 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
686 fe32.dwFlags &= ~ENUM_CALLED;
687 if (ret && dc->funcs->pEnumDeviceFonts) {
688 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
689 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
690 ret = ret2;
692 done:
693 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
694 return ret;
697 /***********************************************************************
698 * EnumFontFamiliesExW (GDI32.@)
700 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
701 FONTENUMPROCW efproc,
702 LPARAM lParam, DWORD dwFlags )
704 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
707 /***********************************************************************
708 * EnumFontFamiliesExA (GDI32.@)
710 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
711 FONTENUMPROCA efproc,
712 LPARAM lParam, DWORD dwFlags)
714 LOGFONTW lfW;
715 FONT_LogFontAToW( plf, &lfW );
717 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
720 /***********************************************************************
721 * EnumFontFamilies (GDI.330)
723 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
724 FONTENUMPROC16 efproc, LPARAM lpData )
726 LOGFONT16 lf;
728 lf.lfCharSet = DEFAULT_CHARSET;
729 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
730 else lf.lfFaceName[0] = '\0';
732 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
735 /***********************************************************************
736 * EnumFontFamiliesA (GDI32.@)
738 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
739 FONTENUMPROCA efproc, LPARAM lpData )
741 LOGFONTA lf;
743 lf.lfCharSet = DEFAULT_CHARSET;
744 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
745 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
747 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
750 /***********************************************************************
751 * EnumFontFamiliesW (GDI32.@)
753 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
754 FONTENUMPROCW efproc, LPARAM lpData )
756 LOGFONTW lf;
758 lf.lfCharSet = DEFAULT_CHARSET;
759 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
760 else lf.lfFaceName[0] = 0;
762 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
765 /***********************************************************************
766 * EnumFonts (GDI.70)
768 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
769 LPARAM lpData )
771 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
774 /***********************************************************************
775 * EnumFontsA (GDI32.@)
777 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
778 LPARAM lpData )
780 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
783 /***********************************************************************
784 * EnumFontsW (GDI32.@)
786 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
787 LPARAM lpData )
789 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
793 /***********************************************************************
794 * GetTextCharacterExtra (GDI32.@)
796 INT WINAPI GetTextCharacterExtra( HDC hdc )
798 INT ret;
799 DC *dc = DC_GetDCPtr( hdc );
800 if (!dc) return 0x80000000;
801 ret = dc->charExtra;
802 GDI_ReleaseObj( hdc );
803 return ret;
807 /***********************************************************************
808 * SetTextCharacterExtra (GDI32.@)
810 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
812 INT prev;
813 DC * dc = DC_GetDCPtr( hdc );
814 if (!dc) return 0x80000000;
815 if (dc->funcs->pSetTextCharacterExtra)
816 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
817 else
819 prev = dc->charExtra;
820 dc->charExtra = extra;
822 GDI_ReleaseObj( hdc );
823 return prev;
827 /***********************************************************************
828 * SetTextJustification (GDI32.@)
830 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
832 BOOL ret = TRUE;
833 DC * dc = DC_GetDCPtr( hdc );
834 if (!dc) return FALSE;
835 if (dc->funcs->pSetTextJustification)
836 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
837 else
839 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
840 if (!extra) breaks = 0;
841 dc->breakTotalExtra = extra;
842 dc->breakCount = breaks;
843 if (breaks)
845 dc->breakExtra = extra / breaks;
846 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
848 else
850 dc->breakExtra = 0;
851 dc->breakRem = 0;
854 GDI_ReleaseObj( hdc );
855 return ret;
859 /***********************************************************************
860 * GetTextFaceA (GDI32.@)
862 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
864 INT res = GetTextFaceW(hdc, 0, NULL);
865 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
866 GetTextFaceW( hdc, res, nameW );
868 if (name)
870 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
871 name[count-1] = 0;
872 res = strlen(name);
874 else
875 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
876 HeapFree( GetProcessHeap(), 0, nameW );
877 return res;
880 /***********************************************************************
881 * GetTextFaceW (GDI32.@)
883 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
885 FONTOBJ *font;
886 INT ret = 0;
888 DC * dc = DC_GetDCPtr( hdc );
889 if (!dc) return 0;
891 if(dc->gdiFont)
892 ret = WineEngGetTextFace(dc->gdiFont, count, name);
893 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
895 if (name)
897 lstrcpynW( name, font->logfont.lfFaceName, count );
898 ret = strlenW(name);
900 else ret = strlenW(font->logfont.lfFaceName) + 1;
901 GDI_ReleaseObj( dc->hFont );
903 GDI_ReleaseObj( hdc );
904 return ret;
908 /***********************************************************************
909 * GetTextExtentPoint32A (GDI32.@)
911 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
912 LPSIZE size )
914 BOOL ret = FALSE;
915 INT wlen;
916 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
918 if (p) {
919 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
920 HeapFree( GetProcessHeap(), 0, p );
923 TRACE("(%p %s %d %p): returning %ld x %ld\n",
924 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
925 return ret;
929 /***********************************************************************
930 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
932 * Computes width and height of the specified string.
934 * RETURNS
935 * Success: TRUE
936 * Failure: FALSE
938 BOOL WINAPI GetTextExtentPoint32W(
939 HDC hdc, /* [in] Handle of device context */
940 LPCWSTR str, /* [in] Address of text string */
941 INT count, /* [in] Number of characters in string */
942 LPSIZE size) /* [out] Address of structure for string size */
944 BOOL ret = FALSE;
945 DC * dc = DC_GetDCPtr( hdc );
946 if (!dc) return FALSE;
948 if(dc->gdiFont) {
949 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
950 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
951 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
953 else if(dc->funcs->pGetTextExtentPoint)
954 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
956 GDI_ReleaseObj( hdc );
958 TRACE("(%p %s %d %p): returning %ld x %ld\n",
959 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
960 return ret;
963 /***********************************************************************
964 * GetTextExtentPointI [GDI32.@]
966 * Computes width and height of the array of glyph indices.
968 * RETURNS
969 * Success: TRUE
970 * Failure: FALSE
972 BOOL WINAPI GetTextExtentPointI(
973 HDC hdc, /* [in] Handle of device context */
974 const WORD *indices, /* [in] Address of glyph index array */
975 INT count, /* [in] Number of glyphs in array */
976 LPSIZE size) /* [out] Address of structure for string size */
978 BOOL ret = FALSE;
979 DC * dc = DC_GetDCPtr( hdc );
980 if (!dc) return FALSE;
982 if(dc->gdiFont) {
983 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
984 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
985 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
987 else if(dc->funcs->pGetTextExtentPoint) {
988 FIXME("calling GetTextExtentPoint\n");
989 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
992 GDI_ReleaseObj( hdc );
994 TRACE("(%p %p %d %p): returning %ld x %ld\n",
995 hdc, indices, count, size, size->cx, size->cy );
996 return ret;
1000 /***********************************************************************
1001 * GetTextExtentPointA (GDI32.@)
1003 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1004 LPSIZE size )
1006 TRACE("not bug compatible.\n");
1007 return GetTextExtentPoint32A( hdc, str, count, size );
1010 /***********************************************************************
1011 * GetTextExtentPointW (GDI32.@)
1013 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1014 LPSIZE size )
1016 TRACE("not bug compatible.\n");
1017 return GetTextExtentPoint32W( hdc, str, count, size );
1021 /***********************************************************************
1022 * GetTextExtentExPointA (GDI32.@)
1024 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1025 INT maxExt, LPINT lpnFit,
1026 LPINT alpDx, LPSIZE size )
1028 BOOL ret;
1029 INT wlen;
1030 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1031 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1032 HeapFree( GetProcessHeap(), 0, p );
1033 return ret;
1037 /***********************************************************************
1038 * GetTextExtentExPointW (GDI32.@)
1040 * Return the size of the string as it would be if it was output properly by
1041 * e.g. TextOut.
1043 * This should include
1044 * - Intercharacter spacing
1045 * - justification spacing (not yet done)
1046 * - kerning? see below
1048 * Kerning. Since kerning would be carried out by the rendering code it should
1049 * be done by the driver. However they don't support it yet. Also I am not
1050 * yet persuaded that (certainly under Win95) any kerning is actually done.
1052 * str: According to MSDN this should be null-terminated. That is not true; a
1053 * null will not terminate it early.
1054 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1055 * than count. I have seen it be either the size of the full string or
1056 * 1 less than the size of the full string. I have not seen it bear any
1057 * resemblance to the portion that would fit.
1058 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1059 * trailing intercharacter spacing and any trailing justification.
1061 * FIXME
1062 * Currently we do this by measuring each character etc. We should do it by
1063 * passing the request to the driver, perhaps by extending the
1064 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1065 * thinking about kerning issues and rounding issues in the justification.
1068 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1069 INT maxExt, LPINT lpnFit,
1070 LPINT alpDx, LPSIZE size )
1072 int index, nFit, extent;
1073 SIZE tSize;
1074 BOOL ret = FALSE;
1076 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1078 size->cx = size->cy = nFit = extent = 0;
1079 for(index = 0; index < count; index++)
1081 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1082 /* GetTextExtentPoint includes intercharacter spacing. */
1083 /* FIXME - justification needs doing yet. Remember that the base
1084 * data will not be in logical coordinates.
1086 extent += tSize.cx;
1087 if( !lpnFit || extent <= maxExt )
1088 /* It is allowed to be equal. */
1090 nFit++;
1091 if( alpDx ) alpDx[index] = extent;
1093 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1094 str++;
1096 size->cx = extent;
1097 if(lpnFit) *lpnFit = nFit;
1098 ret = TRUE;
1100 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1102 done:
1103 return ret;
1106 /***********************************************************************
1107 * GetTextMetricsA (GDI32.@)
1109 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1111 TEXTMETRICW tm32;
1113 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1114 FONT_TextMetricWToA( &tm32, metrics );
1115 return TRUE;
1118 /***********************************************************************
1119 * GetTextMetricsW (GDI32.@)
1121 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1123 BOOL ret = FALSE;
1124 DC * dc = DC_GetDCPtr( hdc );
1125 if (!dc) return FALSE;
1127 if (dc->gdiFont)
1128 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1129 else if (dc->funcs->pGetTextMetrics)
1130 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1132 if (ret)
1134 /* device layer returns values in device units
1135 * therefore we have to convert them to logical */
1137 #define WDPTOLP(x) ((x<0)? \
1138 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1139 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1140 #define HDPTOLP(y) ((y<0)? \
1141 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1142 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1144 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1145 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1146 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1147 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1148 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1149 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1150 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1151 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1152 ret = TRUE;
1153 #undef WDPTOLP
1154 #undef HDPTOLP
1155 TRACE("text metrics:\n"
1156 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1157 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1158 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1159 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1160 " PitchAndFamily = %02x\n"
1161 " --------------------\n"
1162 " InternalLeading = %li\n"
1163 " Ascent = %li\n"
1164 " Descent = %li\n"
1165 " Height = %li\n",
1166 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1167 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1168 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1169 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1170 metrics->tmPitchAndFamily,
1171 metrics->tmInternalLeading,
1172 metrics->tmAscent,
1173 metrics->tmDescent,
1174 metrics->tmHeight );
1176 GDI_ReleaseObj( hdc );
1177 return ret;
1181 /***********************************************************************
1182 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1184 * NOTES
1185 * lpOTM should be LPOUTLINETEXTMETRIC
1187 * RETURNS
1188 * Success: Non-zero or size of required buffer
1189 * Failure: 0
1191 UINT16 WINAPI GetOutlineTextMetrics16(
1192 HDC16 hdc, /* [in] Handle of device context */
1193 UINT16 cbData, /* [in] Size of metric data array */
1194 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1196 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1197 return 0;
1201 /***********************************************************************
1202 * GetOutlineTextMetricsA (GDI32.@)
1203 * Gets metrics for TrueType fonts.
1206 * RETURNS
1207 * Success: Non-zero or size of required buffer
1208 * Failure: 0
1210 UINT WINAPI GetOutlineTextMetricsA(
1211 HDC hdc, /* [in] Handle of device context */
1212 UINT cbData, /* [in] Size of metric data array */
1213 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1215 char buf[512], *ptr;
1216 UINT ret, needed;
1217 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1218 INT left, len;
1220 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1221 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1222 return 0;
1223 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1224 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1227 needed = sizeof(OUTLINETEXTMETRICA);
1228 if(lpOTMW->otmpFamilyName)
1229 needed += WideCharToMultiByte(CP_ACP, 0,
1230 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1231 NULL, 0, NULL, NULL);
1232 if(lpOTMW->otmpFaceName)
1233 needed += WideCharToMultiByte(CP_ACP, 0,
1234 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1235 NULL, 0, NULL, NULL);
1236 if(lpOTMW->otmpStyleName)
1237 needed += WideCharToMultiByte(CP_ACP, 0,
1238 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1239 NULL, 0, NULL, NULL);
1240 if(lpOTMW->otmpFullName)
1241 needed += WideCharToMultiByte(CP_ACP, 0,
1242 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1243 NULL, 0, NULL, NULL);
1245 if(!lpOTM) {
1246 ret = needed;
1247 goto end;
1250 if(needed > cbData) {
1251 ret = 0;
1252 goto end;
1256 lpOTM->otmSize = needed;
1257 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1258 lpOTM->otmFiller = 0;
1259 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1260 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1261 lpOTM->otmfsType = lpOTMW->otmfsType;
1262 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1263 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1264 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1265 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1266 lpOTM->otmAscent = lpOTMW->otmAscent;
1267 lpOTM->otmDescent = lpOTMW->otmDescent;
1268 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1269 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1270 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1271 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1272 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1273 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1274 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1275 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1276 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1277 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1278 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1279 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1280 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1281 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1282 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1283 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1286 ptr = (char*)(lpOTM + 1);
1287 left = needed - sizeof(*lpOTM);
1289 if(lpOTMW->otmpFamilyName) {
1290 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1291 len = WideCharToMultiByte(CP_ACP, 0,
1292 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1293 ptr, left, NULL, NULL);
1294 left -= len;
1295 ptr += len;
1296 } else
1297 lpOTM->otmpFamilyName = 0;
1299 if(lpOTMW->otmpFaceName) {
1300 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1301 len = WideCharToMultiByte(CP_ACP, 0,
1302 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1303 ptr, left, NULL, NULL);
1304 left -= len;
1305 ptr += len;
1306 } else
1307 lpOTM->otmpFaceName = 0;
1309 if(lpOTMW->otmpStyleName) {
1310 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1311 len = WideCharToMultiByte(CP_ACP, 0,
1312 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1313 ptr, left, NULL, NULL);
1314 left -= len;
1315 ptr += len;
1316 } else
1317 lpOTM->otmpStyleName = 0;
1319 if(lpOTMW->otmpFullName) {
1320 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1321 len = WideCharToMultiByte(CP_ACP, 0,
1322 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1323 ptr, left, NULL, NULL);
1324 left -= len;
1325 } else
1326 lpOTM->otmpFullName = 0;
1328 assert(left == 0);
1330 ret = needed;
1332 end:
1333 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1334 HeapFree(GetProcessHeap(), 0, lpOTMW);
1336 return ret;
1340 /***********************************************************************
1341 * GetOutlineTextMetricsW [GDI32.@]
1343 UINT WINAPI GetOutlineTextMetricsW(
1344 HDC hdc, /* [in] Handle of device context */
1345 UINT cbData, /* [in] Size of metric data array */
1346 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1348 DC *dc = DC_GetDCPtr( hdc );
1349 UINT ret;
1351 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1352 if(!dc) return 0;
1354 if(dc->gdiFont) {
1355 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1356 if(ret && ret <= cbData) {
1357 #define WDPTOLP(x) ((x<0)? \
1358 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1359 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1360 #define HDPTOLP(y) ((y<0)? \
1361 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1362 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1364 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1365 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1366 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1367 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1368 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1369 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1370 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1371 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1372 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1373 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1374 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1375 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1376 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1377 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1378 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1379 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1380 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1381 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1382 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1383 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1384 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1385 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1386 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1387 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1388 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1389 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1390 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1391 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1392 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1393 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1394 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1395 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1396 #undef WDPTOLP
1397 #undef HDPTOLP
1401 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1402 but really this should just be a return 0. */
1404 ret = sizeof(*lpOTM);
1405 if (lpOTM) {
1406 if(cbData < ret)
1407 ret = 0;
1408 else {
1409 memset(lpOTM, 0, ret);
1410 lpOTM->otmSize = sizeof(*lpOTM);
1411 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1413 Further fill of the structure not implemented,
1414 Needs real values for the structure members
1419 GDI_ReleaseObj(hdc);
1420 return ret;
1424 /***********************************************************************
1425 * GetCharWidthW (GDI32.@)
1426 * GetCharWidth32W (GDI32.@)
1428 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1429 LPINT buffer )
1431 UINT i;
1432 BOOL ret = FALSE;
1433 DC * dc = DC_GetDCPtr( hdc );
1434 if (!dc) return FALSE;
1436 if (dc->gdiFont)
1437 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1438 else if (dc->funcs->pGetCharWidth)
1439 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1441 if (ret)
1443 /* convert device units to logical */
1444 for( i = firstChar; i <= lastChar; i++, buffer++ )
1445 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1446 ret = TRUE;
1448 GDI_ReleaseObj( hdc );
1449 return ret;
1453 /***********************************************************************
1454 * GetCharWidthA (GDI32.@)
1455 * GetCharWidth32A (GDI32.@)
1457 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1458 LPINT buffer )
1460 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1461 LPSTR str;
1462 LPWSTR wstr;
1463 BOOL ret = TRUE;
1465 if(count <= 0) return FALSE;
1467 str = HeapAlloc(GetProcessHeap(), 0, count);
1468 for(i = 0; i < count; i++)
1469 str[i] = (BYTE)(firstChar + i);
1471 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1473 for(i = 0; i < wlen; i++)
1475 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1477 ret = FALSE;
1478 break;
1480 buffer++;
1483 HeapFree(GetProcessHeap(), 0, str);
1484 HeapFree(GetProcessHeap(), 0, wstr);
1486 return ret;
1490 /* FIXME: all following APIs ******************************************/
1493 /***********************************************************************
1494 * SetMapperFlags (GDI32.@)
1496 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1498 DC *dc = DC_GetDCPtr( hDC );
1499 DWORD ret = 0;
1500 if(!dc) return 0;
1501 if(dc->funcs->pSetMapperFlags)
1502 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1503 else
1504 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1505 GDI_ReleaseObj( hDC );
1506 return ret;
1509 /***********************************************************************
1510 * GetAspectRatioFilterEx (GDI.486)
1512 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1514 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1515 return FALSE;
1518 /***********************************************************************
1519 * GetAspectRatioFilterEx (GDI32.@)
1521 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1523 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1524 return FALSE;
1528 /***********************************************************************
1529 * GetCharABCWidthsA (GDI32.@)
1531 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1532 LPABC abc )
1534 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1535 LPSTR str;
1536 LPWSTR wstr;
1537 BOOL ret = TRUE;
1539 if(count <= 0) return FALSE;
1541 str = HeapAlloc(GetProcessHeap(), 0, count);
1542 for(i = 0; i < count; i++)
1543 str[i] = (BYTE)(firstChar + i);
1545 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1547 for(i = 0; i < wlen; i++)
1549 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1551 ret = FALSE;
1552 break;
1554 abc++;
1557 HeapFree(GetProcessHeap(), 0, str);
1558 HeapFree(GetProcessHeap(), 0, wstr);
1560 return ret;
1564 /******************************************************************************
1565 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1567 * PARAMS
1568 * hdc [I] Handle of device context
1569 * firstChar [I] First character in range to query
1570 * lastChar [I] Last character in range to query
1571 * abc [O] Address of character-width structure
1573 * NOTES
1574 * Only works with TrueType fonts
1576 * RETURNS
1577 * Success: TRUE
1578 * Failure: FALSE
1580 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1581 LPABC abc )
1583 DC *dc = DC_GetDCPtr(hdc);
1584 int i;
1585 GLYPHMETRICS gm;
1586 BOOL ret = FALSE;
1588 if(dc->gdiFont) {
1589 for (i=firstChar;i<=lastChar;i++) {
1590 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1591 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1592 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1593 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1595 ret = TRUE;
1597 GDI_ReleaseObj(hdc);
1598 return ret;
1602 /***********************************************************************
1603 * GetGlyphOutline (GDI.309)
1605 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1606 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1607 LPVOID lpBuffer, const MAT2 *lpmat2 )
1609 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1610 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1611 return (DWORD)-1; /* failure */
1615 /***********************************************************************
1616 * GetGlyphOutlineA (GDI32.@)
1618 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1619 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1620 LPVOID lpBuffer, const MAT2 *lpmat2 )
1622 LPWSTR p = NULL;
1623 DWORD ret;
1624 UINT c;
1626 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1627 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1628 c = p[0];
1629 } else
1630 c = uChar;
1631 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1632 lpmat2);
1633 if(p)
1634 HeapFree(GetProcessHeap(), 0, p);
1635 return ret;
1638 /***********************************************************************
1639 * GetGlyphOutlineW (GDI32.@)
1641 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1642 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1643 LPVOID lpBuffer, const MAT2 *lpmat2 )
1645 DC *dc = DC_GetDCPtr(hdc);
1646 DWORD ret;
1648 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1649 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1651 if(!dc) return GDI_ERROR;
1653 if(dc->gdiFont)
1654 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1655 cbBuffer, lpBuffer, lpmat2);
1656 else
1657 ret = GDI_ERROR;
1659 GDI_ReleaseObj(hdc);
1660 return ret;
1664 /***********************************************************************
1665 * CreateScalableFontResourceA (GDI32.@)
1667 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1668 LPCSTR lpszResourceFile,
1669 LPCSTR lpszFontFile,
1670 LPCSTR lpszCurrentPath )
1672 HANDLE f;
1674 /* fHidden=1 - only visible for the calling app, read-only, not
1675 * enumbered with EnumFonts/EnumFontFamilies
1676 * lpszCurrentPath can be NULL
1678 FIXME("(%ld,%s,%s,%s): stub\n",
1679 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1680 debugstr_a(lpszCurrentPath) );
1682 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1683 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1684 CloseHandle(f);
1685 SetLastError(ERROR_FILE_EXISTS);
1686 return FALSE;
1688 return FALSE; /* create failed */
1691 /***********************************************************************
1692 * CreateScalableFontResourceW (GDI32.@)
1694 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1695 LPCWSTR lpszResourceFile,
1696 LPCWSTR lpszFontFile,
1697 LPCWSTR lpszCurrentPath )
1699 FIXME("(%ld,%p,%p,%p): stub\n",
1700 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1701 return FALSE; /* create failed */
1705 /*************************************************************************
1706 * GetRasterizerCaps (GDI32.@)
1708 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1710 lprs->nSize = sizeof(RASTERIZER_STATUS);
1711 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1712 lprs->nLanguageID = 0;
1713 return TRUE;
1717 /*************************************************************************
1718 * GetKerningPairsA (GDI32.@)
1720 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1721 LPKERNINGPAIR lpKerningPairs )
1723 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1727 /*************************************************************************
1728 * GetKerningPairsW (GDI32.@)
1730 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1731 LPKERNINGPAIR lpKerningPairs )
1733 int i;
1734 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1735 for (i = 0; i < cPairs; i++)
1736 lpKerningPairs[i].iKernAmount = 0;
1737 return 0;
1740 /*************************************************************************
1741 * TranslateCharsetInfo [GDI32.@]
1743 * Fills a CHARSETINFO structure for a character set, code page, or
1744 * font. This allows making the correspondance between different labelings
1745 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1746 * of the same encoding.
1748 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1749 * only one codepage should be set in *lpSrc.
1751 * RETURNS
1752 * TRUE on success, FALSE on failure.
1755 BOOL WINAPI TranslateCharsetInfo(
1756 LPDWORD lpSrc, /* [in]
1757 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1758 if flags == TCI_SRCCHARSET: a character set value
1759 if flags == TCI_SRCCODEPAGE: a code page value
1761 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1762 DWORD flags /* [in] determines interpretation of lpSrc */
1764 int index = 0;
1765 switch (flags) {
1766 case TCI_SRCFONTSIG:
1767 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1768 break;
1769 case TCI_SRCCODEPAGE:
1770 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1771 break;
1772 case TCI_SRCCHARSET:
1773 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1774 break;
1775 default:
1776 return FALSE;
1778 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1779 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1780 return TRUE;
1783 /*************************************************************************
1784 * GetFontLanguageInfo (GDI32.@)
1786 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1788 FONTSIGNATURE fontsig;
1789 static const DWORD GCP_DBCS_MASK=0x003F0000,
1790 GCP_DIACRITIC_MASK=0x00000000,
1791 FLI_GLYPHS_MASK=0x00000000,
1792 GCP_GLYPHSHAPE_MASK=0x00000040,
1793 GCP_KASHIDA_MASK=0x00000000,
1794 GCP_LIGATE_MASK=0x00000000,
1795 GCP_USEKERNING_MASK=0x00000000,
1796 GCP_REORDER_MASK=0x00000060;
1798 DWORD result=0;
1800 GetTextCharsetInfo( hdc, &fontsig, 0 );
1801 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1803 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1804 result|=GCP_DBCS;
1806 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1807 result|=GCP_DIACRITIC;
1809 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1810 result|=FLI_GLYPHS;
1812 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1813 result|=GCP_GLYPHSHAPE;
1815 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1816 result|=GCP_KASHIDA;
1818 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1819 result|=GCP_LIGATE;
1821 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1822 result|=GCP_USEKERNING;
1824 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1825 result|=GCP_REORDER;
1827 return result;
1831 /*************************************************************************
1832 * GetFontData [GDI32.@] Retrieve data for TrueType font
1834 * RETURNS
1836 * success: Number of bytes returned
1837 * failure: GDI_ERROR
1839 * NOTES
1841 * Calls SetLastError()
1844 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1845 LPVOID buffer, DWORD length)
1847 DC *dc = DC_GetDCPtr(hdc);
1848 DWORD ret = GDI_ERROR;
1850 if(!dc) return GDI_ERROR;
1852 if(dc->gdiFont)
1853 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1855 GDI_ReleaseObj(hdc);
1856 return ret;
1859 /*************************************************************************
1860 * GetGlyphIndicesA [GDI32.@]
1862 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1863 LPWORD pgi, DWORD flags)
1865 DWORD ret;
1866 WCHAR *lpstrW;
1867 INT countW;
1869 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1870 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1872 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1873 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1874 HeapFree(GetProcessHeap(), 0, lpstrW);
1876 return ret;
1879 /*************************************************************************
1880 * GetGlyphIndicesW [GDI32.@]
1882 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1883 LPWORD pgi, DWORD flags)
1885 DC *dc = DC_GetDCPtr(hdc);
1886 DWORD ret = GDI_ERROR;
1888 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1889 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1891 if(!dc) return GDI_ERROR;
1893 if(dc->gdiFont)
1894 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1896 GDI_ReleaseObj(hdc);
1897 return ret;
1900 /*************************************************************************
1901 * GetCharacterPlacementA [GDI32.@]
1903 * NOTES:
1904 * the web browser control of ie4 calls this with dwFlags=0
1906 DWORD WINAPI
1907 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1908 INT nMaxExtent, GCP_RESULTSA *lpResults,
1909 DWORD dwFlags)
1911 WCHAR *lpStringW;
1912 INT uCountW, i;
1913 GCP_RESULTSW resultsW;
1914 DWORD ret;
1915 UINT font_cp;
1917 TRACE("%s, %d, %d, 0x%08lx\n",
1918 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1920 /* both structs are equal in size */
1921 memcpy(&resultsW, lpResults, sizeof(resultsW));
1923 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1924 if(lpResults->lpOutString)
1925 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1927 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1929 if(lpResults->lpOutString) {
1930 if(font_cp != CP_SYMBOL)
1931 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1932 lpResults->lpOutString, uCount, NULL, NULL );
1933 else
1934 for(i = 0; i < uCount; i++)
1935 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1938 HeapFree(GetProcessHeap(), 0, lpStringW);
1939 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1941 return ret;
1944 /*************************************************************************
1945 * GetCharacterPlacementW [GDI32.@]
1947 * Retrieve information about a string. This includes the width, reordering,
1948 * Glyphing and so on.
1950 * RETURNS
1952 * The width and height of the string if successful, 0 if failed.
1954 * BUGS
1956 * All flags except GCP_REORDER are not yet implemented.
1957 * Reordering is not 100% complient to the Windows BiDi method.
1958 * Caret positioning is not yet implemented.
1959 * Classes are not yet implemented.
1962 DWORD WINAPI
1963 GetCharacterPlacementW(
1964 HDC hdc, /* [in] Device context for which the rendering is to be done */
1965 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1966 INT uCount, /* [in] Number of WORDS in string. */
1967 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1968 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1969 DWORD dwFlags /* [in] Flags specifying how to process the string */
1972 DWORD ret=0;
1973 SIZE size;
1974 UINT i, nSet;
1976 TRACE("%s, %d, %d, 0x%08lx\n",
1977 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1979 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1980 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1981 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1982 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1983 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1985 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1986 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1987 if(lpResults->lpClass) FIXME("classes not implemented\n");
1989 nSet = (UINT)uCount;
1990 if(nSet > lpResults->nGlyphs)
1991 nSet = lpResults->nGlyphs;
1993 /* return number of initialized fields */
1994 lpResults->nGlyphs = nSet;
1996 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1998 /* Treat the case where no special handling was requested in a fastpath way */
1999 /* copy will do if the GCP_REORDER flag is not set */
2000 if(lpResults->lpOutString)
2001 strncpyW( lpResults->lpOutString, lpString, nSet );
2003 if(lpResults->lpOrder)
2005 for(i = 0; i < nSet; i++)
2006 lpResults->lpOrder[i] = i;
2008 } else
2010 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2011 nSet, lpResults->lpOrder );
2014 /* FIXME: Will use the placement chars */
2015 if (lpResults->lpDx)
2017 int c;
2018 for (i = 0; i < nSet; i++)
2020 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2021 lpResults->lpDx[i]= c;
2025 if(lpResults->lpGlyphs)
2026 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2028 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2029 ret = MAKELONG(size.cx, size.cy);
2031 return ret;
2034 /*************************************************************************
2035 * GetCharABCWidthsFloatA [GDI32.@]
2037 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2038 LPABCFLOAT lpABCF)
2040 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2041 return 0;
2044 /*************************************************************************
2045 * GetCharABCWidthsFloatW [GDI32.@]
2047 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2048 UINT iLastChar, LPABCFLOAT lpABCF)
2050 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2051 return 0;
2054 /*************************************************************************
2055 * GetCharWidthFloatA [GDI32.@]
2057 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2058 UINT iLastChar, PFLOAT pxBuffer)
2060 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2061 return 0;
2064 /*************************************************************************
2065 * GetCharWidthFloatW [GDI32.@]
2067 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2068 UINT iLastChar, PFLOAT pxBuffer)
2070 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2071 return 0;
2075 /***********************************************************************
2077 * Font Resource API *
2079 ***********************************************************************/
2081 /***********************************************************************
2082 * AddFontResourceA (GDI32.@)
2084 INT WINAPI AddFontResourceA( LPCSTR str )
2086 return AddFontResourceExA( str, 0, NULL);
2089 /***********************************************************************
2090 * AddFontResourceW (GDI32.@)
2092 INT WINAPI AddFontResourceW( LPCWSTR str )
2094 return AddFontResourceExW(str, 0, NULL);
2098 /***********************************************************************
2099 * AddFontResourceExA (GDI32.@)
2101 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2103 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2104 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2105 INT ret;
2107 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2108 ret = AddFontResourceExW(strW, fl, pdv);
2109 HeapFree(GetProcessHeap(), 0, strW);
2110 return ret;
2113 /***********************************************************************
2114 * AddFontResourceExW (GDI32.@)
2116 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2118 return WineEngAddFontResourceEx(str, fl, pdv);
2121 /***********************************************************************
2122 * RemoveFontResourceA (GDI32.@)
2124 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2126 return RemoveFontResourceExA(str, 0, 0);
2129 /***********************************************************************
2130 * RemoveFontResourceW (GDI32.@)
2132 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2134 return RemoveFontResourceExW(str, 0, 0);
2137 /***********************************************************************
2138 * RemoveFontResourceExA (GDI32.@)
2140 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2142 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2143 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2144 INT ret;
2146 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2147 ret = RemoveFontResourceExW(strW, fl, pdv);
2148 HeapFree(GetProcessHeap(), 0, strW);
2149 return ret;
2152 /***********************************************************************
2153 * RemoveFontResourceExW (GDI32.@)
2155 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2157 return WineEngRemoveFontResourceEx(str, fl, pdv);
2160 /***********************************************************************
2161 * GetTextCharset (GDI32.@)
2163 UINT WINAPI GetTextCharset(HDC hdc)
2165 /* MSDN docs say this is equivalent */
2166 return GetTextCharsetInfo(hdc, NULL, 0);
2169 /***********************************************************************
2170 * GetTextCharsetInfo (GDI32.@)
2172 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2174 UINT ret = DEFAULT_CHARSET;
2175 DC *dc = DC_GetDCPtr(hdc);
2177 if (!dc) goto done;
2179 if (dc->gdiFont)
2180 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2182 GDI_ReleaseObj(hdc);
2184 done:
2185 if (ret == DEFAULT_CHARSET && fs)
2186 memset(fs, 0, sizeof(FONTSIGNATURE));
2187 return ret;